Due to the incorrect calculation of depositAmount
in the abortBidTaker
function of PreMarkets
, the MakerRefund
is calculated incorrectly. Depending on the parameters of stock
, this could result in a critical amount of losses for the protocol or the maker entity.
In abortBidTaker
function of PreMarkets
, depositAmount
(that being the amount of tokens the stock authority deposited) is calculated as follows:
Let's express this as a standard formula:
It can be seen that the calculation above is incorrect. In reality, the stock was buying stockInfo.points
points, where the price for preOfferInfo.points
points was preOfferInfo.amount
tokens.
This means that the price per point was equal to , and the stock should have deposited . This can be verified in the createTaker
function of PreMarkets
, which calculates depositAmount
in lines 212-216.
So, we can now see that depositAmount
is calculated incorrectly in abortBidTaker
. The abortBidTaker
function will then calculate transferAmount
, which depends on depositAmount
, add a token balance equal to transferAmount
to the stock owner, and mark the stock as finished. Depending on the parameters of stock
and offer
, there could be significant losses either for the protocol (if the MakerRefund
is larger than it should be) or for the stock owner (if the MakerRefund
is smaller than it should be).
Depending on stockInfo.points, preOfferInfo.points, preOfferInfo.amount
, it varies who will bear losses.
Let's consider hypothetical cases where both protocol and stock owner losses occur (the specific numbers are chosen for simplicity). This will serve as a PoC.
Stock owner bears losses:
preOfferInfo.points = 10,preOfferInfo.amount = 20,stockInfo.points = 5
.
The real depositAmount
would be equal to .
The depositAmount
calculated in abortBidTaker
would be equal to .
As we can see, the depositAmount
calculated in abortBidTaker
is way smaller than it should be, so the stock owner bears losses.
Protocol bears losses:
preOfferInfo.points = 100,preOfferInfo.amount = 10,stockInfo.points = 80
.
The real depositAmount
would be equal to .
The depositAmount
calculated in abortBidTaker
would be equal to .
As we can see, the depositAmount
calculated in abortBidTaker
is way bigger than it should be, so the protocol bears losses.
Manual Review
Fix calculation of depositAmount
in abortBidTaker
function.
Valid high severity, due to incorrect computation of `depositAmount` within `abortBidTaker`, when aborting bid offers created by takers, the collateral refund will be completely wrong for the taker, and depending on the difference between the value of `points` and `amount`, it can possibly even round down to zero, causing definite loss of funds. If not, if points were worth less than the collateral, this could instead be used to drain the CapitalPool contract instead.
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.