Omniscia Euler Finance Audit

SwapHandlerUniswapV3 Manual Review Findings

SwapHandlerUniswapV3 Manual Review Findings

SHU-01M: Incorrect Execution Mode Assumption

Description:

The executeSwap function assumes that the params.mode variable will either be set to 0 or 1, however, this is not the case as it is an arbitrary uint256 variable that can be set to any value.

Impact:

A misconfigured SwapParams payload will currently be accepted as valid and will lead to loss of funds for the transaction creator. Additionally, this type of variable ambiguity might have wider implications for the SwapHub implementation which assumes only 1 represents an exact-output trade.

Example:

contracts/swapHandlers/SwapHandlerUniswapV3.sol
16function executeSwap(SwapParams calldata params) override external {
17 setMaxAllowance(params.underlyingIn, params.amountIn, uniSwapRouterV3);
18
19 // The payload in SwapParams has double use. For single pool swaps, the price limit and a pool fee are abi-encoded as 2 uints, where bytes length is 64.
20 // For multi-pool swaps, the payload represents a swap path. A valid path is a packed encoding of tokenIn, pool fee and tokenOut.
21 // The valid path lengths are therefore: 20 + n*(3 + 20), where n >= 1, and no valid path can be 64 bytes long.
22 if (params.payload.length == 64) {
23 (uint sqrtPriceLimitX96, uint fee) = abi.decode(params.payload, (uint, uint));
24 if (params.mode == 0)
25 exactInputSingle(params, sqrtPriceLimitX96, fee);
26 else
27 exactOutputSingle(params, sqrtPriceLimitX96, fee);
28 } else {
29 if (params.mode == 0)
30 exactInput(params, params.payload);
31 else
32 exactOutput(params, params.payload);
33 }
34
35 if (params.mode == 1) transferBack(params.underlyingIn);
36}

Recommendation:

We advise the logic of the contract to properly only handle a case of 0 or "Ø" by simply handling the case of params.mode == 0 and params.mode != 0 instead as otherwise funds could be lost within the contract.

Alleviation:

A require check was introduced in the executeSwap function ensuring that the params.mode execution mode is less-than-or-equal-to (<=) the value of 1, properly sanitizing its value and ensuring the logic of the function executes as expected.