DeFiFoundrySolidity
16,653 OP
View results
Submission Details
Severity: medium
Invalid

Lack of Slippage Protection in Curve Swap Leading to Front-Running Vulnerabilities

Summary

The StrategyMainnet::claimAndSwap function in the contract lacks robust slippage protection when performing swaps via the Curve router. This vulnerability exposes the protocol to front-running attacks, where an attacker manipulates the Curve pool's pricing to execute the victim's transaction at a significant loss. By exploiting this, attackers can profit while causing financial damage to the protocol.

function claimAndSwap(
uint256 _amountClaim,
uint256 _minOut,
uint256 _routeNumber
) external onlyKeepers {
transmuter.claim(_amountClaim, address(this));
uint256 balBefore = asset.balanceOf(address(this));
require(_minOut > _amountClaim, "minOut too low");
router.exchange(
routes[_routeNumber],
swapParams[_routeNumber],
_amountClaim,
_minOut,
pools[_routeNumber],
address(this)
);
uint256 balAfter = asset.balanceOf(address(this));
require((balAfter - balBefore) >= _minOut, "Slippage too high");
transmuter.deposit(asset.balanceOf(address(this)), address(this));
}

Vulnerability Details

The vulnerability arises because the _minOut parameter, which represents the minimum acceptable output tokens (alETH) for the swap, is:

  • Directly provided by the keeper without validation against real-time market prices.

  • Executed without ensuring slippage protection, making the swap susceptible to price manipulation.

The attack occurs as follows:
Observation: An attacker monitors the mempool for a claimAndSwap transaction containing _amountClaim (input WETH amount) and _minOut (minimum acceptable alETH).
Front-Running:
The attacker submits a transaction before the victim's transaction to manipulate the Curve pool, e.g., by swapping a large amount of WETH for alETH. This drains alETH liquidity and increases the price of WETH.
Victim's Loss: The victim's transaction executes at the manipulated (worse) exchange rate. Since _minOut is not validated against real-time prices, the swap goes through despite the attacker skewing the pool.
Profit Extraction: The attacker submits another transaction after the victim's to rebalance the pool and secure a profit.
The lack of validation for _minOut and reliance on Curve's dynamic pricing without slippage checks enables this exploit.

Impact

Financial Loss to the Protocol:

Tools Used

Manual review

Recommendations

There are several ways to mitigate this attack. Will highlight some of the ways to do so:

  1. Implement Robust Slippage Protection: Enforce _minOut based on real-time market data using a price oracle (e.g., Chainlink) or pre-swap calculations.

+ uint256 expectedOut = getExpectedAmountOut(_amountClaim);
+ require(_minOut <= expectedOut, "!minOut");

Add a slippage tolerance (e.g., 1%) to the calculation:
2. Use Time-Weighted Average Price (TWAP):
Implement TWAP oracles to ensure prices are averaged over time, reducing the impact of short-term manipulation.

Updates

Appeal created

inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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