58515 sc medium a liquidated position can end the liquidation process still below collateralizationlowerbound allowing for double liquidation of positions

Submitted on Nov 2nd 2025 at 23:36:41 UTC by @Tadev for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58515

  • Report Type: Smart Contract

  • Report severity: Medium

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

  • Impacts:

    • Contract fails to deliver promised returns, but doesn't lose value

Description

Brief/Intro

If a position's collateralization ratio is too low, below collateralizationLowerBound, it becomes eligible for liquidation.

The purpose of the liquidate function is to restore the collateralization ratio:

  • above collateralizationLowerBound in the case of a force repay of the earmarked debt big enough to restore the ratio above collateralizationLowerBound

  • above minimumCollateralization in the case of a real liquidation that triggers _doLiquidation

The problem arises because the current design allows for a position to be liquidated twice via liquidate function. Indeed, there is a possibility for the first liquidation not to restore a ratio above collateralizationLowerBound while still being successful.

Vulnerability Details

The issue lies in the _liquidate function, at the end:

At this point of the function, if the position had earmarked debt, a _forceRepay happened, potentially restoring the ratio above collateralizationLowerBound.

The problem arises when the forceRepay call restores a ratio juste above collateralizationLowerBound. In that case, the else branch is executed and the fee is calculated and sent to the liquidator. This means we check the ratio first, and after that the liquidator fee reduces the account.collateralBalance in _resolveRepaymentFee function:

Because we don't check again the collateralization ration, it is possible that the fee sent to the liquidator puts the position back below collateralizationLowerBound. In this case, the liquidate call is successful but the position is still eligible for liquidation.

Impact Details

The impact of this issue can be considered medium as it result in a significant disruption of the liquidation process. Liquidations are expected to work properly and restore the ratios without issues.

Proof of Concept

Proof of Concept

Please copy paste the following test in AlchemistV3.t.sol file:

This tests highlights a situation where a user position is liquidated twice in a row. The output of the test is :

This output shows:

  • a position collateralization ratio below collateralizationLowerBound before first liquidation

  • a collateralization ratio still below collateralizationLowerBound after the first liquidation which is not supposed to happen

  • a collateralization ratio at the target minimum collateralization ratio after the second liquidation

Was this helpful?