Function: swapUniversalRouter(address tokenIn, address tokenOut, uint160 amountIn, byte[] commands, byte[][] inputs, uint256 deadline, address receiver)
Transfers amountIn
of tokenIn
tokens from the Spot to Swap and approves them for trading. By using the swap commands in commands
to decide parameters like reverting on failure, and the ABI-encoded inputs in inputs
, multiple trades will be executed within the deadline
block timestamp - or everything reverts. The amount of tokenOut
is measured before and after the trades, and the difference is returned.
This function can only be called by the address in trade
, and that happens whenever a Spot is opened or closed.
Inputs
tokenIn
Control: Full.
Constraints: Must be a contract with IERC20 ABI.
Impact: The type of token to transfer from Spot before executing the trades.
tokenOut
Control: Full.
Constraints: None.
Impact: The type of token to return the balance change for.
amountIn
Control: Full.
Constraints: Cannot be more tokens than
spot
has.Impact: The amount of tokens to transfer and approve.
commands
Control: Full.
Constraints: Special bitfield format (Uniswap).
Impact: For each input, decides the command and if a command is allowed to revert.
inputs
Control: Full.
Constraints: ABI encoded and supported further up the chain (Uniswap).
Impact: ABI-encoded inputs for address, available trade amount, minimum amount to trade, Uniswap path, and if funds come from caller (Permit2) or if they are already in the router.
deadline
Control: Full.
Constraints: None.
Impact: A block timestamp for when the execution should fail if not completed. If 0, an execute function without the deadline parameter is called.
receiver
Control: Full.
Constraints: None.
Impact: The receiver address to use when calculating the balance change.
Branches and code coverage (including function calls)
Intended branches
Called with deadline.
Called with no deadline.
Negative behavior
Called from nontrader.
Called with invalid or bad commands/inputs.
Function call analysis
swapUniversalRouter -> spot.transferToken(tokenIn, amountIn)
What is controllable? All.
If return value controllable, how is it used and how can it go wrong? N/A.
What happens if it reverts, reenters, or does other unusual control flow? If spot owns less than
amountIn
tokens of typetokenIn
, this reverts.
swapUniversalRouter -> IERC20(tokenIn).approve(address(permit2), amountIn)
What is controllable?
tokenIn
,amountIn
.If return value controllable, how is it used and how can it go wrong? N/A.
What happens if it reverts, reenters, or does other unusual control flow? Approved amount can be changed without reducing it to 0 in between. This allows for the approved spender to spend both allowances with unfortunate transaction ordering.
swapUniversalRouter -> universalRouter.execute(commands, inputs, [deadline])
What is controllable? All.
If return value controllable, how is it used and how can it go wrong? With bad inputs, can be made to trade less than the intended amount and lock up funds. Caller must be sure to sync
amountIn
andinputs
. Too long deadline could lead to bad trades.What happens if it reverts, reenters, or does other unusual control flow? Reverts if deadline has expired, an incorrect number of inputs are provided or the execution fails.