Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

steadyman - The broker's swapIn or swapOut functions cannot be used. #63

Open
sherlock-admin4 opened this issue Oct 31, 2024 · 0 comments

Comments

@sherlock-admin4
Copy link
Contributor

sherlock-admin4 commented Oct 31, 2024

steadyman

Medium

The broker's swapIn or swapOut functions cannot be used.

Summary

An attacker can make it impossible to pass the Limits by continuously swapping a small number of tokens, thus making the swapIn or swapOut functions unusable.

Root Cause

When tradingLimitState is updated, if _deltaFlow is very small, the calculation of _deltaFlowUnits will be 0 due to the trade-off problem. At this time, deltaFlowUnits will be counted as 1 (tokenIn), so an attacker can use 1 tokenIn to increase netflow.

https://github.com/sherlock-audit/2024-10-mento-update/blob/main/mento-core/contracts/libraries/TradingLimits.sol#L124

Internal pre-conditions

No response

External pre-conditions

Gas price is very low

Attack Path

Continuously call the swapIn function with amountIn = 1 to make netflow0, netflow1, or netflowGlobal reach the limit

Impact

The netflow increases due to low-quality swapIn transactions (amountIn == 1), which will cause swapIn transactions to be unable to proceed due to restrictions for a certain period of time, or swapIn transactions to be affected. Even if swapOut transactions reduce netflow, attackers can still increase netflow again through low-quality swapIn transactions (amountIn == 1).

PoC

No response

Mitigation

Set the AMOUNT_MIN variable

+ uint256 public AMOUNT_MIN;

  /// @inheritdoc IBroker
  function swapIn(
    address exchangeProvider,
    bytes32 exchangeId,
    address tokenIn,
    address tokenOut,
    uint256 amountIn,
    uint256 amountOutMin
  ) external nonReentrant returns (uint256 amountOut) {
+ require(AMOUNT_MIN < amountIn);
    require(isExchangeProvider[exchangeProvider], "ExchangeProvider does not exist");
    // slither-disable-next-line reentrancy-benign
    amountOut = IExchangeProvider(exchangeProvider).swapIn(exchangeId, tokenIn, tokenOut, amountIn);
    require(amountOut >= amountOutMin, "amountOutMin not met");
    guardTradingLimits(exchangeId, tokenIn, amountIn, tokenOut, amountOut);

    address reserve = exchangeReserve[exchangeProvider];
    transferIn(payable(msg.sender), tokenIn, amountIn, reserve);
    transferOut(payable(msg.sender), tokenOut, amountOut, reserve);
    emit Swap(exchangeProvider, exchangeId, msg.sender, tokenIn, tokenOut, amountIn, amountOut);
  }

  /// @inheritdoc IBroker
  function swapOut(
    address exchangeProvider,
    bytes32 exchangeId,
    address tokenIn,
    address tokenOut,
    uint256 amountOut,
    uint256 amountInMax
  ) external nonReentrant returns (uint256 amountIn) {
+ require(AMOUNT_MIN < amountOut);
    require(isExchangeProvider[exchangeProvider], "ExchangeProvider does not exist");
    // slither-disable-next-line reentrancy-benign
    amountIn = IExchangeProvider(exchangeProvider).swapOut(exchangeId, tokenIn, tokenOut, amountOut);
    require(amountIn <= amountInMax, "amountInMax exceeded");
    guardTradingLimits(exchangeId, tokenIn, amountIn, tokenOut, amountOut);

    address reserve = exchangeReserve[exchangeProvider];
    transferIn(payable(msg.sender), tokenIn, amountIn, reserve);
    transferOut(payable(msg.sender), tokenOut, amountOut, reserve);
    emit Swap(exchangeProvider, exchangeId, msg.sender, tokenIn, tokenOut, amountIn, amountOut);
  }
@sherlock-admin3 sherlock-admin3 changed the title Passive Aquamarine Beetle - The broker's swapIn or swapOut functions cannot be used. steadyman - The broker's swapIn or swapOut functions cannot be used. Nov 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant