Summary
After liquidation skew and open Interest are set to zero.
Vulnerability Details
During the unfortunate event of a liquidation, in each market assets of the liquidatee are emptied. However instead of updating the the skew and open interest, both are set to 0.
perpMarket.updateOpenInterest(ctx.newOpenInterestX18, ctx.newSkewX18);
This happens because ctx.newOpenInterestX18 and ctx.newSkewX18 default to zero.
Impact
The balance of the skew is lost after liquidation, now skew which is an important parameter in the order pricing loses its relevance
Tools Used
Manual review
Recommendations
Consider adding this function in order to calculate both skew and openInterest after liquidations:
function openInterestAndSkewAfterLiquidation(
Data storage self,
SD59x18 sizeDelta,
SD59x18 oldPositionSize,
SD59x18 newPositionSize
)
internal
view
returns (UD60x18 newOpenInterest, SD59x18 newSkew)
{
UD60x18 maxOpenInterest = ud60x18(self.configuration.maxOpenInterest);
UD60x18 currentOpenInterest = ud60x18(self.openInterest);
newOpenInterest =
currentOpenInterest.sub(oldPositionSize.abs().intoUD60x18()).add(newPositionSize.abs().intoUD60x18());
SD59x18 maxSkew = ud60x18(self.configuration.maxSkew).intoSD59x18();
SD59x18 currentSkew = sd59x18(self.skew);
newSkew = currentSkew.add(sizeDelta);
}
And add it to the loop:
function liquidateAccounts(uint128[] calldata accountsIds) external {
. . .
tradingAccount.updateActiveMarkets(ctx.marketId, ctx.oldPositionSizeX18, SD59x18_ZERO);
+ (ctx.newOpenInterestX18, ctx.newSkewX18) = checkOpenInterestLimitsAfterLiquidation(ctx.liquidationSizeX18, ctx.oldPositionSizeX18, SD59x18_ZERO)
perpMarket.updateOpenInterest(ctx.newOpenInterestX18, ctx.newSkewX18);
}