Part 2

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

Market::getAutoDeleverageFactor does not calculate deleverage correctly

Summary

The Market::getAutoDeleverageFactor function calculates the auto-deleveraging factor for a market based on its debt ratio. The function uses a polynomial regression curve to determine the factor, which is then applied to adjust profits during auto-deleveraging events. However, the implementation has two key issues:

  1. When the marketDebtRatio equals the autoDeleverageStartThreshold, the function returns zero, which may lead to unintended behavior.

  2. As the marketDebtRatio increases from the autoDeleverageStartThreshold toward the autoDeleverageEndThreshold, the output of the function increases. This results in users receiving less output when the debt ratio is close to the start threshold and more output as the debt ratio grows, which contradicts the intended behavior of progressively reducing payouts.


Vulnerability Details

Issue 1: Zero Output at autoDeleverageStartThreshold

  • Description: When the marketDebtRatio equals the autoDeleverageStartThreshold, the numerator in the calculation becomes zero (marketDebtRatio - autoDeleverageStartThreshold = 0). Consequently, the function returns zero, which means Zero is applied to profits during auto-deleveraging. This could result engines receiving no usd token when withdrawUsdTokenFromMarket is called

  • Code Reference:

    UD60x18 unscaledDeleverageFactor = Math.min(marketDebtRatio, autoDeleverageEndThresholdX18).sub(
    autoDeleverageStartThresholdX18
    ).div(autoDeleverageEndThresholdX18.sub(autoDeleverageStartThresholdX18));

Issue 2: Increasing Output with Rising Debt Ratio

  • Description: The function's design causes the auto-deleveraging factor to increase as the marketDebtRatio moves closer to the autoDeleverageEndThreshold. This behavior is counterintuitive because higher debt ratios should result in stricter reductions in payouts, not larger ones. The issue arises from the polynomial regression formula used (y = x^z), where x increases as the debt ratio grows until autoDeleverageEndThreshold, causing y to increase


The getAutoDeleverageFactor function is invoked when the market's auto-deleveraging system is triggered:

if (market.isAutoDeleverageTriggered(delegatedCreditUsdX18, marketTotalDebtUsdX18)) {
adjustedProfitUsdX18 =
market.getAutoDeleverageFactor(delegatedCreditUsdX18, marketTotalDebtUsdX18).mul(adjustedProfitUsdX18);
}

This means the calculated factor directly impacts the engines during auto-deleveraging events.

In the line where the deleverage factor is applied to the adjusted profit:

adjustedProfitUsdX18 = market.getAutoDeleverageFactor(delegatedCreditUsdX18, marketTotalDebtUsdX18).mul(adjustedProfitUsdX18);

As marketDebtRatio increases from autoDeleverageStartThreshold to autoDeleverageEndThreshold, the factor increases, causing adjustedProfitUsdX18 increase


Impact

The unintended behavior of the auto-deleveraging mechanism could destabilize the market by failing to provide usd tokens appropriately when the market needs them. Engines will not get correct usd token when it calls withdrawUsdTokenFromMarket


Tools Used

  • Manual Code Review


Recommendations

  1. Modify the function to ensure that it returns a non-zero value when the marketDebtRatio equals the autoDeleverageStartThreshold

  2. Adjust the behavior of the getAutoDeleverageFactor function so that the output does not increase in a linear fashion when marketDebtRatio is between the autoDeleverageStartThreshold and autoDeleverageEndThreshold

Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[INVALID] The equality case in `CreditDelegationBranch::isAutoDeleverageTriggered` (market ratio is == the start threshold) causes a small dos.

Support

FAQs

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

Give us feedback!