56498 sc low reserve drainage due to incorrect balance measurement
Description
Summary
Description
The Bug
function _deallocate(uint256 amount) internal override returns (uint256) {
// ...
vault.withdraw(amount, address(this), address(this)); // Withdrawal happens here
// BOTH reads happen AFTER the withdrawal
uint256 wethBalanceBefore = TokenUtils.safeBalanceOf(address(weth), address(this));
uint256 wethBalanceAfter = TokenUtils.safeBalanceOf(address(weth), address(this));
uint256 wethRedeemed = wethBalanceAfter - wethBalanceBefore; // Always ≈ 0
// This check is meaningless since wethRedeemed ≈ 0
require(wethRedeemed + wethBalanceBefore >= amount, ...);
// This only checks total balance, not what the vault actually returned
require(TokenUtils.safeBalanceOf(address(weth), address(this)) >= amount, ...);
return amount; // Claims success even if vault returned less
}How It Fails
Impact
1. Theft of Unclaimed Yield
2. Temporary Freezing of Funds
Mitigation
Fix: Measure Balance Before and After Withdrawal
Alternative: Slippage Tolerance
Proof of Concept
Proof of Concept
Import the following in MorphoYearnOGWETHStrategyTest.t.sol
MorphoYearnOGWETHStrategyTest.t.solPaste the test in MorphoYearnOGWETHStrategyTest.t.sol
MorphoYearnOGWETHStrategyTest.t.solRun it via `forge test --mt test_deallocate_drains_strategy_reserves_silently -vvv
Logs
Previous57930 sc high allocation tracking underflow in strategy deallocation leads to protocol insolvencyNext58728 sc medium when the strategy is at a loss the assets cannot be withdrawn
Was this helpful?