58163 sc critical total loss of user funds in claim redemption

Submitted on Oct 31st 2025 at 02:37:26 UTC by @MentemDeus28 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58163

  • Report Type: Smart Contract

  • Report severity: Critical

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

  • Impacts:

    • Theft of unclaimed yield

Description

Brief/Intro

when all earmarked debt is redeemed, cumulativeEarmarked = 0.The _earmark function in AlchemistV3 cancels valid transmutation signals from the transmuter when queryGraph returns a value less than or equal to coverInDebt. This causes cumulativeEarmarked to remain zero even when users have legitimately transmuted synthetic debt into redeemable yield. As a result, the redeem function is called with amount = 0, and claimRedemption pays only the transmuter’s local balance (often dust). The user’s position is then deleted, resulting in permanent loss of 99%+ of expected redemption value, a total loss of funds.

uint256 amount = ITransmuter(transmuter).queryGraph(lastEarmarkBlock + 1, block.number);
uint256 coverInDebt = convertYieldTokensToDebt(transmuterDifference);
amount = amount > coverInDebt ? amount - coverInDebt : 0;  

Vulnerability Details

The Transmuter claimRedemption function can finalize a user’s position and permanently delete it even when no yield has been earmarked from the Alchemist, resulting in no yield token payout (MYT) and a loss of future yield entitlement.

However, under certain protocol states, cumulativeEarmarked can remain zero, especially periods when earmark conditions are not met. This leads to an empty redeem execution and a dust or zero distributable value.

However, the system still executes:

which erases the user’s redemption position and burns the synthetic tokens, even though they were never truly converted into yield. Position is deleted , irreversible.

Impact Details

User receives little or no yield (MYT) even though some portion of their position or full position is considered transmuted.

consider making these changes in claimRedeemption function

References

https://github.com/alchemix-finance/v3-poc/blob/a192ab313c81ba3ab621d9ca1ee000110fbdd1e9/src/Transmuter.sol#L191

Proof of Concept

Proof of Concept

Expected Output

Ran 1 test for src/test/MyPoc.t.sol:AlchemistV3POCGROUND [PASS] test_redeem_DoS_when_no_earmark() (gas: 1879526) Logs: cumulativeEarmarked:: 0

Expected:: 50000000000000000000

MYT Received:: 1990000000000000000

Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 63.48ms (21.57ms CPU time)

User staked 50e18 and after a successful transmutation he received 1.99e18 Losing 99% of his funds

Was this helpful?