57678 sc high liquidation fee is deducted from user but not paid to liquidator

Submitted on Oct 28th 2025 at 05:18:12 UTC by @Anirruth for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #57678

  • 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 unclaimed yield

Description

Brief/Intro

When liquidating a position, the contract deducts the gross seizure (debt burn + base fee) from the user’s collateral. It then sends only the net amount (gross − fee) to the transmuter and attempts to pay the fee to the liquidator. If the account’s collateral is fully drained by the gross deduction (or the leftover is less than the fee), the fee transfer never occurs. The result is a fee that is charged to the user but not paid to the liquidator and not sent to the transmuter, effectively being withheld in the contract.

Vulnerability Details

In _doLiquidation, the contract:

  1. Deducts the full gross seizure from the account’s collateralBalance.

  2. Transfers only the net amount (gross − fee) to the transmuter.

  3. Pays the base fee to the liquidator only if the account’s remaining balance is still at least the fee.

  • amountLiquidated equals the gross seizure in yield units , so line 871 reduces the account by gross. https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistV3.sol?utm_source=immunefi#L871

  • The net (gross − fee) is sent to the transmuter (https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistV3.sol?utm_source=immunefi#L875).

  • If the gross deduction drains the account (or leaves a leftover smaller than the fee), the conditional on line 878 fails and the liquidator receives no fee, even though that fee has already been accounted for in the gross deduction from the user. https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistV3.sol?utm_source=immunefi#L878

Impact Details

Liquidators perform valid liquidations but do not receive the fee when the account is liquidated and the fee will stay in the contract.

References

https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistV3.sol?utm_source=immunefi#L871-L880

Proof of Concept

Proof of Concept

Paste the test in AlchemistV3.t.sol and run the test using forge test -vvvv --match-path src/test/AlchemistV3.t.sol --match-test testLiquidate_FeeNotPaid_When_GrossEqualsBalance

Was this helpful?