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

Critical Precision Bug: Collateral Overestimated Due to Missing 10³⁰ Scaling

The core issue in this snippet is that it miscalculates the USD value of a token amount by multiplying the token amount by its price without adjusting for the 10³⁰ “price precision” factor.

In GMX-style contracts, prices are stored in fixed-point 10³⁰ format (e.g., a price of $1 is actually stored as 1 * 10^30). When converting a token amount to its USD value, the correct approach is:

USD Value=Token Amount×Price (10³⁰)1030\text{USD Value} = \frac{\text{Token Amount} \times \text{Price (10³⁰)}}{10^{30}}

However, in the function willPositionCollateralBeSufficient, the calculation omits this division, leading to an overestimated collateral value in USD.


Bug Location willPositionCollateralBeSufficient

function willPositionCollateralBeSufficient(
IDataStore dataStore,
MarketProps memory market,
MarketPrices memory prices,
bool isLong,
WillPositionCollateralBeSufficientValues memory values
) external view returns (bool, int256) {
PriceProps memory collateralTokenPrice = prices.shortTokenPrice;
// ❌ BUG: Overestimates remainingCollateralUsd by not dividing by FLOAT_PRECISION
int256 remainingCollateralUsd =
values.positionCollateralAmount.toInt256() * collateralTokenPrice.min.toInt256();
if (values.realizedPnlUsd < 0) {
remainingCollateralUsd = remainingCollateralUsd + values.realizedPnlUsd;
}
...
}

  • collateralTokenPrice.min is stored in 10³⁰ format.

  • values.positionCollateralAmount is a raw token amount (without 10³⁰ scaling).

  • Multiplying them directly over-scales the result by 10³⁰, instead of returning the correct USD value.

The correct approach is to divide by 10³⁰ after multiplication to maintain the proper USD scale:

remainingCollateralUsd =
Math.mulDiv(values.positionCollateralAmount.toInt256(), collateralTokenPrice.min.toInt256(), FLOAT_PRECISION.toInt256());

where:

FLOAT_PRECISION = 10**30;

Severely Overestimates Collateral

- The system **thinks** there is **10³⁰ times more collateral than actually exists**, making collateral checks meaningless.

Allows Undercollateralized Positions

- Malicious users can **open or maintain** positions that should be **disallowed due to insufficient collateral**.
- This **exposes the system to financial loss**, as liquidations may fail to recover enough funds.

Potential Exploit Scenario

- A trader with minimal funds can **pass collateral checks** for large positions.
- This could lead to **vault insolvency** if many undercollateralized positions exist.

To correctly compute remainingCollateralUsd, apply division by 10³⁰ to bring the result back to USD precision:

int256 remainingCollateralUsd = Math.mulDiv(
values.positionCollateralAmount.toInt256(),
collateralTokenPrice.min.toInt256(),
FLOAT_PRECISION.toInt256()
);

This critical vulnerability causes the system to massively overestimate collateral due to a missing precision adjustment, allowing undercollateralized positions to pass validation. Properly scaling the calculation by dividing by 10³⁰ ensures accurate collateral tracking and prevents potential exploits that could drain the system’s liquidity.

Updates

Lead Judging Commences

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

Support

FAQs

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

Give us feedback!