Technical Reference
Functionsβ
Transactions to the UniversalRouter all go through the UniversalRouter.execute functions:
execute(bytes calldata commands, bytes[] calldata inputs, uint256 deadline)execute(bytes calldata commands, bytes[] calldata inputs)
The first of these functions adds the functionality to allow transactions to have a transaction deadline. If the block.timestamp is after the deadline provided the transaction will revert. After that check, the 2 functions otherwise execute identically.
The execute functions work like a simplified VM - they take in a list of commands, and a list of inputs for the commands and execute them in the order specified.
Command Structureβ
The first parameter for the function (bytes calldata commands) is a list of commands for the contract to execute, in the order they should be executed. Each command is encoded in 1 byte, containing the following split of 8 bits:
| 0 | 1 2 | 3 4 5 6 7 |
|---|---|---|
| f | r | command |
fβ
A single bit flag, that signals whether or not the command should be allowed to revert without the whole transaction failing.
- If
fis0akafalseand the command reverts, then the entire transaction will revert and none of the commands will be executed. - If
fis1akatrueand the command reverts, then the transaction will continue, allowing us to achieve partial fills. If using this flag, be careful to include further commands that will remove any funds that could be left unused in theUniversalRoutercontract.
rβ
2 unused bytes, reserved for future use. Leaving these 2 bits as 0 will save gas, but any value passed into the contract will be ignored. Later versions of the UniversalRouter will likely expand the 5 bits used for command to use at least 1 of these bits.
commandβ
A 5 bit unique identifier for the command that should be carried out. The values of these commands can be found within Commands.sol, or can be viewed in the table below.
The command types that are not defined do not have an assigned command at this moment in time. Providing one of these identifiers will cause the transaction to revert with InvalidCommandType.
A complete list of commands can be found in the table below:
| Command | Value |
|---|---|
0x00 | V3_SWAP_EXACT_IN |
0x01 | V3_SWAP_EXACT_OUT |
0x02 | PERMIT2_TRANSFER_FROM |
0x03 | PERMIT2_PERMIT_BATCH |
0x04 | SWEEP |
0x05 | TRANSFER |
0x06 | PAY_PORTION |
0x07 | |
0x08 | V2_SWAP_EXACT_IN |
0x09 | V2_SWAP_EXACT_OUT |
0x0a | PERMIT2_PERMIT |
0x0b | WRAP_ETH |
0x0c | UNWRAP_WETH |
0x0d | PERMIT2_TRANSFER_FROM_BATCH |
0x0e | |
0x0f | |
0x10 | SEAPORT |
0x11 | LOOKS_RARE_721 |
0x12 | NFTX |
0x13 | CRYPTOPUNKS |
0x14 | LOOKS_RARE_1155 |
0x15 | OWNER_CHECK_721 |
0x16 | OWNER_CHECK_1155 |
0x17 | SWEEP_ERC721 |
0x18 | X2Y2_721 |
0x19 | SUDOSWAP |
0x1a | NFT20 |
0x1b | X2Y2_1155 |
0x1c | FOUNDATION |
0x1d | SWEEP_ERC1155 |
0x1e | |
0x1f |
Command Inputsβ
The second parameter for the function is an array of bytes strings. Each element in the array is the abi-encoded input that will be used for the respective command.
commands[i] is the command that will use inputs[i] as its encoded input parameters.
The router uses the command type to know how to decode the encoded input parameters - depending on the command chosen, the required inputs is different.
The input parameters required for each command are outlined below:
V3_SWAP_EXACT_INβ
addressThe recipient of the output of the tradeuint256The amount of input tokens for the tradeuint256The minimum amount of output tokens the user wantsbytesThe UniswapV3 encoded path to trade alongboolA flag for whether the input tokens should come from themsg.sender(through Permit2) or whether the funds are already in theUniversalRouter
V3_SWAP_EXACT_OUTβ
addressThe recipient of the output of the tradeuint256The amount of output tokens to receiveuint256The maximum number of input tokens that should be spentbytesThe UniswapV3 encoded path to trade alongboolA flag for whether the input tokens should come from themsg.sender(through Permit2) or whether the funds are already in theUniversalRouter
PERMIT2_TRANSFER_FROMβ
addressThe token to fetch from Permit2addressThe recipient of the tokens fetcheduint256The amount of token to fetch
The individual that the tokens are fetched from is always the msg.sender of the transaction
PERMIT2_PERMIT_BATCHβ
IAllowanceTransfer.PermitBatchAPermitBatchstruct outlining all of the Permit2 permits to execute.bytesThe signature to provide to Permit2
The individual that signed the permits must be the msg.sender of the transaction
SWEEPβ
addressThe ERC20 token to sweep (or Constants.ETH for ETH)addressThe recipient of the sweepuint256The minimum required tokens to receive from the sweep
TRANSFERβ
addressThe ERC20 token to transfer (or Constants.ETH for ETH)addressThe recipient of the transferuint256The amount to transfer
PAY_PORTIONβ
addressThe ERC20 token to transfer (or Constants.ETH for ETH)addressThe recipient of the transferuint256In basis points, the percentage of the contractβs balance to transfer
V2_SWAP_EXACT_INβ
addressThe recipient of the output of the tradeuint256The amount of input tokens for the tradeuint256The minimum amount of output tokens the user wantsaddress[]The UniswapV2 token path to trade alongboolA flag for whether the input tokens should come from themsg.sender(through Permit2) or whether the funds are already in theUniversalRouter
V2_SWAP_EXACT_OUTβ
addressThe recipient of the output of the tradeuint256The amount of output tokens to receiveuint256The maximum number of input tokens that should be spentaddress[]The UniswapV2 token path to trade alongboolA flag for whether the input tokens should come from themsg.sender(through Permit2) or whether the funds are already in theUniversalRouter
PERMIT2_PERMITβ
IAllowanceTransfer.PermitSingleAPermitSinglestruct outlining the Permit2 permit to executebytesThe signature to provide to Permit2
The individual that signed the permit must be the msg.sender of the transaction
WRAP_ETHβ
addressThe recipient of the WETHuint256The amount of ETH to wrap
UNWRAP_WETHβ
addressThe recipient of the ETHuint256The minimum required ETH to receive from the unwrapping
PERMIT2_TRANSFER_FROM_BATCHβ
IAllowanceTransfer.AllowanceTransferDetails[]An array ofAllowanceTransferDetailsstructs that each describe a Permit2 transfer to perform
SEAPORTβ
uint256The ETH value to forward to the Seaport contractbytesThe calldata to use to call the Seaport contract
LOOKS_RARE_721β
uint256The ETH value to forward to the LooksRare contractbytesThe calldata to use to call the LooksRare contractaddressThe recipient of the ERC721addressThe ERC721 token addressuint256The ID of the ERC721
NFTXβ
uint256The ETH value to forward to the NFTX contractbytesThe calldata to use to call the NFTX contract
CRYPTOPUNKSβ
uint256The PunkID to purchaseaddressThe recipient for the cryptopunkuint256The ETH value to forward to the Cryptopunks contract
LOOKS_RARE_1155β
uint256The ETH value to forward to the LooksRare contractbytesThe calldata to use to call the LooksRare contractaddressThe recipient of the ERC1155addressThe ERC1155 token addressuint256The ID of the ERC1155uint256The amount of the ERC1155 to transfer
OWNER_CHECK_721β
addressThe required owner of the ERC721addressThe ERC721 token addressuint256The ID of the ERC721
OWNER_CHECK_1155β
addressThe required owner of the ERC1155addressThe ERC721 token addressuint256The ID of the ERC1155uint256The minimum required amount of the ERC1155
SWEEP_ERC721β
addressThe ERC721 token address to transferaddressThe recipient of the transferuint256The token ID to transfer
X2Y2_721β
uint256The ETH value to forward to the X2Y2 contractbytesThe calldata to use to call the X2Y2 contractaddressThe recipient of the ERC721addressThe ERC721 token addressuint256The ID of the ERC721
SUDOSWAPβ
uint256The ETH value to forward to the Sudoswap contractbytesThe calldata to use to call the Sudoswap contract
NFT20β
uint256The ETH value to forward to the NFT20 contractbytesThe calldata to use to call the NFT20 contract
X2Y2_1155β
uint256The ETH value to forward to the X2Y2 contractbytesThe calldata to use to call the X2Y2 contractaddressThe recipient of the ERC1155addressThe ERC1155 token addressuint256The ID of the ERC1155uint256The amount of the ERC1155 to transfer
FOUNDATIONβ
uint256The ETH value to forward to the Foundation contractbytesThe calldata to use to call the Foundation contractaddressThe recipient of the ERC721addressThe ERC721 token addressuint256The ID of the ERC721
SWEEP_ERC1155β
addressThe ERC1155 token address to sweepaddressThe recipient of the sweepuint256The token ID to sweepuint256The minimum required tokens to receive from the sweep
Example: Reverting Commandsβ
For a Sudoswap command, that should be allowed to revert, the following 8 bit command should be provided:
command = 0x80 (10000000) && 0x19 (00011001) = 0x99 (10011001)
Take care when working with reverting commands - ensure you have appended commands to deal with funds that could remain in the contract after either outcomes. For example, if the Sudoswap command reverts, a following SWEEP can be added to ensure that any ETH that was not spent does not get left in the router.