PRE CONTEXTE: This issue arises after addressing the missing update of the
Ongoing
status when someone take an offer
The current implementation of createTaker
does not update the offer status from Virgin
to Ongoing
(as explained in other report), after addressing that issue, several functions in the protocols will break and will not work as intended:
The PreMarkets::abortAskOffer
function allows ask-offer owners to abort their offers and reclaim their collateral, while simultaneously aborting all ongoing deals with existing takers. Aborting an ask offer should be allowed under the following conditions:
Virgin Status: The offer has no takers, allowing the owner to be refunded the full collateral
Canceled Status: The offer has takers but was subsequently canceled. The owner can still abort the used points.
Ongoing Status: The offer has active takers, and the owner aborts the offer. All existing takers are aborted, and the owner is refunded with his collateral(if there are no sub-trades in case of Turbo mode).
The issue is that the third scenario (Ongoing
status) is not included in the status check, preventing the abortion of ask offers with an Ongoing
status:
Bid offer makers deposit the amount of points they are willing to purchase in advance when creating an offer using the createOffer
function in PreMarket
. Sellers (bid takers) then call createTaker
to sell points to bid offer makers when the market is online.
During the settlement period, bid offer makers are expected to use the DeliveryPlace::closeBidOffer
function to withdraw the collateral for the unused points—those points that were not bought. However, the function currently only allows refunds for offers that remain in the Virgin
status:
As seen above, the check if (offerInfo.offerStatus != OfferStatus.Virgin) revert InvalidOfferStatus()
restricts refunds to offers that have not been traded (i.e., Virgin status). If an offer’s points were partially used—meaning a bid taker sold some, but not all, of the offer points—and the market enters the settlement period, bid makers will be unable to retrieve the deposit for the unused points, causing these funds to remain stuck in the contract.
Ask offer settlements should be initiated by the offer maker under one of the following conditions:
Virgin
Status: The offer has not been traded (no takers), allowing the offer maker to settle 0 points and receive their full collateral, as demonstrated by this code block in settleAskMaker
Closed
Status: The offer was canceled, but some points were used before cancellation, which still need to be settled.
Ongoing
Status: The offer has takers, and offer points need to settled.
The problem lies in the fact that the third scenario (Ongoing
status) is not included in the status check, preventing the settlement of ask offers with an Ongoing
status:
The PreMarkets::closeOffer
function allows offer owners to cancel their offers and receive a refund based on the unused points amount, calculated by getRefundAmount. Cancellation of an offer should be permissible in one of the following scenarios (as confirmed by the sponsor):
Virgin Status: The offer has no takers, and the owner is refunded the full collateral.
Ongoing Status: The offer has takers, and the owner is refunded with the unused points.
The problem is that the closeOffer
function currently restricts cancellations to offers with a Virgin
status only:
As shown above, the function enforces that the offer must have a Virgin
status (no takers) for it to be canceled, but it does not allow the cancellation of offers with an Ongoing
status, preventing the owner from canceling the offer and receiving a refund for the unused points.
Several functions will break if the missing Virgin status update in createTaker
is addressed
Manual Review
After addressing the missing update of offer status from Virgin
to Ongoing
in createTaker
, consider iterating over the mentioned functions above and include the status Ongoing
in the offer's status check
The reason for severity for this issue and duplicates are very similar to issue #1164. However, in this case, the issues correctly identified that offer statuses should be updated accordingly based on points transaction (partially filled orders = `Ongoing`, fully filled orders = `Filled`). There is currently no impact on the tadle system since the above two statuses are unused, and while sementically `Virgin` status is not the correct status representing whether taker orders can be created agains maker offers, it can still be performed without a DoS. However, if we are basing it off of the correct status implementation (i.e. `Ongoing` phase appropriately updated when takers create taker offers), then the DoS will occur, essentially blocking any taker offers from being created by subsequent takers for partially filled orders. All issues that does not mention the DoS impact will be low severity, since they still correctly highlighted the wrong status accounting. All issues that mention the possible bypass of `Virgin` status is incorrect, because the usedPoint checks will always ensure points are filled only up to the points posted for offer as seen [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L180-L186). Note for downgrade to low severity: Agree with appeals and low severity, this is more of a status accounting error and does not have any impact, since the statuses consistently do not utilize a switch from Vigin to Ongoing/Filled and the protocol can function appropriately even without the use of such statuses (presuming other bugs are fixed), the DoS impact will not occur.
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.