58639 sc medium off by one issue in the forcerepay function causes protocol to lose funds in the form of protocol fee

Submitted on Nov 3rd 2025 at 18:32:54 UTC by @Tarnishedx0 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58639

  • Report Type: Smart Contract

  • Report severity: Medium

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

  • Impacts:

Description

Brief/Intro

Off by One issue in the _forceRepay() function causes protocol to lose funds in the form of protocol fee.

Vulnerability Details

In the _forceRepay() function, protocolFeeTotal is paid when account.collateralBalance > protocolFeeTotal.

    function _forceRepay(uint256 accountId, uint256 amount) internal returns (uint256) {
...
        if (account.collateralBalance > protocolFeeTotal) {
            account.collateralBalance -= protocolFeeTotal;
            // Transfer the protocol fee to the protocol fee receiver
            TokenUtils.safeTransfer(myt, protocolFeeReceiver, protocolFeeTotal);
        }
...

But what if whenaccount.collateralBalance = protocolFeeTotal.

The check should be account.collateralBalance >= protocolFeeTotal where >= should be used instead of =.

Impact Details

Loss of funds for the protocol when account.collateralBalance = protocolFeeTotal.

References

The above code snippets can be verified here: https://github.com/alchemix-finance/v3-poc/blob/a192ab313c81ba3ab621d9ca1ee000110fbdd1e9/src/AlchemistV3.sol#L771-L775

Proof of Concept

Proof of Concept

Paste the above test in the AlchemistV3.t.sol contract, set up $MAINNET_RPC_URL and run it using:

Was this helpful?