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 trade
- uint256The amount of input tokens for the trade
- uint256The minimum amount of output tokens the user wants
- bytesThe UniswapV3 encoded path to trade along
- boolA flag for whether the input tokens should come from the- msg.sender(through Permit2) or whether the funds are already in the- UniversalRouter
V3_SWAP_EXACT_OUTβ
- addressThe recipient of the output of the trade
- uint256The amount of output tokens to receive
- uint256The maximum number of input tokens that should be spent
- bytesThe UniswapV3 encoded path to trade along
- boolA flag for whether the input tokens should come from the- msg.sender(through Permit2) or whether the funds are already in the- UniversalRouter
PERMIT2_TRANSFER_FROMβ
- addressThe token to fetch from Permit2
- addressThe recipient of the tokens fetched
- uint256The 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.PermitBatchA- PermitBatchstruct 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 sweep
- uint256The minimum required tokens to receive from the sweep
TRANSFERβ
- addressThe ERC20 token to transfer (or Constants.ETH for ETH)
- addressThe recipient of the transfer
- uint256The amount to transfer
PAY_PORTIONβ
- addressThe ERC20 token to transfer (or Constants.ETH for ETH)
- addressThe recipient of the transfer
- uint256In basis points, the percentage of the contractβs balance to transfer
V2_SWAP_EXACT_INβ
- addressThe recipient of the output of the trade
- uint256The amount of input tokens for the trade
- uint256The minimum amount of output tokens the user wants
- address[]The UniswapV2 token path to trade along
- boolA flag for whether the input tokens should come from the- msg.sender(through Permit2) or whether the funds are already in the- UniversalRouter
V2_SWAP_EXACT_OUTβ
- addressThe recipient of the output of the trade
- uint256The amount of output tokens to receive
- uint256The maximum number of input tokens that should be spent
- address[]The UniswapV2 token path to trade along
- boolA flag for whether the input tokens should come from the- msg.sender(through Permit2) or whether the funds are already in the- UniversalRouter
PERMIT2_PERMITβ
- IAllowanceTransfer.PermitSingleA- PermitSinglestruct outlining the Permit2 permit to execute
- bytesThe 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 WETH
- uint256The amount of ETH to wrap
UNWRAP_WETHβ
- addressThe recipient of the ETH
- uint256The minimum required ETH to receive from the unwrapping
PERMIT2_TRANSFER_FROM_BATCHβ
- IAllowanceTransfer.AllowanceTransferDetails[]An array of- AllowanceTransferDetailsstructs that each describe a Permit2 transfer to perform
SEAPORTβ
- uint256The ETH value to forward to the Seaport contract
- bytesThe calldata to use to call the Seaport contract
LOOKS_RARE_721β
- uint256The ETH value to forward to the LooksRare contract
- bytesThe calldata to use to call the LooksRare contract
- addressThe recipient of the ERC721
- addressThe ERC721 token address
- uint256The ID of the ERC721
NFTXβ
- uint256The ETH value to forward to the NFTX contract
- bytesThe calldata to use to call the NFTX contract
CRYPTOPUNKSβ
- uint256The PunkID to purchase
- addressThe recipient for the cryptopunk
- uint256The ETH value to forward to the Cryptopunks contract
LOOKS_RARE_1155β
- uint256The ETH value to forward to the LooksRare contract
- bytesThe calldata to use to call the LooksRare contract
- addressThe recipient of the ERC1155
- addressThe ERC1155 token address
- uint256The ID of the ERC1155
- uint256The amount of the ERC1155 to transfer
OWNER_CHECK_721β
- addressThe required owner of the ERC721
- addressThe ERC721 token address
- uint256The ID of the ERC721
OWNER_CHECK_1155β
- addressThe required owner of the ERC1155
- addressThe ERC721 token address
- uint256The ID of the ERC1155
- uint256The minimum required amount of the ERC1155
SWEEP_ERC721β
- addressThe ERC721 token address to transfer
- addressThe recipient of the transfer
- uint256The token ID to transfer
X2Y2_721β
- uint256The ETH value to forward to the X2Y2 contract
- bytesThe calldata to use to call the X2Y2 contract
- addressThe recipient of the ERC721
- addressThe ERC721 token address
- uint256The ID of the ERC721
SUDOSWAPβ
- uint256The ETH value to forward to the Sudoswap contract
- bytesThe calldata to use to call the Sudoswap contract
NFT20β
- uint256The ETH value to forward to the NFT20 contract
- bytesThe calldata to use to call the NFT20 contract
X2Y2_1155β
- uint256The ETH value to forward to the X2Y2 contract
- bytesThe calldata to use to call the X2Y2 contract
- addressThe recipient of the ERC1155
- addressThe ERC1155 token address
- uint256The ID of the ERC1155
- uint256The amount of the ERC1155 to transfer
FOUNDATIONβ
- uint256The ETH value to forward to the Foundation contract
- bytesThe calldata to use to call the Foundation contract
- addressThe recipient of the ERC721
- addressThe ERC721 token address
- uint256The ID of the ERC721
SWEEP_ERC1155β
- addressThe ERC1155 token address to sweep
- addressThe recipient of the sweep
- uint256The token ID to sweep
- uint256The 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.