58320 sc critical incorrect fee return value in resolverepaymentfee enables fund theft under extreme conditions

Submitted on Nov 1st 2025 at 08:50:27 UTC by @Diavol0 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58320

  • 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

1. Executive Summary

Vulnerability Description

The _resolveRepaymentFee() function in AlchemistV3 contains a critical logic error where it returns the calculated repayment fee instead of the actual amount deducted from the user's collateral. When a liquidated position has insufficient collateral to pay the full repayment fee, this discrepancy allows the liquidator to receive tokens from other users' funds in the protocol.

Code Location: AlchemistV3.sol:900-907

Severity Rationale:

  • Code Logic Error Confirmed: The return value does not match the actual deduction

  • Impact When Triggered: Direct theft of user funds (100% fund loss for affected transaction)

  • No User Mitigation: Users cannot prevent this once conditions are met

  • Core Mechanism Affected: Liquidation is core protocol function

  • ⚠️ Trigger Difficulty: HIGH - Requires extreme market stress + high leverage + high earmark

  • ⚠️ Natural Occurrence: Unlikely under normal protocol operations

Classification: HIGH severity based on impact (direct theft of any user funds) per Immunefi standards, regardless of trigger difficulty.


2. Technical Analysis

2.1 Root Cause

The function calculates a repayment fee based on the repaid amount, but when the account's collateral balance is insufficient to pay this fee, only a partial amount is deducted. However, the function returns the full calculated fee, not the partial deduction.

Buggy Code (AlchemistV3.sol:900-907):

The Problem:

2.2 Call Chain Analysis

The bug manifests during liquidation when a position has earmarked debt:

Alternative path (Line 839) has the same bug.

2.3 Why This Bug is Difficult to Trigger Naturally

Let's analyze why the insufficient balance condition rarely occurs:

Setup Scenario:

  • User deposits: 200e18 collateral

  • User borrows: 180e18 debt (90% LTV)

  • Transmuter earmarks: 99% of debt = 178.2e18

Collateral Flow During Liquidation:

For bug to trigger, we need: remaining balance < repayment fee

This requires extreme combination:

  1. ✅ High initial leverage (90% LTV)

  2. ✅ Very high earmark percentage (>95%)

  3. Additional stress factors needed:

    • Rapid conversion rate deterioration (yield token crash)

    • Protocol fee spike

    • Multiple liquidation penalties accumulating

    • Market volatility reducing collateral value mid-transaction

Conclusion: The safety margin (11x) is intentionally built into the protocol design, making natural triggering require catastrophic market conditions.


3. Impact Assessment

3.1 When Bug Triggers

IF the bug condition is met (insufficient collateral for repayment fee):

Immediate Impact:

  • Liquidator receives full calculated fee (e.g., 1.782e18)

  • Victim's account only pays partial amount (e.g., 0.5e18)

  • Shortfall (e.g., 1.282e18) is taken from protocol's MYT balance

  • Other users' funds are directly stolen to pay the liquidator

Systemic Impact:

  • Protocol accounting becomes inconsistent

  • MYT token shortage develops over repeated occurrences

  • Potential bank run if multiple such liquidations occur

https://gist.github.com/6newbie/f012efd4b130d3d6de58b009fd048f77

Proof of Concept

4. Proof of Concept

4.1 Test Implementation

Test Approach: This test uses forced manipulation to clearly demonstrate the code logic error. While this specific test does not trigger the insufficient balance condition (due to the 15x safety margin in standard parameters), it proves the code path exists and demonstrates the objective logic error in the function.

Run Test:

Key Test Output:

4.2 Demonstration of Code Logic Error

To verify the code bug exists, examine the logic:

Correct Implementation Should Be:

Was this helpful?