Elastic-Finance-DAO / eefi_contracts

0 stars 0 forks source link

[TRE-01C] Inefficient Enforcements of Minimum Output #105

Open stalker474 opened 3 weeks ago

stalker474 commented 3 weeks ago

TRE-01C: Inefficient Enforcements of Minimum Output

Type Severity Location
Gas Optimization Trader.sol:L63, L67, L97, L99

Description:

The Trader::sellAMPLForOHM and Trader::sellAMPLForEEFI functions will inefficiently impose a minimum output amount locally instead of relying on the Uniswap protocols directly.

Example:

/**
* @dev Caller must transfer the right amount of tokens to the trader
* @param amount Amount of AMPL to sell
* @param minimalExpectedAmount The minimal expected amount of ohm
 */
function sellAMPLForOHM(uint256 amount, uint256 minimalExpectedAmount) external override returns (uint256 ohmAmount) {
    amplToken.safeTransferFrom(msg.sender, address(this), amount);
    amplToken.approve(address(uniswapV2Router), amount);
    uint[] memory amounts = uniswapV2Router.swapExactTokensForTokens(amount, 0, pathAMPLETH, address(this), block.timestamp);
    uint256 ethAmount = amounts[1];
    wethToken.approve(address(uniswapV3Router), ethAmount);
    ohmAmount = uniswapV3Router.exactInputSingle(
        ISwapRouter.ExactInputSingleParams(
            address(wethToken),
            address(ohmToken),
            FEE,
            msg.sender,
            block.timestamp,
            ethAmount,
            0,
            0
        )
    );
    require(ohmAmount >= minimalExpectedAmount, "Trader: minimalExpectedAmount not acquired");

    emit Sale_OHM(amount, ohmAmount);
}

/**
* @dev Caller must transfer the right amount of tokens to the trader
* @param amount Amount of AMPL to sell
* @param minimalExpectedAmount The minimal expected amount of EEFI
 */
function sellAMPLForEEFI(uint256 amount, uint256 minimalExpectedAmount) external override returns (uint256 eefiAmount) {
    amplToken.safeTransferFrom(msg.sender, address(this), amount);
    amplToken.approve(address(uniswapV2Router), amount);
    uint[] memory amounts = uniswapV2Router.swapExactTokensForTokens(amount, 0, pathAMPLETH, address(this), block.timestamp);
    uint256 ethAmount = amounts[1];
    wethToken.approve(address(uniswapV3Router), ethAmount);
    uint256 ohmAmount = uniswapV3Router.exactInputSingle(
        ISwapRouter.ExactInputSingleParams(
            address(wethToken),
            address(ohmToken),
            FEE,
            address(this),
            block.timestamp,
            ethAmount,
            0,
            0
        )
    );
    // purchase EEFI
    ohmToken.approve(address(uniswapV2Router), ohmAmount);
    amounts = uniswapV2Router.swapExactTokensForTokens(ohmAmount, 0, pathOHMEEFI, msg.sender, block.timestamp);
    eefiAmount = amounts[1];
    require(eefiAmount >= minimalExpectedAmount, "Trader: minimalExpectedAmount not acquired");

    emit Sale_EEFI(amount, eefiAmount);
}

Recommendation:

We advise the relevant minimum output variables to be passed in to the Uniswap V3 and Uniswap V2 calls respectively, ensuring that the minimum output is upheld by the protocols directly.