We learned about the UniswapV3 pool contract worked, now we turn our attention to the router contract.
The UniswapV3 router works very much like the UniswapV2 router in the sense that it is designed to operate as a “single point of contact” for the UniswapV3 ecosystem. User applications can approve and swap from the router instead of needing to find and interact with individual liquidity pools.
A big difference between the V3 and V2 contracts is the number of functions. Where the V2 router has 24 functions (19 for RouterV01, plus 5 more for RouterV02), the V3 router only has 4 functions!
Check the V3 router contract source and you’ll find the following:
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut)
function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut)
function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn)
function exactOutput(ExactOutputParams calldataparams) externalpayablereturns (uint256amountIn)
Each function accepts a struct
of arguments. This is a gas savings mechanism, since structs can be packed more closely together instead of padded each function argument out to 32 bytes.
Here they are:
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
struct ExactInputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
}
struct ExactOutputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
uint160 sqrtPriceLimitX96;
}
struct ExactOutputParams {
bytes path;
address recipient;
uint256 deadline;
uint256 amountOut;
uint256 amountInMaximum;
}
Many of these structs have very familiar and intuitive variable names, so you should mostly know what to do with them. The sqrtPriceLimitX96
input is a bit intimidating, and having to specify fee
seems odd. But otherwise stuff like path
, deadline
, tokenIn
, tokenOut
, etc. should not make you apprehensive.
Just like you’d expect, the function exactInputSingle
accepts as its single argument a ExactInputSingleParams
struct. The other functions are similar, accepting a matching-name struct describing the swap.
You can visit the UniswapV3 documentation for the router interface and read what each function does, the inputs it expects, and the values it returns.
Console Exploration
Now let’s take our pool from the previous lesson (DAI-WETH, 0.3% fee, address 0xC2e9F25Be6257c210d7Adf0D4Cd6E3E881ba25f8) and play around with the router on a local fork.
The deployment addresses for all contracts are listed HERE.