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

Wrong accounting of `openInterest` and `skew`

Summary

The liquidateAccounts function updates openInterest and skew to 0 due to uninitialized values, leading to incorrect calculations.

Vulnerability Details

At the end of the liquidateAccounts function, perpMarket.updateOpenInterest is called to update the skew and the open interest of a given perpetual market:

LiquidationBranch.sol#L209

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

The issue is that both ctx.newOpenInterestX18 and ctx.newSkewX18 are never initialized at this point in the function. Therefore the skew and open interest will get updated to 0:

PerpMarket.sol#L354-L357

function updateOpenInterest(Data storage self, UD60x18 newOpenInterest, SD59x18 newSkew) internal {
self.skew = newSkew.intoInt256().toInt128();
self.openInterest = newOpenInterest.intoUint128();
}

Impact

This issue will lead to wrong fee and mark price calculation (because the skew is involved) and prevent checking the open interest and skew max limits during settlement.

Tool used

Manual Review.

Recommendations

You could either use checkOpenInterestLimits (try) to get these values or manually calculating them (catch). The problem with checkOpenInterestLimits is that it checks against open interest and skew limits which could prevent some liquidations so I would not recommend using it.

+ // enforce open interest and skew limits for target market and calculate
+ // new open interest and new skew
+ try {
+ (ctx.newOpenInterestX18, ctx.newSkewX18) =
+ perpMarket.checkOpenInterestLimits(ctx.liquidationSizeX18, ctx.oldPositionSizeX18, SD59x18_ZERO);
+ } catch {
+ // If open interest or skew checks fail, allow liquidation to proceed by setting new open interest and skew manually
+ ctx.newOpenInterestX18 = ud60x18(perpMarket.openInterest).sub(ctx.oldPositionSizeX18.abs().intoUD60x18());
+ ctx.newSkewX18 = sd59x18(perpMarket.skew).add(ctx.liquidationSizeX18);
+ }
// update perp market's open interest and skew; we don't enforce ipen
// interest and skew caps during liquidations as:
// 1) open interest and skew are both decreased by liquidations
// 2) we don't want liquidation to be DoS'd in case somehow those cap
// checks would fail
perpMarket.updateOpenInterest(ctx.newOpenInterestX18, ctx.newSkewX18);
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.