58542 sc low low logic error in morphoyearnogwethstrategy deallocate wethredeemed always zero all deallocations emit strategydeallocationloss

#58542 [SC-Low] [Low] Logic Error in MorphoYearnOGWETHStrategy._deallocate(): `wethRedeemed` Always Zero → All Deallocations Emit `StrategyDeallocationLoss`

Submitted on Nov 3rd 2025 at 06:16:49 UTC by @chief_hunter888 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58542

  • Report Type: Smart Contract

  • Report severity: Low

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

  • Impacts:

    • Contract fails to deliver promised returns, but doesn't lose value

    • Broken accounting / misreported events

Description

[Low] Logic Errors in MorphoYearnOGWETHStrategy._deallocate(): wethRedeemed Always Zero → All Deallocations Emit StrategyDeallocationLoss

Summary of the bug

The _deallocate() implementation in MorphoYearnOGWETHStrategy.sol contains a logic error that causes the variable wethRedeemed to always record as zero, even when WETH is correctly redeemed and returned to the adapter contract.

This happens because the contract reads its WETH balance twice after the redemption using identical logic, but does not store the “before” value prior to calling the redemption. As a result, both readings occur after the redemption has completed — making their relative difference zero every time.

[Low] - Bug #1 Faulty Event Emission and Accounting Issues

This bug breaks both accounting and event reporting for every deallocate() execution:

  1. Incorrect Event Emission: The StrategyDeallocationLoss` event is always emitted, falsely signaling a strategy loss, when there was none. The event becomes a meaningless waste of gas and does not alert about real strategy losses.

  2. Incorrect Data Reporting: The StrategyDeallocationLos event’s wethRedeemed field is always emitted as 0, even when WETH was actually redeemed and transferred correctly. This breaks the accounting of the backend services, because before this field was used to infer how much WETH was redeemed if the amount was less than the targeted amount. Now there is no way of knowing this from the event.

  3. False Loss Reporting: The strategy will always appear to operate at a loss, which may prevent it from being selected or used in yield allocation decisions.

  4. While funds are not directly stolen or misallocated, this bug erodes the integrity of accounting and monitoring, making it impossible to trust strategy-level performance data.

[Insight] Finding - Bug #2 Costly and Unnecessarily Complex Require Statement

Additionally, the require on line 57 relies on the faulty wethRedeemed value:

The lefthandside of the require statement introduces additional gas cost because the wethRedeemed + wethBalanceBefore is the same as the wethBalanceAfter, a variable available and already cached a few lines above, which could be used here instead to improve code clarity and reduce gas costs by avoiding duplicate calculations.

Context

The MorphoYearnOGWETHStrategy.sol is a strategy adapter in the Alchemix system that: Role:

  • Acts as a bridge between Alchemix's MYT Vault and the Morpho Yearn vault

  • Receives WETH from the MYT vault

  • Deposits it into the Morpho Yearn OG WETH vault

  • Gets vault shares in return

  • Withdraws WETH when deallocating (this is where the bug is!)

The adapter connects to the Morpho Yearn vault which is a yield-bearing ERC4626 tokenized vault created by Yearn Finance that is expected to accrue value over time. Upon deposit Alchemix gets a share in the tokenized vault, which reflects the amoun of deposited WETH and is expected to accrue more WETH over time (ctoken style).

Now, the bug is that the adapter's faulty implementation of the _deallocate() functionality incorrectly registers the redeemed WETH amount as zero, when it was actually redeemed back to the adapter contract.

// Allocation (✅ Works correctly) _allocate(100 WETH) { 1. Strategy receives 100 WETH from MYT vault 2. Approves Morpho Yearn vault to spend WETH 3. Calls vault.deposit(100 WETH) 4. Receives ~98 vault shares (ERC4626 conversion) 5. Strategy now holds shares representing 100 WETH value }

// Deallocation (❌ BUG HERE!) _deallocate(105 WETH) { 1. vault.withdraw(105 WETH) → Burns shares, returns ~104.x WETH 2. wethBalanceBefore = 104.x WETH ❌ (measured AFTER withdrawal!) 3. wethBalanceAfter = 104.x WETH 4. wethRedeemed = 0 ❌ (always zero!) 5. Require statement would fail because it 0 + 104.x WETH >= 105 WETH, which fails. ❌ }

Vulnerability Details

Root Cause

In the _deallocate function of MorphoYearnOGWETHStrategy (lines 49-61), the WETH balance is measured twice after the withdrawal has already occurred:

Severity Justification

Impact Medium/Low

  1. Faulty Strategy Loss Alerting: Produces misleading “loss” events for every deallocation. Alerting feature is lost, there is no way of knowing how much WETH was redeemed, if it was less than the requested amount.

  2. Incorrect Accounting Data & Data Loss: Corrupts both on-chain and off-chain accounting data via faulty accounting information emission. While it does not immediately steal funds, it undermines the integrity of the protocol’s core accounting. Once this bug is deployed, there is no way of retroactively fixing the past events.

Please refer to the POC tests that illustrate the incorrect event emission. This is definitely at least a low finding because the code does not provide the desired returns, it does not loose funds, but given the impact on the backend accounting services is huge, this might be ranked even higher. The backend is required to be up to date to input correct input data into the deallocate() function.

Likelihood: EXTREMELY HIGH

  • Affects every single deallocation operation

  • Bug is always active, not dependent on external conditions

  • Will manifest as soon as any yield accrues

Recommendations

Fix

Move the wethBalanceBefore measurement to before the withdrawal:

Proof of Concept

Proof of Concept

Please add this test to MorphoYearnOGWETHStrategy.t.sol

full test file

Was this helpful?