Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: high
Invalid

Auto-Deleverage Factor Calculation May Revert on Negative Debt

Summary

The getAutoDeleverageFactor function in src/market-making/leaves/Market.sol assumes the market is in net debt without enforcing this check. When called with negative debt values, the function will revert due to invalid conversion from signed to unsigned decimals, potentially disrupting critical protocol operations.

Vulnerability Details

function getAutoDeleverageFactor(
Data storage self,
UD60x18 delegatedCreditUsdX18,
SD59x18 totalDebtUsdX18
) internal view returns (UD60x18 autoDeleverageFactorX18) {
SD59x18 sdDelegatedCreditUsdX18 = delegatedCreditUsdX18.intoSD59x18();
if (sdDelegatedCreditUsdX18.lte(totalDebtUsdX18) || sdDelegatedCreditUsdX18.isZero()) {
return UD60x18_UNIT;
}

// This will revert if totalDebtUsdX18 is negative
UD60x18 marketDebtRatio = totalDebtUsdX18.div(sdDelegatedCreditUsdX18).intoUD60x18();
// ...rest of calculation

}

The issue occurs in the conversion from SD59x18 to UD60x18 when calculating marketDebtRatio. If totalDebtUsdX18 is negative:

  1. The division totalDebtUsdX18.div(sdDelegatedCreditUsdX18) produces a negative result

  2. Attempting to convert this negative value to UD60x18 with intoUD60x18() will revert

  3. No validation prevents calling the function with negative debt values

Impact

Critical protocol functions depending on auto-deleverage calculations may be blocked

  • Risk management mechanisms could fail when market conditions require auto-deleveraging

  • System-wide impact as this affects core market functionality

  • Market operations could be disrupted during periods of market recovery (transition from negative to positive debt)

Tools Used

Manual code review

  • Understanding of PRBMath library behavior with signed/unsigned conversions

Recommendations

Add explicit check for negative debt values:

function getAutoDeleverageFactor(
Data storage self,
UD60x18 delegatedCreditUsdX18,
SD59x18 totalDebtUsdX18
) internal view returns (UD60x18 autoDeleverageFactorX18) {
if (totalDebtUsdX18.isNegative()) {
return UD60x18_ZERO; // Or other appropriate handling
}

// Rest of the function
...

}

Add documentation specifying valid input ranges:

/// @notice Calculates the auto-deleverage factor for a market
/// @dev MUST only be called when market is in net debt (totalDebtUsdX18 > 0)
/// @param totalDebtUsdX18 Must be positive, represents market's total debt

Consider adding a modifier to relevant functions:

modifier onlyPositiveDebt(SD59x18 debt) {
require(!debt.isNegative(), "Negative debt not allowed");
_;
}

Updates

Lead Judging Commences

inallhonesty Lead Judge
6 months ago
inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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