code-423n4 / 2024-07-reserve-validation

0 stars 0 forks source link

Users are not allowed to provide their acceptable slippage when settling trades #15

Closed c4-bot-6 closed 1 month ago

c4-bot-6 commented 2 months ago

Lines of code

https://github.com/code-423n4/2024-07-reserve/blob/825e5a98a8c94a7b4458b3b359a507edb9e662ba/contracts/p1/RevenueTrader.sol#L109-L183

Vulnerability details

Proof of Concept

Take a look at https://github.com/code-423n4/2024-07-reserve/blob/825e5a98a8c94a7b4458b3b359a507edb9e662ba/contracts/p1/RevenueTrader.sol#L109-L183

    function manageTokens(IERC20[] calldata erc20s, TradeKind[] calldata kinds){
..snip

        for (uint256 i = 0; i < len; ++i) {
            IERC20 erc20 = erc20s[i];
            if (erc20 == tokenToBuy) continue;

            require(address(trades[erc20]) == address(0), "trade open");
            require(erc20.balanceOf(address(this)) != 0, "0 balance");

            IAsset assetToSell = assetRegistry.toAsset(erc20);
            (uint192 sellLow, uint192 sellHigh) = assetToSell.price(); // {UoA/tok}

            TradeInfo memory trade = TradeInfo({
                sell: assetToSell,
                buy: assetToBuy,
                sellAmount: assetToSell.bal(address(this)),
                buyAmount: 0,
                prices: TradePrices(sellLow, sellHigh, buyLow, buyHigh)
            });

            // Whether dust or not, trade the non-target asset for the target asset
            // Any asset with a broken price feed will trigger a revert here
            //@audit
            (, TradeRequest memory req) = TradeLib.prepareTradeSell(
                trade,
                minTradeVolume,
                maxTradeSlippage
            );
            require(req.sellAmount > 1, "sell amount too low");

            // Launch trade
            tryTrade(kinds[i], req, trade.prices);
        }
    }

This function is used to process a set of tokens, issue however is that for all ERC20s that isn't the tokenToBuy, there would be a need to start an auction of the given kind for that token, however the max slippage attached to this auction is not provided in a case by case pattern, but rather what has been attached as the maxTradeSlippage in RevenueTrader#init().

Impact

Ineffective trading logic, considering a hardcoded slippage has been applied to trades and would lead either of the two cases below:

Recommended Mitigation Steps

Consider allowing slippages in a case by case pattern.

Assessed type

Context