58648 sc low incorrect wethbalancebefore read causes broken loss detection in deallocation
Submitted on Nov 3rd 2025 at 19:35:04 UTC by @Khay3 for Audit Comp | Alchemix V3
Report ID: #58648
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
Description
Summary
A balance snapshot is taken after withdrawal in MorphoYearnOGWETHStrategy::_deallocate, making wethRedeemed always zero and breaking loss detection.
Vulnerability details
MorphoYearnOGWETHStrategy::\_deallocate reads wethBalanceBefore after the withdrawal. Since both “before” and “after” balances are read post-withdrawal, their difference is always zero, masking any loss and causing misleading events.
MorphoYearnOGWETHStrategy::_deallocate():
function _deallocate(uint256 amount) internal override returns (uint256) {
vault.withdraw(amount, address(this), address(this)); // Withdrawal happens FIRST
uint256 wethBalanceBefore = TokenUtils.safeBalanceOf(address(weth), address(this)); // Read AFTER
uint256 wethBalanceAfter = TokenUtils.safeBalanceOf(address(weth), address(this)); // Same value
uint256 wethRedeemed = wethBalanceAfter - wethBalanceBefore; // Always 0
if (wethRedeemed < amount) {
emit StrategyDeallocationLoss("Strategy deallocation loss.", amount, wethRedeemed);
}
require(TokenUtils.safeBalanceOf(address(weth), address(this)) >= amount, "Strategy balance is less than the amount needed");
TokenUtils.safeApprove(address(weth), msg.sender, amount);
return amount;
}In comparison with other strategies, they implemented this correct (Read balance before wtihdrawal)
Example scenario
Morpho vault experiences issues and return only 95TH when 100 ETH was requested. Strategy cannot deter the 5ETH loss(wethRedeemd shows 0 instead of 95). The loss event incorrectly shows StrategyDeallocationLoss("...", 100, 0) instead of StrategyDeallocationLoss("...", 100, 95). If the loss is within the require tolerance, it goes completely unnoticed
Impact
This lead to the system not being able to detect actual losses from vault withdrawals. The StrategyDeallocationLoss event will always fire, since 0 < amount is always true, even when there's no loss
Likelihood
This will occur on every deallocation but mitigated with the require statement
Recommendation
Read the WETH balance before the withdrawal, then withdraw, then read after, and compute the delta from those two readings.
Proof of Concept
paste in src/test/strategies/MorphoYearnOGWETHStrategy.t.sol and run with forge test --match-test test_strategy_deallocate_wrong_balance_calculation -vvv
Was this helpful?