57138 sc critical protocol subsidizes repayment fees during liquidation

Submitted on Oct 23rd 2025 at 19:32:38 UTC by @teoslaf1 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #57138

  • 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

    • Protocol insolvency

Description

Summary

When a position with earmarked debt is liquidated and the user's collateral is insufficient, the protocol subsidizes the repayment fee from its own balance (other users' collateral). The _resolveRepaymentFee function calculates the full fee amount but can only deduct what's available from the user's depleted collateral, yet returns the full fee amount which is then paid from the contract's balance.

Vulnerability Details

Root Cause

The vulnerability exists in the liquidation flow when handling earmarked debt:

  1. _forceRepay is called first (line 823):

    • Consumes the user's collateral to repay earmarked debt

    • Sends the repaid amount to the transmuter

    • User's collateralBalance is significantly reduced or depleted

  2. _resolveRepaymentFee is called after (line 828):

  3. Fee Transfer (line 830):

    This calls myt.transfer(msg.sender, feeInYield) which transfers tokens from the AlchemistV3 contract's balance to the liquidator.

The Problem

  • Line 907 deducts min(fee, collateralBalance) from the user's accounting(maybe 0 if depleted)

  • Line 909 returns the full calculated fee amount

  • Line 830 transfers this full fee from the contract's actual token balance to the liquidator

  • The accounting shows less was deducted from the user than what was actually paid out

  • The shortfall comes from the contract's balance, which contains other users' collateral

Token Flow Explanation

  • All user collateral is held in the AlchemistV3 contract's token balance

  • account.collateralBalance is just an accounting entry tracking each user's share

  • When TokenUtils.safeTransfer(myt, recipient, amount) is called, it transfers from the contract's actual balance

  • If the accounting deducts less than what's transferred, the difference is taken from other users' funds

Step-by-Step Example (matching test scenario)

Impact

Direct Theft of User Funds

The vulnerability causes immediate theft of funds from the protocol's balance (other users' collateral at-rest):

  • Liquidators receive fees that were never deducted from the liquidated user

  • The shortfall is paid from the contract's balance containing other users' deposits

  • This is not a rounding error or edge case - it's systematic theft on every undercollateralized liquidation

Financial Loss Per Liquidation

With a 1% repayment fee:

  • 100,000 alETH position → 900 alETH stolen ($2.25M at $2,500/ETH)

  • 1,000,000 alETH position → 9,000 alETH stolen ($22.5M at $2,500/ETH)

The vulnerability creates systemic risk that threatens protocol solvency:

  • During market crashes, many positions become undercollateralized simultaneously

  • Each liquidation drains protocol reserves by 1% of the repaid amount

  • Protocol continuously loses funds to liquidators without collecting from users

  • Accumulated losses can lead to protocol insolvency

  • Other users cannot withdraw their full collateral as reserves are depleted

Proof of Concept

Proof of Concept

Add this test to AlchemistV3.t.sol

Test Output

Was this helpful?