In case that an ask maker aborts her offer, it is expected that after taker aborts his order, the taker would receive the full collateral of the maker as punishment to the maker because of not keeping the promise. But, due to a mis-implementation, the taker only receives a portion of maker's collateral that does not include the collateral rate effect.
This breaks a main invariant of the protocol, because the collateral rate is a main mechanism to incentivise makers to keep their promises and ensuring takers that they will be compensated in case of maker's failure.
The flow of bug is:
Maker creates an ask offer createOffer
Taker places a bid order createTaker
Maker aborts her offer abortAskOffer
Taker aborts his order abortBidTaker
(bug happens here)
Please note that this bug may seem similar to another finding with title Aborted ask offer returns the extra collateral to the maker that leads to breaking a main invariant of the protocol
, but the root cause and impacts are different.
Suppose Alice(maker) creates an ask offer for 1000 points with $1 as collateral with collateral rate 12000 (equivalent to 120%). In total she deposits $1.2.
Bob places a bid order against Alice's offer to buy those 1000 points.
Then, Alice aborts her offer.
Now, Bob can also abort his order because Alice's offer is already aborted.
When Bob calls abortBidTaker
, it is expected that the Alice's collateral be dedicated to Bob (even those extra portion of collateral related to collateral rate, i.e. $0.2). Because, Alice is aborting her offer and she is not keeping her promise, so she should be punished. So, we expect that after Bob calls abortBidTaker
to have:
But due to the miscalcualtion we will have:
The miscalculation happens here where the transferAmount
is calculated. It calculates the transfer amount as $1, because the parameters of getDepositAmount
are forwarded as:
_offerType
: ask
_collateralRate
: 12000 (equivalent to 20%)
_amount
: $1
_isMaker
: false
_rounding
: Floor
https://github.com/Cyfrin/2024-08-tadle/blob/main/src/core/PreMarkets.sol#L677
https://github.com/Cyfrin/2024-08-tadle/blob/main/src/libraries/OfferLibraries.sol#L27
While the parameter _isMaker
should be set to true
.
In the following test Alice creates a turbo ask offer to sell 1000 points for $1 with collateral rate 12000 (equivalent to 120%), and Bob places a bid order to buy all those 1000 points.
Later, Alice aborts her offer by calling abortAskOffer
, and then Bob calls abortBidTaker
to abort his order. The output shows that only $1 is dedicated to Bob balance as MakerRefund, while it should be $1.2.
An important note is that in this test, the following code is fixed (which is reported in another finding with title Stealing the fund by misusing the vulnerability in the function abortBidTaker
), to be able to show the impact of this finding.
https://github.com/Cyfrin/2024-08-tadle/blob/main/src/core/PreMarkets.sol#L671
The output is:
Aborted bid-taker will not fully receive the collateral from the aborted ask-maker
Taker will not be compensated properly if the maker aborts
https://github.com/Cyfrin/2024-08-tadle/blob/main/src/core/PreMarkets.sol#L677
Valid high severity, the `totalDepositAmount` of collateral computed from the amount of point used (posted to transact) should use the same isMaker flag as when computing the original collateral deposited by maker, if not, the amount available for withdrawal during abortion will be overestimated
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.