DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: high
Valid

Market openInterest and skew are updated to 0 every time a liquidation takes place

Summary

The market openInterest and skew are set to zero any time a user is liquidated. This will lead to the market's accounting being wrong, resulting in multiple issues.

1) openInterest and skew can far exceed the MAX_OPEN_INTEREST and MAX_SKEW. This will lead to market makers potentialy having a high exposition to one side of the market.

2) Skew is used to calculate the funding velocity and funding rate. Skew being set to zero will result in the market having the lowest possible funding rate, so traders will not be deducted the funding fees that they should be.

Vulnerability Details

In LiquidationBranch::liquidateAccounts, a new LiquidationContext struct is created to update the perp market's funding, open interest and skew, and the trading account's position. At the end, the following function is called:

perpMarket.updateOpenInterest(ctx.newOpenInterestX18, ctx.newSkewX18);

However, the ctx.newOpenInterestX18 and ctx.newSkewX18 are not assigned any value during the liquidation, so they will have the default value of 0. This means that the perpMarket's open interest and skew will be 0 after the liquidation.

Impact

Setting the open interest and skew to 0 on every liquidation makes the accounting of the protocol false and will jeopardize the LPs. As the protocol will lose track of the open interest and skew, users will effectively be able to open positions far beyond the MAX_SKEW and MAX OPEN_INTEREST. According to the sponsors (shared in a private thread) these maximum parameters exist in order to protect LPs, who are on the market maker side, from having too high an exposure to one side of the market. While the market making engine is beyond the scope of this audit, it is reasonable to assume that this is contradictory to the protocol's design, puts LPs at risk and can be exploited by malicious users.

In addition, the skew is also used to calculate the funding velocity and funding rate. When it is set to zero, the funding rate will be equal to the minimum of SD_UNIT, leading to funding fees not being properly collected.

Tools Used

Manual review

Recommendations

This issue arises from a mitigation of another issue identified by the Cyfrin private audit. The line

(ctx.newOpenInterestX18, ctx.newSkewX18) =
perpMarket.checkOpenInterestLimits(ctx.liquidationSizeX18, ctx.oldPositionSizeX18, sd59x18(0));

has been removed because liquidations should be possible even if the open interest and skew are beyond the maximum (as they will be decreased by liquidations). However, this call also sets the values for the newOpenInterest and newSkewX18.

The logic for setting these should be implemented separately from the checkOpenInterestLimitsfunction and should still be done at the end of liquidateAccounts().

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

`liquidateAccounts` calls `updateOpenInterest` with uninitialized OI and skew)

Support

FAQs

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