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

Incorrect Collateral Price Selection Leading to False Liquidations

Summary

The MarketUtils library contains a critical issue in its collateral calculation logic, where it incorrectly uses shortTokenPrice for all collateral calculations, regardless of whether the position uses longToken or shortToken as collateral. This can lead to incorrect position valuations and trigger false liquidations.

Vulnerability Details

IDataStore dataStore,
MarketProps memory market,
MarketPrices memory prices,
bool isLong,
WillPositionCollateralBeSufficientValues memory values
) external view returns (bool, int256) {
PriceProps memory collateralTokenPrice = prices.shortTokenPrice; // <-- ISSUE
int256 remainingCollateralUsd = values.positionCollateralAmount.toInt256() *
collateralTokenPrice.min.toInt256();
//...
}

The root of the problem is that the willPositionCollateralBeSufficient function always uses shortTokenPrice for collateral calculation without considering that the collateral can be longToken or shortToken which can lead to incorrect collateral value calculation.

If a position uses longToken as collateral, the collateral value will be incorrect due to the incorrect price being used. This can cause the position to appear under-collateralized when it is not.

Impact

  • False liquidations of healthy positions

  • Incorrect margin calculations

Scenario

  1. User opens a long position using longToken (e.g., ETH) as collateral

  2. Market price of longToken increases significantly

  3. System calculates collateral value using shortTokenPrice (e.g., USDC)

  4. Position appears under-collateralized due to incorrect price usage

  5. Position gets wrongfully liquidated despite having sufficient collateral value

Example:

// Initial state
longTokenPrice = 2000 USD
shortTokenPrice = 1 USD
collateralAmount = 1 ETH
// Actual collateral value
actualValue = 1 ETH * 2000 USD = 2000 USD
// Incorrect calculation in contract
calculatedValue = 1 ETH * 1 USD = 1 USD // Uses shortTokenPrice
// Position appears under-collateralized

Tools Used

  • Manual review

Recommendations

Implement proper collateral price selection logic.

function willPositionCollateralBeSufficient(
IDataStore dataStore,
MarketProps memory market,
MarketPrices memory prices,
bool isLong,
WillPositionCollateralBeSufficientValues memory values
) external view returns (bool, int256) {
// Determine correct collateral token and price
PriceProps memory collateralTokenPrice;
if (values.collateralToken == market.longToken) {
collateralTokenPrice = prices.longTokenPrice;
} else if (values.collateralToken == market.shortToken) {
collateralTokenPrice = prices.shortTokenPrice;
} else {
revert InvalidCollateralToken();
}
// Validate price data
if (collateralTokenPrice.min == 0 || collateralTokenPrice.max == 0) {
revert InvalidPriceData();
}
int256 remainingCollateralUsd = values.positionCollateralAmount.toInt256() *
collateralTokenPrice.min.toInt256();
// Add additional safety checks
if (remainingCollateralUsd < 0) {
revert NegativeCollateralValue();
}
// Continue with existing logic...
}
Updates

Lead Judging Commences

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

Support

FAQs

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