The settleAskMaker
is a function present in DeliveryPlace
which is used to Ask
offers by Makers
. However, the current logic is susceptible to being broken and reverts on subsequent calls when called by a Maker
- a critical invariant.
Line Of Code
Tadle is a protocol that allows users to trade points(buy or sell) and can be done by Makers
who create offers that are then being matched by corresponding Takers
interested in the offer created by the Maker
.
After the Makers
and Takers
have been matched by the prospective offerId
, there comes a time for settlements which happens in the DeliveryPlace::settleAskMaker
.
The settleAskMaker
does some checks and ensure that status == MarketPlaceStatus.AskSettling
before proceeding to makes a call to perMarkets.settledAskOffer
which is a function only callable by onlyDeliveryPlace
.
The DeliveryPlace::settleAskMaker
updates the state of the offerInfo.offerStatus
to OfferStatus.Settled
even in situations where offers were meant to be partially settled.
The bug lies in the fact that when a Maker
settles some portions of the point, the system gets bricked and no longer able to settle the remaining points to a user due the status change not properly being handled.
code Snippet
The above implementation breaks a core invariant of the protocol and has immerse impacts on both the protocol and the users.
ILlustration
Bob - a Maker
, decides to offer some points(1000 points) for sale on a marketplace by depositing collateral.
Alice - a Taker
sees this offer and Decides to buy this points(1000 points)
After a while vm.warp(few days)
, Bob decides to settle this offer partially by passing some amount of the total points (_settledPoints) that was offered to Alice.
Bob then make a call to DeliveryPlace::settleAskMaker
with the generated offer address as _offer
and 500 as _settledPoints
The transaction goes through. However, bob stills owes Alice settlements worth 500 points which in this case becomes bricked and can no longer be settled.
After further evaluation, it can be proven that this is not a design choice, otherwise the protocol could have implemented a logic to allow Makers
only settle the total amount of points owed to a Taker
.
Changed the pseudo names(users) to real names for more code readability and clarity.
Could lead to loss of funds for the Takers
as they are not able to have their points settled and DOS attack to the protocol.
Restructure the logic either settle the entire points or add a check that only changes the status to OfferStatus.Settled
only of all points have been settled.
Valid high, in settleAskTaker/settleAskMaker, if the original offer maker performs a partial final settlement, the existing checks [here](https://github.com/Cyfrin/2024-08-tadle/blob/main/src/core/DeliveryPlace.sol#L356-L358) and [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/DeliveryPlace.sol#L230-L232) will cause an revert when attempting to complete a full settlement, resulting in their collateral being locked and requiring a rescue from the admin. To note, although examples in the documentation implies settlement in a single click, it is not stated that partial settlements are not allowed, so I believe it is a valid user flow.
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.