Zaros implements a 2 steps process to execute an order :
order creation by the users (off-chain or on-chain)
order fulfillment by the keepers
The keepers are implemented in a way they trigger the orders fulfillment at the most strategic moment possible.
The SettlementBranch::fillMarketOrder() function is able to execute 1 on-chain pending order at a time, which in case of revert would only affect this particular order.
Such order can revert in case it has been modified before it was executed to make sure the order executed is the intended one (this was subject to a valid issue in the previous Cyfrin audit).
Zaros has implemented off-chain orders which are fulfilled using the SettlementBranch::fillOffchainOrders() function.
The issue is that this function can not only revert for multiple reason BUT takes multiple orders at the same time.
This means if something goes wrong with one of the orders and should revert, all the orders won't be able to be filled.
Here is an extract of the code that causes the issue :
As you can see, the function loops through all the orders and performs various verifications that, if not met, revert.
A user can easily block all the orders included with his like such :
create an off-chain order (with nonce == 0) on a vivid market that has a lot of orders pending
cancel his order by calling the OrderBranch::cancelAllOffchainOrders() function which will increment his nonce in storage
his order is trying to be fulfilled among many others BUT since his tradingAccount.nonce is now equal to 1 because of previous step, the transaction will revert and no orders will be filled.
This can have a dramatic impact on traders who would want their orders to be executed as soon as possible to align with their market analysis.
Delaying the fulfillment could reduce the amount of profit they would have generated if their orders was filled correctly.
Manual review
The protocol partially implemented a way to mitigate the issue but did not implement it everywhere.
In case the order is invalid, rather than revert() the transaction should continue to loop over all the orders.
If you send 1 cancel and 1 create it should still run the cancel, not revert everything.
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.