58383 sc high due to cumulativeearmarked not being updated in alchemix forcerepay user funds are locked longer due to slower debt decay and calculation of system collaterization rate is inc
Due to cumulativeEarmarked not being updated in Alchemix::_forceRepay user funds are locked longer due to slower debt decay and calculation of system collaterization rate is Incorrect
Description: When a position is liquidated, AlchemistV3::_liquidate() first calls AlchemistV3::_forceRepay(accountId, account.earmarked) to clear the position’s earmarked debt using its collateral. Inside _forceRepay, the account’s local earmarked is reduced, but the global cumulativeEarmarked is not decremented to reflect that removal.
Because redeem() uses cumulativeEarmarked as the live denominator for decay/weight math, an inflated cumulativeEarmarked causes subsequent redemptions to be allocated over a larger-than-real bucket. Remaining users’ earmarks decay too slowly, delaying their debt reduction and effectively keeping their funds locked longer than intended.
As well because AlchemistV3::_forceRepay(accountId, account.earmarked) decrements totalDebt through AlchemistV3::subDebt without updating cumulativeEarmarked, AlchemistV3::redeem subtracts that phantom portion from totalDebt a second time (totalDebt -= redeemedDebtTotal, redeemedDebtTotal is inflated because cumulativeEarmark is inflated). This results in a defalted totalDebt which subsequently affects liquidations because it affects calculation of system collaterization (alchemistCurrentCollateralization uses totalDebt in the denominator). This makes liquidations less likely when they should happen.
By contrast, repay() correctly decrements both the account’s earmarked and the global cumulativeEarmarked.
Impact:
Users debt experience slower-than-correct earmark decay compared to the amount of collateral they lose after any _forceRepay event. This delays their redemptions and extending time-to-unlock.
Deflated Total Debt -> Inflated System collaterization -> Affects liqudations -> Affects Protocol Solvency.
Proof of Concept
Proof of Concept:
The provided test testPOC_ForceRepay_SlowsDecay_WithBurn() demonstrates:
Two users A & B mint near the minimum collateralization and build earmarks.
A triggers liquidation. _forceRepay() zeros A’s local earmarked but does not reduce cumulativeEarmarked. The test asserts:
A small redeem() is executed. Because redeem() uses the inflatedcumulativeEarmarked as denominator, B’s observed earmark drop is less than the ideal drop computed using the true live sum of earmarks. The test verifies:
The total debt reduction matches the inflated-denominator cap.
B_ChangeInEarMark * liveEarmarkSum < B_EarmarkBeforeRedeem * ObservedTotalDebtReduction (i.e., B’s earmark decays too slowly, and is not proportional to the amount of debt reduced in the system).
As well we assert totalDebt < Sum(A.debt + b.debt) even after they have been synced.
To run the POC paste the below code in AlchemistV3.t.sol and run the test using the command forge test --mt testPOC_ForceRepay_SlowsDown_DebtDecay