56873 sc medium incorrect eth wrapping condition in moonwellwethstrategy deallocate leads to temporary freezing of funds

Submitted on Oct 21st 2025 at 12:45:51 UTC by @flora for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #56873

  • Report Type: Smart Contract

  • Report severity: Medium

  • Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/strategies/optimism/MoonwellWETHStrategy.sol

  • Impacts:

    • Temporary freezing of funds for at least 1 hour

Description

Brief/Intro

A logical flaw exists in the _deallocate function of the MoonwellWETHStrategy and StargateEthPoolStrategy contracts. The condition for wrapping redeemed ETH into WETH is incorrect, causing the function to fail and revert when deallocating funds under certain common scenarios, such as minor redemption losses. While this bug does not lead to a direct loss of funds, it results in a denial of service for deallocations, making withdrawals from the strategy unreliable and causing wasted gas.

Vulnerability Details

The root cause of the vulnerability is an incorrect conditional check on line 64 of MoonwellWETHStrategy.sol. When deallocating, the strategy redeems mWETH for native ETH and is supposed to wrap this ETH into WETH to be returned to the vault. However, the wrapping logic is executed only if ethRedeemed + ethBalanceBefore >= amount, which is mathematically equivalent to ethBalanceAfter >= amount.

Problematic Code: src/strategies/optimism/MoonwellWETHStrategy.sol:64-66

// ...
if (ethRedeemed + ethBalanceBefore >= amount) {
    weth.deposit{value: ethRedeemed}();
}
require(TokenUtils.safeBalanceOf(address(weth), address(this)) >= amount, "...");
// ...

This logic is flawed because the intention, as stated in the code comments, is to wrap any ETH received. The condition fails if there is a slight loss during redemption (i.e., ethRedeemed < amount) and the contract has no pre-existing ETH balance (ethBalanceBefore == 0). In this case:

  1. The if condition evaluates to false.

  2. The redeemed ETH is not wrapped into WETH.

  3. The subsequent require statement, which checks that the contract's WETH balance is sufficient (>= amount), fails and reverts the transaction.

This issue is also present in StargateEthPoolStrategy.sol due to code duplication.

Impact Details

The primary impact of this vulnerability is a Denial of Service (DoS) for the deallocate functionality. Any attempt to deallocate from the strategy will fail if there is a redemption loss and no residual ETH in the contract to satisfy the flawed condition. This makes the withdrawal process unreliable and dependent on unpredictable contract state (residual ETH). While the reverting transaction prevents permanent fund loss or lock, it leads to:

  • Operational Failure: Legitimate deallocations cannot be processed, preventing funds from being moved out of the strategy.

  • Wasted Gas: All failed attempts to deallocate will consume gas without successfully executing.

  • Reduced System Reliability: The strategy's core function of deallocation becomes unstable and unreliable.

The severity is medium, as it impacts a core function of the protocol under normal operating conditions, even without malicious intent.

References

  • Affected Contract 1: src/strategies/optimism/MoonwellWETHStrategy.sol

  • Affected Contract 2: src/strategies/optimism/StargateEthPoolStrategy.sol

Proof of Concept

Proof of Concept

Was this helpful?