56757 sc high incorrect leftover collateral check blocks liquidator fee payment leading broken incentives delayed deleveraging
Submitted on Oct 20th 2025 at 12:42:31 UTC by @yesofcourse for Audit Comp | Alchemix V3
Report ID: #56757
Report Type: Smart Contract
Report severity: High
Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistV3.sol
Impacts:
Temporary freezing of funds for at least 1 hour
Description
Brief/Intro
In AlchemistV3._doLiquidation, the protocol debits the gross seized collateral (including the liquidator’s base fee) from the victim, then always forwards the net amount to the Transmuter-but only pays the base fee to the liquidator if the account still has “leftover” collateral after that gross debit.
When the seizure consumes all collateral (common), the fee is withheld, making liquidations uneconomic. Reduced liquidator participation leads to stalled deleveraging, which can temporarily freeze user funds that depend on liquidations to proceed.
Vulnerability Details
src/AlchemistV3.sol, liquidation path inside _doLiquidation(...).
What happens :
Why this is a bug
The base fee is part of the gross seizure already removed from the victim. Payment to the liquidator should not depend on any post-seizure “leftover collateral” in the account.
If the seizure consumes the account (common on marginal positions),
account.collateralBalance == 0and the conditional check fails—no fee is paid. Value stays pooled in the contract (not stolen), but the liquidator isn’t compensated as designed.
Concrete example
Victim has
XMYT shares; liquidation computesamountLiquidated = XandfeeInYield = f(0<f<X)._doLiquidationdebitsX(victim balance →0), sendsX-fto Transmuter, then checks if0 >= fto pay the fee → false → fee not paid.Liquidator executed the work but received no base fee even though it was included in the gross seizure.
Liquidations rely on external actors (searchers/keepers). If fees are frequently withheld in “full wipe” cases, the expected payout is inconsistent or negative (after gas + risk). Rational liquidators stop participating.
With fewer liquidations, unhealthy positions linger; vault rebalances and user withdrawals that depend on deleveraging can revert or be delayed until market conditions or buffers change.
Impact Details
Temporary freezing of funds for at least 1 hour. When liquidations become uneconomic, deleveraging stalls. Withdrawals/rebalances that require collateral to be freed or debt to be burned can revert, temporarily freezing user funds until incentives are fixed or conditions change.
Any liquidation that fully (or nearly fully) consumes a victim’s collateral can exhibit the issue.
Repeated occurrences reduce keeper participation across the system, compounding deleveraging delays during stress—precisely when timely liquidations are most needed.
References
Contract:
src/AlchemistV3.solFunction:
_doLiquidation(...)(liquidation path where fee is gated byaccount.collateralBalance >= feeInYieldafter debiting the grossamountLiquidated): https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistV3.sol#L878-L880Related types:
calculateLiquidation(...)(providesliquidationAmountandbaseFee),convertDebtTokensToYield(...), and calls toTokenUtils.safeTransfer(...)for Transmuter and liquidator payouts. https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistV3.sol#L1244-L1291
Proof of Concept
Proof of Concept
Paste the following in AlchemistV3.t.sol and run with forge test --match-test test_LiquidationBaseFee_Withheld_When_NoLeftoverCollateral:
Was this helpful?