58422 sc low morphoyearn og weth strategy always emits deallocation loss event due to zero delta calculation

Submitted on Nov 2nd 2025 at 08:30:27 UTC by @unineko for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58422

  • Report Type: Smart Contract

  • Report severity: Low

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

  • Impacts:

Description

1. Title

MorphoYearn OG WETH strategy always emits deallocation-loss event due to zero delta calculation

Scope commit: a192ab313c81ba3ab621d9ca1ee000110fbdd1e9

2. Description

Brief/Intro

MorphoYearnOGWETHStrategy._deallocate measures the strategy’s WETH balance both before and after a withdraw call after the assets have already been returned. As a result, wethRedeemed is always zero, causing StrategyDeallocationLoss to emit even when the withdraw completes successfully. Worse, if the vault actually returns less than requested, the function reverts after the (incorrect) event and the revert rolls the log back, so no alert is emitted. The signal becomes an anti-signal: guaranteed false positives during healthy operation and no persistent alert when losses really happen.

Vulnerability Details

  • The strategy intends to compare the WETH balance before and after vault.withdraw(amount, ...) to detect shortfalls.

  • The current implementation calls TokenUtils.safeBalanceOf(...) twice after withdrawal, so wethBalanceBefore == wethBalanceAfter, making wethRedeemed == 0 regardless of actual redemption.

  • The strategy then checks if (wethRedeemed < amount) and emits StrategyDeallocationLoss, so every deallocation logs a loss event even when the exact amount was returned. This produces constant false positives and erodes operator trust.

  • When the vault really returns less than amount, the subsequent require statements revert, rolling back the event and leaving no trace (false negative). The monitoring hook never records the loss, defeating its purpose.

  • The PoC executes both a lossless and a “haircut” deallocation in a mock environment, demonstrating the false-positive / false-negative pair.

Impact Details

  • Operational noise / monitoring false positives: Every healthy deallocation triggers a loss alert, overwhelming dashboards and pagers.

  • False negatives for real losses: When a vault underpays, _deallocate reverts after emitting the event, so the log rolls back and the loss goes unreported. Observability is effectively inverted.

  • Automation and debugging friction: Automated safeguards or incident responders relying on StrategyDeallocationLoss cannot distinguish real issues, raising operational risk even without direct fund loss.

References

  • Affected code: src/strategies/mainnet/MorphoYearnOGWETH.sol::_deallocate

  • PoC: src/test/L1_MorphoYearnOGWETHLossEvent.t.sol::{testLossEventAlwaysTriggersWithNoActualLoss,testLossEventDoesNotPersistWhenActualLossOccurs}

Steps to Reproduce

  1. Check out the scoped commit and install dependencies (forge install).

  2. Run the PoC (Cancun EVM):

  3. Observe that:

    • StrategyDeallocationLoss fires even though the mock vault returns the full AMOUNT (testLossEventAlwaysTriggersWithNoActualLoss).

    • When the vault returns amount - 1, _deallocate reverts and the event is rolled back (testLossEventDoesNotPersistWhenActualLossOccurs).

Technical Details

  • To compute the true delta, wethBalanceBefore must be sampled before calling vault.withdraw.

  • Alternatively, the vault’s return value could be trusted as the redeemed amount.

  • Without fixing the order of operations, the event is guaranteed to indicate losses on every withdrawal, undermining its purpose.

  1. Capture the strategy’s WETH balance prior to calling vault.withdraw:

  2. Emit the loss event only when wethRedeemed < amount, and decide whether to revert or surface the loss depending on protocol policy.

  3. Optionally, reset allowances (to zero) before reuse to align with ERC20 best practices and add regression tests covering both full and partial redemptions.

Supporting Evidence

  • PoC demonstrates the constant loss event emission in a “no-loss” scenario.

  • The existing code clearly reads balances after the withdrawal, explaining the zero delta.

  • Fixing the measurement order restores meaningful loss detection without affecting strategy flows.

Proof of Concept

Was this helpful?