58061 sc high incorrect collateral and fee check in doliquidation allows liquidator to loose fee

Submitted on Oct 30th 2025 at 11:40:35 UTC by @Bizarro for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58061

  • Report Type: Smart Contract

  • Report severity: High

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

  • Impacts:

    • Permanent freezing of funds

Description

Brief/Intro

In _doLiquidation function where the contract checks that collateralBalance >= fee before transferring the fee to the liquidator(msg.sender). This is incorrect because, in calculateLiquidation, the fee is already included in the liquidationAmount returned and is removed from the user's collateral.

Vulnerability Details

The function double-counts the fee in the collateral balance check. The fee is included in the liquidationAmount(already removed from the user's balance), but the contract still checks if the remaining balance is sufficient to pay the fee again.

Path:

  1. User position: collateralBalance = 109, liquidationAmount = 100, fee = 10

  2. _doLiquidation removes 100 from collateralBalance, leaving 9.

  3. The fee check collateralBalance >= fee fails (9<10).

  4. Fee transfer to the liquidator does not occur, even though tokens are already removed from the user.

  • @3 = calculateLiquidation is returning (debtToBurn + fee, , fee,);

  • @1 = collateral is reduced by amountLiquidated (debtToBurn + fee converted to yield token)

  • @2 = after removing the fee from the collateral, collateralBalance >= feeInYield is required to transfer fee to the liquidator

Impact Details

If users' collateralBalance is just above the liquidationAmount then removing liquidationAmount leaves only 9 tokens, the subsequent check (collateralBalance >= fee) fails (9 < 10), so the fee transfer to the liquidator does not occur and the funds are stuck in the protocol, even though the fee was already deducted. This means:

  • The fee is reduced from the user's collateral but is never transferred to the liquidator.

  • Liquidator funds are stuck in the contract.

References

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

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

Proof of Concept

Proof of Concept

Paste this test in test/AlchemistV3.t.sol and run forge test --mt testLiquidate_no_fee -vvv

The test will pass showing that the liquidator will not receive any fee.

Was this helpful?