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

Front-running `StrategyArb::claimAndSwap` will lead to loss of funds

Summary

StrategyArb::claimAndSwap is designed to generate yield for the strategy but it can be front-run by attacker, normal (seeking profit) user or MEV. First, the front-runner profits through arbitrage. Second, the protocol loses the opportunity to earn yield. Third, the transmuted alETH is converted into WETH, which cannot be claimed by the protocol or its users. These funds will be indefinitely frozen in the Transmuter contract because there is no function that can handle the claimed, transmuted WETH.

Vulnerability Details

The strategy generates yield by swapping WETH for alETH when the trade is profitable (i.e., when 1 WETH is worth more than 1 alETH). Users deposit alETH into the strategy, which then deposits it into the Transmuter. While in the Transmuter, the alETH is gradually transmuted into WETH. The strategy can claim this WETH and exchange it for alETH at a premium.

The issue is that the claimAndSwap function can be front-run. An attacker can use price discrepancies to profit from swaps, preventing the protocol from exchanging WETH for alETH. Since WETH cannot be claimed by either the users or the protocol, it becomes stuck in the Transmuter, resulting in a loss of funds for users.

https://github.com/Cyfrin/2024-12-alchemix/blob/82798f4891e41959eef866bd1d4cb44fc1e26439/src/StrategyArb.sol#L71-L78

function claimAndSwap(uint256 _amountClaim, uint256 _minOut, IRamsesRouter.route[] calldata _path) external onlyKeepers {
transmuter.claim(_amountClaim, address(this));
uint256 balBefore = asset.balanceOf(address(this));
_swapUnderlyingToAsset(_amountClaim, _minOut, _path);
uint256 balAfter = asset.balanceOf(address(this));
require((balAfter - balBefore) >= _minOut, "Slippage too high");
transmuter.deposit(asset.balanceOf(address(this)), address(this));
}

The attacker, MEV and profit seeking users have an incentive to front-run the swap. When the swap is not profitable the claimAndSwap will revert and no WETH will be swapped.

For illustrative purposes, I provided simplified calculations, omitting AMM formulas and liquidity details to focus on the concept of the exploit.

  1. A user deposits 100 alETH into the strategy, where 1 WETH is initially equal to 1 alETH.

  2. Over time, the value of 1 WETH increases to 1.1 alETH.

  3. The keeper calls the claimAndSwap function to claim 1 WETH and swap it for 1.1 alETH.

  4. An attacker or MEV bot front-runs the keeper’s transaction, causing the keeper’s transaction to fail.

  5. Meanwhile, alETH continues to be transmuted into WETH.

  6. When the user attempts to withdraw their funds, they are unable to do so because they can only claim alETH, while the WETH remains stuck in the Transmuter contract.

Impact

Funds will be stuck in Transmuter contract due to lack of proper implementation in the StrategyArb contract.

It is important to note that this report specifically addresses the vulnerability in the StrategyArb contract. While the claimAndSwap function is implemented in all three strategies, the root causes of the issue are different and one fix will not fix all of the three issues.

Tools Used

Manual review

Recommended Mitigation

Consider implementing a new function to manage WETH in a way that allows users to withdraw their funds under fair conditions.

Updates

Appeal created

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
ke1caM Submitter
10 months ago
inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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