58672 sc low incorrect balance check sequence

Submitted on Nov 4th 2025 at 00:20:21 UTC by @Shivansh for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58672

  • Report Type: Smart Contract

  • Report severity: Low

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

  • Impacts:

    • Permanent freezing of funds

Description

Brief/Intro

The _deallocate function contains a critical logic error where balanceBefore is calculated AFTER the vault.withdraw() call instead of before. This means balanceBefore and balanceAfter will always be identical values, causing wethRedeemed to always equal 0. Since the function checks if (wethRedeemed < amount) and reverts when true, this function will ALWAYS revert, making it impossible to withdraw funds from the strategy. This is a permanent denial of service that locks all funds in the vault.

Vulnerability Details

The _deallocate function contains a critical logic error where balanceBefore is calculated AFTER the vault.withdraw() call instead of before. This means balanceBefore and balanceAfter will always be identical values, causing wethRedeemed to always equal 0. Since the function checks if (wethRedeemed < amount) and reverts when true, this function will ALWAYS revert, making it impossible to withdraw funds from the strategy. This is a permanent denial of service that locks all funds in the vault.

function _deallocate(uint256 amount) internal override returns (uint256) {
        vault.withdraw(amount, address(this), address(this));
        uint256 balanceBefore = TokenUtils.safeBalanceOf(address(weth), address(this));
        uint256 balanceAfter = TokenUtils.safeBalanceOf(address(weth), address(this));
        uint256 wethRedeemed = balanceAfter - balanceBefore;
        
        if (wethRedeemed < amount) {
            emit StrategyDeallocationLoss("Strategy deallocation loss.", amount, wethRedeemed);
            revert("StrategyDeallocationLoss");
        }
        
        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;
    }

Impact Details

All funds deposited into the strategy become permanently locked. Users cannot withdraw their WETH from the vault, resulting in complete loss of funds. The strategy becomes unusable after any allocation since deallocations will always fail.

References

Link : - https://github.com/alchemix-finance/v3-poc/blob/a192ab313c81ba3ab621d9ca1ee000110fbdd1e9/src/strategies/mainnet/MorphoYearnOGWETH.sol#L51

Proof of Concept

Proof of Concept

For running the test , Go in a file in src/test/strategies/MorphoYearnOGWETHStrategy.t.sol , delete the old code , then copy this given code and paste it there .

I used the setup for testing which is already in the file, where function is tested.

after this run a command

Running Tests

Was this helpful?