For the complete documentation index, see llms.txt. This page is also available as Markdown.

56622 sc critical repayment fee overpays liquidators using pooled collateral after forcerepay

Submitted on Oct 18th 2025 at 14:32:26 UTC by @vivekd for Audit Comp | Alchemix V3

  • Report ID: #56622

  • Report Type: Smart Contract

  • Report severity: Critical

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

  • Impacts:

    • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield

Description

Brief/Intro

During liquidation, _resolveRepaymentFee returns a fee based on the earmarked debt repaid. If the borrower has no collateral left—common after _forceRepay—the function still returns the full fee even though nothing was deducted from the borrower. _doLiquidation then pays that fee out of the Alchemist's global MYT balance, siphoning other users' collateral to the liquidator.

Vulnerability Details

  1. _forceRepay uses the account's collateral to repay earmarked debt and can zero out account.collateralBalance.

  2. _resolveRepaymentFee computes fee = repaidAmountInYield * repaymentFee / BPS and only reduces the borrower's balance by min(fee, account.collateralBalance). When the balance is zero, it subtracts nothing but still returns the full fee.

  3. _liquidate calls _resolveRepaymentFee, receives the inflated feeInYield, and transfers that amount to the liquidator: TokenUtils.safeTransfer(myt, msg.sender, feeInYield). Since the borrower contributed nothing, the transfer comes directly from the Alchemist's pooled MYT (i.e., other users' collateral).

  4. The PoC (testPoC_repayment_fee_drains_global_collateral in src/test/AlchemistV3.t.sol) shows a liquidation where the liquidator collects a fee from pooled funds rather than the borrower's own shares.

Impact Details

  • A malicious liquidator can repeatedly target accounts whose collateral was consumed by _forceRepay. Each liquidation yields a positive fee paid from pooled funds, enabling unlimited extraction.

  • Every exploit reduces the Alchemist's collateralization, threatening solvency and allowing the attacker to drain the MYT pool even though borrowers cannot repay.

  • All Alchemist depositors are affected: their backing collateral is transferred to the attacker through liquidation fees they should never have owed.

Proof of Concept

Proof of Concept

code:

  1. Apply the repository test testPoC_repayment_fee_drains_global_collateral added in src/test/AlchemistV3.t.sol.

  2. This setup increases the repayment fee (50%), earmarks all of an attacker's debt, zeroes their collateral via _forceRepay, and triggers liquidation.

  3. Run:

  1. Logs:

Demonstrating the fee is paid from pooled collateral, not the borrower.

Was this helpful?