Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Valid

Slippage check is unnecessarily strict when executes swaps in CurveAdapter

Summary

Slippage check is unnecessarily strict when executes swaps in CurveAdapter.

Vulnerability Details

CurveAdapter provides executeSwapExactInput() for executing swaps. User can specify a custom path to swap input token for the desired output token.

CurveAdapter::executeSwapExactInput():

// decode path as it is Uniswap V3 specific
(address[] memory tokens,) = swapPayload.path.decodePath();
// declare amountIn as initial token amountIn
uint256 amountIn = swapPayload.amountIn;
// cache to prevent identicla storage reads during loop
address curveStrategyRouterCache = curveStrategyRouter;
for (uint256 i; i < tokens.length - 1; i++) {
// approve the tokenIn to the swap router
IERC20(tokens[i]).approve(curveStrategyRouterCache, amountIn);
// get the expected output amount
uint256 expectedAmountOut = getExpectedOutput(tokens[i], tokens[i + 1], amountIn);
// Calculate the minimum acceptable output based on the slippage tolerance
uint256 amountOutMinimum = calculateAmountOutMin(expectedAmountOut);
// If last swap send received tokens to payload recipient
address receiver = (i == tokens.length - 2) ? swapPayload.recipient : address(this);
// make single exchange
amountIn = ICurveSwapRouter(curveStrategyRouterCache).exchange_with_best_rate({
_from: tokens[i],
_to: tokens[i + 1],
_amount: amountIn,
@> _expected: amountOutMinimum,
_receiver: receiver
});
}

The problem is that it performs slippage checking for every intermediate swap, this is a bit strict and the whole swap may revert unnecessarily.

Assuming:

  • Swap path is [tokenA, tokenB, tokenC]

  • Slippage tolerance is 2%

  • For tokenA : tokenB, the expected swap rate is 100 : 1, and the actual swap rate is 103 : 1

  • For tokenB : tokenC, the expected swap rate is 1 : 50, and the actual swap rate is 1 : 53

Therefore, for tokenA : tokenC, the expected swap rate for is 2 : 1, and the actual swap rate is 1.83 : 1.

By providing 100 tokenA, user is expected to receive 50 tokenC, but they can actually receive 51 tokenC, which is better, however, the transaction will revert when swaps tokenA for tokenB, as user is expected to receive 1 tokenB but they actually receive 0.97, the slippage is more than 2%.

Impact

The swap unnecessarily revert.

Tools Used

Manual Review

Recommendations

It is recommended to calculate the expected swap rate for input token and output token, use this rate to perform slippage checking against the actual received token amount.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

CurveAdapter cumulative slippage

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.