57816 sc insight critical incentive failure in calculateliquidation leads to protocol insolvency risk during global bad debt

Submitted on Oct 29th 2025 at 02:03:47 UTC by @fullstop for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #57816

  • Report Type: Smart Contract

  • Report severity: Insight

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

  • Impacts:

    • Protocol insolvency

Description

Brief/Intro

A critical logic flaw exists in the AlchemistV3.sol contract's calculateLiquidation function. When the protocol becomes globally undercollateralized (a high-stress scenario), the function incorrectly sets the primary liquidator incentive (the base fee) to zero. This design fully relies on a secondary, exhaustible fee vault (alchemistFeeVault) to pay liquidators. If this secondary vault is empty—a predictable state during a market crash due to high liquidation volume—all liquidator incentives become zero. This halts all liquidation activity at the most critical time, preventing the protocol from clearing bad debt and leading to a "death spiral" that could result in total insolvency.

Vulnerability Details

The protocol's liquidation mechanism relies on two distinct fee sources to incentivize external liquidators:

  1. Base Fee (feeInYield): The primary and most reliable incentive. It is calculated based on the liquidated position's surplus and paid directly from the position's own collateral.

  2. Outsourced Fee (feeInUnderlying): A secondary, supplemental incentive. It is paid from an external alchemistFeeVault contract and is not guaranteed; if the vault is empty, this fee is 0.

The vulnerability is triggered when the protocol's total collateralization (alchemistCurrentCollateralization) drops below the alchemistMinimumCollateralization threshold. This is the exact moment the protocol is in greatest danger and relies most heavily on liquidators.

In this specific "global bad debt" scenario, the calculateLiquidation function enters a flawed logical branch:

As shown, the function intentionally returns 0 as the third value, which corresponds to the Base Fee.

This logic incorrectly switches off the reliable, primary incentive (fee) and shifts 100% of the incentive burden onto the unreliable, secondary outsourcedFee.

This creates a "perfect storm" scenario:

  1. A market crash causes alchemistCurrentCollateralization to fall, triggering the bug (fee = 0).

  2. The same market crash causes a high volume of liquidations, which rapidly drains the alchemistFeeVault as it pays out the outsourcedFee for each one.

  3. The alchemistFeeVault is an exhaustible buffer, not an infinite source. Once it is depleted (a predictable event in this scenario), the _doLiquidation function's check if (vaultBalance > 0) will fail, and the outsourcedFee will also become 0.

At this point, both the primary and secondary incentives are 0, and rational liquidators will no longer participate.

Impact Details

The severity of this vulnerability is Critical. It creates a "death spiral" scenario from which the protocol cannot recover.

The direct impact is the total loss of liquidator incentives during a protocol-wide crisis.

This leads to a cascading failure:

  1. Market Crash: The protocol becomes globally undercollateralized.

  2. Bug Triggered: The calculateLiquidation flaw sets the base fee to 0.

  3. Vault Drain: High liquidation volume (from the crash) drains the alchemistFeeVault, setting the outsourced fee to 0.

  4. Incentive Collapse: The total reward for liquidators becomes 0.

  5. Liquidation Halt: Rational liquidator bots stop all activity, as they would lose money on gas fees.

  6. Death Spiral: Bad debt (underwater positions) is no longer cleared from the system. The protocol's health (alchemistCurrentCollateralization) continues to fall, permanently locking the contract in the flawed logic branch.

  7. Protocol Insolvency: Unchecked bad debt accumulates until the protocol's liabilities (debt tokens) exceed its assets, leading to a loss of funds for all users.

References

Vulnerable Contract: AlchemistV3.sol

Flawed Function (calculateLiquidation): AlchemistV3.sol 1104)

Fee Payout Logic (_doLiquidation): AlchemistV3.sol

Fee Vault (alchemistFeeVault): AlchemistV3.sol

Proof of Concept

Proof of Concept

The following Foundry test, when added to AlchemistV3.t.sol, reproduces the vulnerability. It simulates the "perfect storm" by (1) triggering the global bad debt state via price manipulation and (2) emptying the alchemistFeeVault. It then asserts that the liquidator receives zero fees.

Was this helpful?