58369 sc high missing mytsharesdeposited decrements in forcerepay doliquidation leads to smart contract unable to operate due to lack of token funds

Submitted on Nov 1st 2025 at 17:27:23 UTC by @gor97 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58369

  • Report Type: Smart Contract

  • Report severity: High

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

  • Impacts:

    • Smart contract unable to operate due to lack of token funds

Description

Brief/Intro

The AlchemistV3 protocol contains a critical accounting vulnerability where the internal _mytSharesDeposited variable fails to be decremented when MYT tokens are transferred out during forced repayments (_forceRepay()) and liquidations (_doLiquidation()). This accounting mismatch causes the _getTotalUnderlyingValue() function to return progressively overstated Total Value Locked (TVL) calculations, which compound with each liquidation event. As the discrepancy between reported and actual token balances grows, the smart contract becomes unable to operate properly due to insufficient token funds relative to what the protocol believes it holds, ultimately leading to operational failure and potential system-wide dysfunction.

Vulnerability Details

The vulnerability stems from incomplete accounting maintenance in two critical functions within the AlchemistV3 contract. The contract uses an internal variable _mytSharesDeposited (line 134) to track the total MYT shares deposited:

uint256 private _mytSharesDeposited;

This variable is used by the _getTotalUnderlyingValue() function (line 1238-1241) to calculate the protocol's TVL:

function _getTotalUnderlyingValue() internal view returns (uint256 totalUnderlyingValue) {
    uint256 yieldTokenTVLInUnderlying = convertYieldTokensToUnderlying(_mytSharesDeposited);
    totalUnderlyingValue = yieldTokenTVLInUnderlying;
}

The contract correctly maintains this accounting variable in most operations:

  • Incremented during deposit() at line 383: _mytSharesDeposited += amount;

  • Decremented during withdraw() at line 410: _mytSharesDeposited -= amount;

  • Decremented for protocol fees in multiple locations

However, two critical functions transfer MYT tokens out without updating the accounting:

Location 1: _forceRepay() Function (Line 779)

Location 2: _doLiquidation() Function (Lines 875, 879)

Technical Impact Chain

  1. Accounting Discrepancy: Each liquidation/forced repayment creates a growing gap between _mytSharesDeposited and actual MYT token balance

  2. TVL Overstatement: _getTotalUnderlyingValue() returns inflated values based on the incorrect _mytSharesDeposited

  3. Dependent Function Failures: Functions like totalValue() (line 1073) and collateralization calculations rely on accurate TVL data

  4. Operational Breakdown: As the discrepancy grows, operations requiring actual token transfers fail when the contract believes it has more tokens than it actually possesses

Vulnerability Reproduction Path

  1. User deposits 50,000 MYT shares → _mytSharesDeposited = 50,000

  2. User borrows against collateral and creates transmuter redemption

  3. Liquidation occurs → _forceRepay() transfers 50 MYT shares to Transmuter

  4. Actual MYT balance: 49,950 shares (correctly decreased)

  5. _mytSharesDeposited: 50,000 shares (incorrectly unchanged)

  6. TVL calculation overstated by 50 shares

  7. Process repeats with each liquidation, compounding the discrepancy

Impact Details

The vulnerability manifests as progressive operational degradation with compounding effects:

Primary Impact: Smart Contract Operational Failure

  • Token Fund Shortage: The contract believes it holds more MYT tokens than it actually possesses

  • Operation Failures: Functions requiring token transfers fail when attempting to move non-existent tokens

  • Progressive Deterioration: Each liquidation/forced repayment event worsens the discrepancy

Financial Quantification

  • Per-Event Impact: Each liquidation creates a permanent accounting gap equivalent to the liquidated amount

  • Cumulative Effect: The discrepancy compounds with protocol usage - active protocols with frequent liquidations will accumulate larger discrepancies faster

  • System-Wide Risk: Affects all users as the core TVL calculation becomes increasingly unreliable

Operational Consequences

  1. Withdrawal Failures: Users may be unable to withdraw funds when the contract's perceived balance exceeds actual balance

  2. Liquidation System Breakdown: Incorrect TVL calculations affect liquidation triggers and calculations

  3. Risk Management Failure: Collateralization ratios become unreliable, preventing proper risk assessment

  4. Protocol Dysfunction: Core protocol operations that depend on accurate token accounting begin to fail

Severity Factors

  • Likelihood: HIGH - Occurs during normal protocol operations (liquidations and forced repayments)

  • Impact Scope: ALL protocol users affected as TVL is a global calculation

  • Persistence: Bug effects are permanent and accumulate over time

  • Recovery Difficulty: Requires protocol-level intervention to correct accumulated discrepancies

Code Locations

  • Primary Contract: /src/AlchemistV3.sol

  • Vulnerable Functions:

    • _forceRepay() - Line 779

    • _doLiquidation() - Lines 875, 879

  • Affected Calculations:

    • _getTotalUnderlyingValue() - Line 1238-1241

    • totalValue() - Line 1073 (depends on accurate TVL)

  1. For _forceRepay(): Add _mytSharesDeposited -= creditToYield; after the token transfer

  2. For _doLiquidation(): Add _mytSharesDeposited -= amountLiquidated; after both token transfers

  3. Additional Safeguards: Implement assertion checks to verify _mytSharesDeposited == IERC20(myt).balanceOf(address(this)) in critical functions

Proof of Concept

Proof of Concept

Was this helpful?