sherlock-audit / 2022-09-notional-judging

4 stars 2 forks source link

ctf_sec - UniV2Adapter.sol does not implement swapExactTokensForTokensSupportingFeeOnTransferTokens #90

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

ctf_sec

medium

UniV2Adapter.sol does not implement swapExactTokensForTokensSupportingFeeOnTransferTokens

Summary

UniV2Adapter.sol does not support fee on transfer token, because it does not swapExactTokensForTokensSupportingFeeOnTransferTokens function call.

Vulnerability Detail

Uniswap is considered the dominant AMM protocol. While Uniswap V3's innovation is advanced, Uniswap V2 and Uniswap V2 related fork still takes a considerable amount of shares.

The integration with UniswapV2 should not be taken for granted.

In the current implementation,

the UniswapV2Adapter only support regular ERC20 token swap by supporting

        executionCallData = abi.encodeWithSelector(
                IUniV2Router2.swapExactTokensForTokens.selector,
                trade.amount,
                trade.limit,
                data.path,
                from,
                trade.deadline
        );

However, swapExactTokensForTokens fails if the underlying token is fee on transfer token.

there is a special transfer function that takes care of the fee on transfer token in UniswapV2.sol, which is not supported at this time.

function swapExactTokensForTokensSupportingFeeOnTransferTokens(
  uint amountIn,
  uint amountOutMin,
  address[] calldata path,
  address to,
  uint deadline
) external;

Source: https://docs.uniswap.org/protocol/V2/reference/smart-contracts/router-02#swapexacttokensfortokenssupportingfeeontransfertokens

Identical to swapExactTokensForTokens, but succeeds for tokens that take a fee on transfer.

Impact

lack of such support for fee on transfer token would means that when strategy vault execute trade, fee on transfer token will be left off in UniswapV2 in

    /// @notice Can be used to delegate call to the TradingModule's implementation in order to execute
    /// a trade.
    function _executeTrade(
        uint16 dexId,
        Trade memory trade
    ) internal returns (uint256 amountSold, uint256 amountBought) {
        return trade._executeTrade(dexId, TRADING_MODULE);
    }

Code Snippet

https://github.com/sherlock-audit/2022-09-notional/blob/main/leveraged-vaults/contracts/trading/adapters/UniV2Adapter.sol#L27-L51

Tool used

Manual Review

Recommendation

We recommand the project add swapExactTokensForTokensSupportingFeeOnTransferTokens support for Uniswap V2