DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: low
Invalid

Inconsistent Units in Share Allocation During Deposit _mint()

Summary

The _mint function, which is responsible for issuing vault shares upon deposit, incorrectly calculates the vault’s pre-deposit valuation (totalAmountBefore). In a 1x long position, the function subtracts the deposit amount (denoted in collateral token units) from the index token balance (expressed in index token units). This inconsistency in unit measurement results in an inaccurate share issuance, leading to the over-allocation of shares to new depositors and dilution of existing shares.

Vulnerability Details

  • Context of the Issue:
    Deposits are conducted using a collateral token (e.g., USDC), but in a 1x long position, the vault predominantly holds its value in index tokens (e.g., ETH) after executing a spot swap. The logic for open positions computes:

    totalAmountBefore = IERC20(indexToken).balanceOf(address(this)) - amount;

    Here, amount represents the deposit in collateral token units, while IERC20(indexToken).balanceOf(address(this)) represents the vault’s holdings in index token units. This equation assumes a direct 1:1 conversion rate between the two tokens, which is incorrect when market prices vary.

  • Unit Discrepancy & Valuation Miscalculation:
    Conversely, the _totalAmount(prices) function properly converts the index token balance into equivalent collateral token units using:

    IERC20(indexToken).balanceOf(address(this)) * prices.indexTokenPrice.min / prices.shortTokenPrice.min;

    By directly using the index token balance without appropriate conversion, the vault underestimates its total assets, resulting in an artificially reduced totalAmountBefore. This leads to an incorrect share issuance calculation:

    _shares = amount * totalShares / totalAmountBefore;

    Consequently, depositors receive more shares than they should, reducing the value of existing shares.

  • Example Simulation:
    Assumptions:

    • Pre-deposit vault state (1x long position):

      • Index token balance = 5000 (ETH units)

      • Collateral balance = 0 (converted fully into index tokens)

      • Total Shares = 1000

    • A new deposit of amount = 1000 collateral tokens (USDC).

    • Market Prices:

      • Index Token Price = $2

      • Collateral Token Price = $1

    Current Implementation:

    • The pre-deposit valuation is incorrectly computed as:

      totalAmountBefore = 5000 - 1000 = 4000
    • Shares allocated:

      shares = (1000 * 1000) / 4000 = 250 shares

    Correct Calculation (Using _totalAmount(prices)):

    • The vault’s actual total value should be computed as:

      Total Vault Value = (5000 * 2/1) + 0 = 10000
    • The proper pre-deposit valuation:

      totalAmountBefore = 10000 - 1000 = 9000
    • Correct share allocation:

      shares = (1000 * 1000) / 9000111 shares

    This discrepancy illustrates how the current implementation improperly grants over twice the correct number of shares, leading to unfair dilution of prior depositors.

Impact

  • Dilution of Share Value:
    Incorrect share issuance increases the total share supply disproportionate to the actual vault value, diminishing the value of existing shares.

  • Potential for Economic Exploitation:
    Malicious actors could strategically deposit at inflated share rates and withdraw disproportionately large amounts, extracting value from the vault unfairly.

  • Inaccurate Vault Valuation:
    The misalignment of units leads to an incorrect assessment of the vault’s holdings. Even minor pricing variations, such as an oracle deviation from 1 USD per USDC, can compound over time and create significant fairness issues.

Tools Used

  • Manual Code Review

Recommendations

  1. Compute totalAmountBefore using _totalAmount(prices), which ensures accurate unit conversion:

    totalAmountBefore = _totalAmount(prices) - amount;

    This correction guarantees that all values are represented in a uniform unit.

  2. Ensure the share allocation formula accounts for correct unit conversions. Introduce a parameterized precision multiplier instead of hardcoding 1e8, with well-documented safeguards against rounding errors.

Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

Suppositions

There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!