Severity: High
Traders can create order with sizeDelta of -positon.size * 2 + x
. The order would flip the direction but will also have new position size greater than old size i.e trade has resulted in increase of the position size. The Position::isIncreasing
function incorrectly returns false
for such a sizeDelta
.
The Position::isIncreasing
is used to
disallow increasing orders in disabled markets and disabled settlement type.
determine the margin requirement: trader have to satisfy initial margin requirement if increasing otherwise only the maintenance margin.
Because of the incorrect implementation of the isIncreasing
function, traders can create increasing orders in disabled markets, with disabled settlement types. More importantly, traders can trade by only satisfying maintenance margin requirement.
Note the trader can keep their position direction on the market when increasing the position size:
Increasing the trade using this vulnerability would flip the trader's position for e.g from long to short.
Trader can create another order which will bring the position to original direction e.g back from short to long
The offline orders allow traders to perform this without any market risk in between the two orders.
Definition of the isIncreasing
function: Position.sol#L166-L172
The Position::isIncreasing
function determines whether sizeDelta
is increasing the position or not based on the direction instead of the sizes of old and new positions. As a result, the isIncreasing
function would return false
even for orders which increase the overall size of the position if sizeDelta
moves it in the opposite direction.
The SettlementBranch::_fillOrder
allows for sizeDelta
that flips the direction of position.
The _fillOrder
function uses the isIncreasing
function before filling the order:
Use of the isIncreasing
function to check for enabled markets in the _fillOrder
function: SettlementBranch.sol#L369-L380
The Zaros protocol intends to prevent existing positions from being increased when market and settlement is disabled. The isIncreasing
function is used to determine if existing position is being increased.
Similarly, the Zaros protocol allows for decreasing orders to only satisfy the maintenance margin. But the increasing orders must satisfy the initial margin requirement.
Use of isIncreasing
to determine the margin requirement to use: SettlementBranch.sol#L416-L430
Because of incorrect implementation of the isIncreasing
function
Traders can trade, both increase and decrease positions, in disabled markets and disabled settlement types
Traders can increase position size with only maintenance margin.
Example:
Initial Position Size = 100
BTC; Long on BTC
Trader wants to increase size to 120
BTC; Long on BTC
Trader have margin balance less than initial margin requirement
Protocol disallows increasing the size if margin balance is less than initial margin requirement. Creating an order with sizeDelta = +20
will fail.
Trader can use this issue and create two offline orders:
Order1 sizeDelta = -110
Order2 sizeDelta =+130
Position after Order1: size = -10
BTC; Short on BTC
Position after filling Order2: size = 120
BTC; Long on BTC
Multiple offline orders are filled in a single transaction. As a result, trader is not subjected to market risk in between Order1 and Order2.
Traders can trade, both increase and decrease positions, in disabled markets and disabled settlement types
Traders can increase position size with only maintenance margin.
Manual Review
Update the isIncreasing
function to account for the value of sizeDelta
along with direction
to determine if the order is increasing the position.
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.