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

Initial Share Minting Vulnerability in PerpetualVault.sol

Summary

The first deposit into the vault mints shares using a fixed scaling factor (1e8) without accounting for the collateral token’s decimals. This allows attackers to mint inflated shares for tokens with low decimals (e.g., USDC), diluting future depositors and enabling share manipulation.


Vulnerability Details

Code Snippet

if (totalShares == 0) {
_shares = depositInfo[counter].amount * 1e8; // Ignores token decimals
}

Root Cause

  • The initial share calculation uses amount * 1e8, where amount is in the token’s native units (e.g., 1 USDC = 1e6 units).

  • This hardcoded scaling factor (1e8) does not adjust for the token’s decimals, leading to inconsistent share minting.

Technical Analysis

  • Low-Decimals Tokens (e.g., USDC with 6 decimals):

    • A deposit of 1 USDC (1e6 units) mints 1e6 * 1e8 = 1e14 shares.

    • Subsequent deposits use the formula shares = (amount * totalShares) / totalAmount.

    • A second deposit of 1 USDC (1e6 units) would receive (1e6 * 1e14) / 1e6 = 1e14 shares.

    • Result: The first depositor owns 50% of shares despite contributing 50% of collateral.

  • High-Decimals Tokens (e.g., WBTC with 8 decimals):

    • A deposit of 1 WBTC (1e8 units) mints 1e8 * 1e8 = 1e16 shares.

    • A second deposit of 1 WBTC receives (1e8 * 1e16) / 1e8 = 1e16 shares.

    • Result: Fair distribution, but the arbitrary scaling introduces unnecessary imprecision.


Impact

  • Share Inflation: Low-decimals tokens allow attackers to mint disproportionately high shares, stealing value from later depositors.

  • Protocol Instability: Mismanaged share ratios undermine trust and could lead to liquidity crises.


Proof of Concept (PoC)

True Exploit Scenario:
The vulnerability does not directly enable share theft but introduces precision risks:

  • Tokens with <8 decimals (e.g., 6 decimals) will mint shares with 2 extra decimal places, causing rounding errors.

  • Tokens with >8 decimals (e.g., 18 decimals) will mint fewer shares than intended, diluting early depositors.


Recommended Mitigation

Normalize Shares to 18 Decimals

Adjust the initial share calculation based on the token’s decimals:

uint256 decimals = IERC20Metadata(collateralToken).decimals();
_shares = amount * 10 ** (18 - decimals);

Example

  • For USDC (6 decimals):

    • 1 USDC = 1e6 units → 1e6 * 1e12 = 1e18 shares.

  • For WBTC (8 decimals):

    • 1 WBTC = 1e8 units → 1e8 * 1e10 = 1e18 shares.

This ensures 1 share = 1e18 units of collateral, standardizing the minting process.

Updates

Lead Judging Commences

n0kto Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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