Assessment reports>Concrete>Medium findings>Potential underflow in ,MorphoVaultStrategy._protocolWithdraw, could lead to withdrawal failure
Category: Coding Mistakes

Potential underflow in MorphoVaultStrategy._protocolWithdraw could lead to withdrawal failure

Medium Impact
Medium Severity
Low Likelihood

Description

When users withdraw from a Concrete Vault that uses a MorphoVaultStrategy, the vault withdraws a portion of assets from the MorphoVaultStrategy, and execution proceeds to the _protocolWithdraw function.

The _protocolWithdraw function in MorphoVaultStrategy does not validate whether the assets_ parameter exceeds the contract's current _assetBalance before performing the subtraction assets_ -= _assetBalance. This omission causes an arithmetic underflow when _assetBalance exceeds assets_.

function _protocolWithdraw(uint256 assets_, uint256) internal virtual override {
    address _asset = asset();
    uint256 _assetBalance = IERC20(_asset).balanceOf(address(this));
    if (_assetBalance > 0) {
        assets_ -= _assetBalance;
    }
    // [...]
}

The asset balance of the MorphoVaultStrategy contract (_assetBalance) can exceed the requested withdrawal amount (assets_) in two scenarios:

  1. The _autoCompoundRewards function executes before the withdrawal and swaps harvested MORPHO reward tokens into asset tokens.

  2. An attacker transfers assets directly to the MorphoVaultStrategy to inflate _assetBalance.

When either scenario occurs, withdrawal attempts revert due to arithmetic underflow.

Impact

Users cannot withdraw their funds from the vault when the MorphoVaultStrategy's asset balance exceeds the requested withdrawal amount. Withdrawals remain blocked until other users' withdrawals reduce the strategy's asset balance below the requested amount.

Recommendations

Consider adding an early return in _protocolWithdraw when the strategy's asset balance satisfies the withdrawal request.

function _protocolWithdraw(uint256 assets_, uint256) internal virtual override {
    address _asset = asset();
    uint256 _assetBalance = IERC20(_asset).balanceOf(address(this));
    if (_assetBalance > 0) {
+        if (assets_ <= _assetBalance) return;
        assets_ -= _assetBalance;
    }
    // [...]
}

Remediation

This issue has been acknowledged by Blueprint Finance, and a fix was implemented in commit 4b5f74fa.

Zellic © 2025Back to top ↑