For the complete documentation index, see llms.txt. This page is also available as Markdown.

58769 sc high forcerepay fails to decrement global cumulativeearmarked causing redemption accounting desynchronization and potential protocol wide redemption halt

Submitted on Nov 4th 2025 at 12:43:00 UTC by @Pataroff for Audit Comp | Alchemix V3

  • Report ID: #58769

  • Report Type: Smart Contract

  • Report severity: High

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

  • Impacts:

    • Smart contract unable to operate due to lack of token funds

Description

Brief/Intro

The cumulativeEarmarked variable, which tracks protocol-wide earmarked debt for redemptions, is properly decremented during normal repay() calls. However, during liquidations, which calls _forceRepay(), the same reduction is not applied. As a result, cumulativeEarmarked remains overstated even though the underlying debt and collateral have been settled.

Vulnerability Details

When a user repays debt normally using repay(), the protocol decreases both the user’s earmarked amount and the global cumulativeEarmarked:

function repay(uint256 amount, uint256 recipientTokenId) public returns (uint256) {
    ...
    // Repay debt from earmarked amount of debt first
    uint256 earmarkToRemove = credit > account.earmarked ? account.earmarked : credit;
@>  account.earmarked -= earmarkToRemove;

    uint256 earmarkPaidGlobal = cumulativeEarmarked > earmarkToRemove ? earmarkToRemove : cumulativeEarmarked;
@>  cumulativeEarmarked -= earmarkPaidGlobal;
    ...
}

However, during liquidations (alchemist.liquidate()), the protocol internally calls _forceRepay(). This function correctly updates the user’s local account.earmarked but never decreases the global cumulativeEarmarked value. This creates a permanent mismatch between real earmarked debt and what the protocol believes is earmarked.

Impact Details

References

AlchemistV3.sol#L498-L546

AlchemistV3.sol#L738-L782

Proof of Concept

Proof of Concept

Was this helpful?