The MorphoYearnOGWETHStrategy._deallocate() function measures balance AFTER withdrawal instead of BEFORE, causing wethRedeemed to always be 0 and making the function revert on any withdrawal loss.
function_deallocate(uint256amount)internaloverridereturns(uint256){ vault.withdraw(amount,address(this),address(this));// Line 49: Withdrawal happens HEREuint256 wethBalanceBefore = TokenUtils.safeBalanceOf(address(weth),address(this));// Line 50: Measured AFTER withdrawaluint256 wethBalanceAfter = TokenUtils.safeBalanceOf(address(weth),address(this));// Line 51: Same value!uint256 wethRedeemed = wethBalanceAfter - wethBalanceBefore;// Line 52: Always 0if(wethRedeemed < amount){emitStrategyDeallocationLoss("Strategy deallocation loss.", amount, wethRedeemed);}require(wethRedeemed + wethBalanceBefore >= amount,"Strategy balance is less than the amount needed");// Line 56: Will fail...}
Root Cause
Lines 50-51 both measure balance AFTER the withdrawal (line 49), making them equal. Therefore wethRedeemed = 0 always.
Impact
Severity: HIGH - Denial of Service
Any deallocate with slippage/loss will revert
Cannot withdraw from strategy when market conditions cause losses
Funds stuck in strategy
Protocol cannot rebalance allocations
Proof of Concept
How to run the POC:
Scenario: Deallocate 100 WETH with 2 WETH loss
Execution Flow:
Expected:wethRedeemed should be 98 (actual received amount) Actual:wethRedeemed is 0, causing revert
Code Comparison
Correct Implementation (TokeAutoEth):
Buggy Implementation (MorphoYearn):
Recommendation
Move the wethBalanceBefore measurement BEFORE the withdrawal: