When both markets and settlement are disabled, the protocol aims to disallow new positions from being opened and also disallow already opened positions from increasing their size. However, this invariant is susceptible to being broken as users can still open new positions even when the the markets and settlements are disabled.
According to the protocol-
"both markets and settlement can be disabled, however when this happens we want to: 1) allow open positions not subject to liquidation to decrease their size or close 2) prevent new positions from being opened & existing positions being increased the idea is to prevent a state where traders have open positions but are unable to reduce size or close even though they can still be liquidated; such a state would severly disadvantage traders"
The above invariant can be bypassed in situations whereby a user opens a position that is currently decreasing thereby bypassing the explicit check meant to safeguard the invariant
The above implementation only checks if the current context i.e the current position to be created is increasing before validating if the market and settlements are being enabled. And as such, can be bypassed by creating a position with a negative sizeDelta
.
The logic that determines weather the position is increasing or not is as follows;
and the implementation is illustrated below:
From the above, it is made obvious the conditions required to be fulfilled in order to ascertain if a position is increasing or not. And this internal function only returns true
if the sizeDelta
is in the same direction as the current market position, otherwise, it is said to be decreasing.
Looking closely at the above implementation, we can clearly deduce how this bypass could be achieved.
In situations whereby the current market position is in a positive direction, and the sizeDelta
configured by a user is in the negative, the isIncreasing
will return false
, hence the checkMarketIsEnabled
and checkIsSettlementEnabled
check would be bypassed.
Walkthrough
Alice(a user) creates a market order with a negative int128 sizeDelta
.
The isIncreasing
returns false when the position size is positive.
checkMarketIsEnabled
and checkIsSettlementEnabled
would be bypassed
Alice successfully opens a position even when the market and settlement are disabled.
Moreover opening a position with a negative sizeDelta
does not mean the position will result in a loss, market directions are not always stable, hence such positions will start off as a loss but might still move in profit(positive direction) later on.
This breaks an invariant and will lead to users still being able to open positions when market and settlements are disabled which could lead to protocol insolvency
Manual review
Restructure the logic or make an implementation in the liquidation function to be called by the keepers, to check for opened positions in markets that have been disabled and close such positions or technically liquidate them.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.