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

Strategy fails to consider a scenario with insufficient unexchangedBalance in transmuter, which can block users who wants to withdraw.

Summary

There can be a scenario where;

  • the AMMs does not trade at a discount price i.e. 1:1 or lower, which means Keeper is not allowed to convert WETH back to alETH

  • and the available unexchangedBalance is not enough to satisfy the users withdrawal

Users withdraw are possible because of the unexchangedBalance in the transmuter, and when this is 0 i.e. all alETH has been converted to WETH, and claimAnsSwap cannot be called , users have no way to withdraw their deposited alETH.

Now this is problematic because the users who wants to withdraw their alTokens will be forced to wait until the AMMs start trading at a discount price again i.e. more than 1:1 . Example- 1 ETH : 1.1 alETH

The problem is Alchemix cannot controll the prices of the AMMs nor is it guaranteed that AMMs will always trade alTokens at a discounted price.

Vulnerability Details

Example:

  • Bob and Alice deposits 1000 alETH each

  • the transmuter has converted all alETH fully to WETH, and the AMMs are trading at 1:1 (maintains peg)

  • Bob wants to withdraw his alETH, but gets reverted due to unexchangeBalance = 0(or insufficent) i.e. insufficient alETH to perform withdraw

  • Bob complains to the Keeper,

  • Keeper tries to increase unexcahnged balance through claimAndSwap but cannot since AMMs trade at 1:1 and due to the strict requirement check: require(minOut > _amount, "minOut too low");

  • Bob and Keeper cannot do anything but wait and hope for AMMs to trade at a discount

This is why we cannot neglect this scenario and allow swapping of WETH to alETH at 1:1, if there is any user who wants to withdraw.

Now, obviously the strategy is trying to profit from depegs through swaps hence the strict require statement, but this does not mean that we should lock users tokens even if they want to withdraw. And this report is not suggesting to swap at a loss, but rather allow swaps even when no loss no profit scenario to allow users withdraws.

The problem is not the require statement but the locking of users funds. Therefore, we need to allow swapping of tokens even at 1:1(no loss no profit) when users want to withdraw during the described scenario.

Impact

All users' tokens are locked and are forced to wait until the AMMs start trading below the peg again which is unpredictable and out of controll by the Strategy/Keeper.

The impact is high but since the likelyhood is low for the described scenario, I would like to rate the overall severity as medium.

Tools Used

manual

Recommendations

for StrategyOP and StrategyArb:

function _swapUnderlyingToAsset(uint256 _amount, uint256 minOut, IVeloRouter.route[] calldata _path) internal {
// TODO : we swap WETH to ALETH -> need to check that price is better than 1:1 // @audit does not consider the described scenario which can lock users' tokens
// uint256 oraclePrice = 1e18 * 101 / 100;
- require(minOut > _amount, "minOut too low");
+ require(minOut >= _amount, "minOut too low"); // allow 1:1 for described scenario, Keeper can still make profits when depegs
uint256 underlyingBalance = underlying.balanceOf(address(this));
require(underlyingBalance >= _amount, "not enough underlying balance");
IVeloRouter(router).swapExactTokensForTokens(_amount, minOut, _path, address(this), block.timestamp);
}

for the StrategyMainnet change this in the claimAnsSwap function:

- require(_minOut > _amountClaim, "minOut too low");
+ require(_minOut >= _amountClaim, "minOut too low");

Now the Keeper can swap some WETH for alETH to allow Bob's withdrawal.
And this does not mean that the Keeper will always swap at _minOut = _amountClaim it is to allow withdrawals only when necessary, and can still function as a profit swap.

Updates

Appeal created

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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