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

Critical Vulnerabilities in claimAndSwap: Sandwich Attacks and Price Constraint Risks

Security Analysis: Price Manipulation and Premium State Vulnerabilities in claimAndSwap Function

Summary

The claimAndSwap function in its current implementation has three notable vulnerabilities:

  1. Susceptibility to Sandwich Attacks: The function is exposed to front-running and back-running attacks due to the lack of protection mechanisms, allowing malicious actors (such as MEV bots) to manipulate the price impact of the swap.

  2. Strict Price Constraint: The price check that enforces _minOut > _amountClaim can block legitimate claims, particularly during periods of market volatility, even when the operation would still be profitable.

  3. Premium State Manipulation: Malicious actors can sandwich attack users calling claimAndSwap, manipulating prices to force them out of the premium state and preventing them from claiming their rewards.

Vulnerability Details

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"); // Issue 1: Strict premium requirement
// Issue 2: No flash loan protection, vulnerable to sandwich attacks
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));
}

Key Issues:

  1. Sandwich Attack Vulnerability:

    • Problem: Without protection against sandwich attacks, malicious actors (MEV bots) can manipulate the price before and after the swap. The attacker can front-run the swap by initiating their own transaction to alter the price of the asset, and then back-run to profit from the manipulated price impact.

    • Impact: This can result in artificial slippage, forced higher slippage, or even the failure of the transaction, preventing the operation from executing as expected.

  2. Strict Price Check on _minOut:

    • Problem: The require(_minOut > _amountClaim) constraint enforces that the user must receive more than the amount claimed, effectively creating a strict price premium requirement. This can block the swap from executing during periods of market volatility where a slight deviation from the expected price is common.

    • Impact: During volatile market conditions, this check could prevent the swap from occurring even if the transaction would still be profitable, reducing the protocol’s functionality and user experience.

  3. Premium State Manipulation via Sandwich Attack:

The claimAndSwap function’s requirement of _minOut > _amountClaim creates an opportunity for malicious actors to prevent users from claiming their rewards through sandwich attacks:

  1. When a user attempts to call claimAndSwap, an attacker can front-run the transaction with a large swap that temporarily impacts the price.

  2. This price manipulation can cause the _minOut to fall below _amountClaim, making the user’s transaction revert due to the “minOut too low” check.

  3. The attacker then back-runs with a swap in the opposite direction to profit from the price manipulation.

This attack effectively prevents users from claiming their rightful rewards by manipulating them out of the premium state, even when the overall market conditions would normally allow for profitable claims.

Impact: High. Users can be consistently blocked from claiming their rewards, leading to locked funds and poor user experience.

Recommendation:

  • Implement slippage protection mechanisms

  • Consider using Time-Weighted Average Price (TWAP) oracles for price validation

  • Add configurable premium thresholds that can adapt to market conditions

Impact

HIGH Impact:

  1. Sandwich Attack Vulnerability:

    • MEV bots could exploit the lack of protection, resulting in manipulated prices and forced slippage. This would lead to:

      • Losses for the protocol or users due to manipulated price movements.

      • Transaction failure if the manipulated prices cause slippage to exceed limits.

      • Loss of trust in the protocol’s ability to perform swaps securely and reliably.

  2. Strict Price Constraint:

    • Enforcing an overly strict price premium check (_minOut > _amountClaim) can lead to legitimate claims being blocked, especially during periods of high volatility where minor price fluctuations are expected. This could:

      • Prevent legitimate swaps that would still yield profitable results.

      • Disrupt protocol operations, preventing keepers from performing valid claims and swaps, potentially locking liquidity or preventing profitable trades.

      • Decrease user experience as legitimate transactions fail due to the overly stringent price checks.

Tools Used

  • Manual Code Review: Detailed analysis of the claimAndSwap function’s logic, especially around the price validation and swap execution process.

  • Sandwich Attack Simulation: Potential exposure to MEV bots (sandwich attacks) as identified in the logic of the swap execution.

  • Market Volatility Consideration: Examining the price check constraint and its potential impact on legitimate claims in volatile market conditions.

Recommendations

1. Add Sandwich Attack Protection:

To prevent MEV bots from front-running and back-running the transaction, consider adding a deadline for the transaction and/or slippage tolerance to mitigate price manipulation.

Suggested Update:

function claimAndSwap(
uint256 _amountClaim,
uint256 _minOut,
uint256 _routeNumber,
uint256 _deadline
) external onlyKeepers {
require(block.timestamp <= _deadline, "Transaction expired");
transmuter.claim(_amountClaim, address(this));
uint256 balBefore = asset.balanceOf(address(this));
// Proceed with swap logic...
}
  • Explanation: Adding a deadline ensures that the swap happens within a reasonable time frame and prevents price manipulation by actors who might try to execute their transactions before or after the swap occurs. It also prevents outdated swaps that are no longer profitable due to changing market conditions.

2. Make Price Premium Check More Flexible:

Instead of requiring _minOut to be strictly greater than _amountClaim, make the check more flexible by allowing a small deviation (e.g., 0.5% to 1%) to account for normal price fluctuations during volatile market conditions.

Suggested Update:

function claimAndSwap(
uint256 _amountClaim,
uint256 _minOut,
uint256 _routeNumber
) external onlyKeepers {
transmuter.claim(_amountClaim, address(this));
uint256 balBefore = asset.balanceOf(address(this));
// Allow for small deviations in expected output to handle volatility
require(_minOut >= (_amountClaim * 995) / 1000, "Expected return too low");
// Proceed with swap logic...
}
  • Explanation: Allowing some deviation from the expected minimum output will reduce the likelihood of the function being blocked during volatile periods. For example, a 0.5% flexibility in price is generally reasonable and would accommodate small, temporary market fluctuations.

3. Consider Implementing Batched Claims/Swaps:

Batch claims and swaps together to reduce MEV exposure. This approach can help mitigate potential front-running or back-running attacks that exploit the time between claim and swap execution.

Suggested Approach:

  • Implement a batching mechanism where multiple claims and swaps are aggregated into a single transaction, reducing the opportunities for MEV bots to exploit individual claims.

  • This can be done by using a multi-step transaction pattern or commit-reveal strategy, where all operations are tied together in a single atomic batch.

Example:

function batchClaimAndSwap(
uint256[] calldata _amountClaims,
uint256[] calldata _minOuts,
uint256[] calldata _routeNumbers
) external onlyKeepers {
for (uint i = 0; i < _amountClaims.length; i++) {
claimAndSwap(_amountClaims[i], _minOuts[i], _routeNumbers[i]);
}
}
  • Explanation: By batching multiple claims and swaps together, you reduce the time window for malicious actors to manipulate the price. This also makes it more difficult for bots to execute front-running or back-running strategies.


By addressing these issues, the claimAndSwap function would become more resilient against malicious manipulation while maintaining its functionality during normal market conditions. The improvements would also increase the protocol’s security, ensuring that legitimate transactions can still occur even during periods of volatility.

Updates

Lead Judging Commences

inallhonesty Lead Judge
7 months ago

Appeal created

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
drlaravel Submitter
7 months ago
inallhonesty Lead Judge
7 months ago
inallhonesty Lead Judge 7 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.