Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: high
Valid

Incorrect refunds in `PreMarkets::abortBidTaker(...)` due to miscalculation of `depositAmount`

Summary

In PreMarkets::abortBidTaker(...) function, there is a critical miscalculation of the taker's deposited collateral, causing incorrect collateral refunds either by paying less or more than deserved.

Vulnerability Details

Let's establish what depositAmount is first, in the context of abortBidTaker(...). It represents the amount of funds that were originally deposited by the taker when they placed their bid. This is calculated based on the taker's points and the offer's points and amount. Fundamentally, it should be calculated as:

taker amount = total amount * (taker points / total points) ✅.

However, the current implementation incorrectly flips the points ratio:

taker amount = total amount * (total points / taker points) ❌, which is translated from the following code snippet:

function abortBidTaker(address _stock, address _offer) external {
...
uint256 depositAmount = stockInfo.points.mulDiv(preOfferInfo.points, preOfferInfo.amount, Math.Rounding.Floor);
//@note The miscalculated depositAmount is used then to calculate the refund amount:
uint256 transferAmount = OfferLibraries.getDepositAmount(
preOfferInfo.offerType, preOfferInfo.collateralRate, depositAmount, false, Math.Rounding.Floor
);
...
}

The depositAmount is used to calculate the transferAmount, which is the amount of funds to be transferred back to the taker when they abort their bid.

Impact

Incorrect refunds for takers, the wrong points ratio(total points / taker points) is >1 which will inflate the amount of refund for early refundees, and cause loss of funds for late ones.

Tools Used

Manual review.

Recommendations

function abortBidTaker(address _stock, address _offer) external {
...
- uint256 depositAmount = stockInfo.points.mulDiv(preOfferInfo.points, preOfferInfo.amount, Math.Rounding.Floor);
+ uint256 depositAmount = stockInfo.points.mulDiv(preOfferInfo.amount, preOfferInfo.points, Math.Rounding.Floor);
uint256 transferAmount = OfferLibraries.getDepositAmount(
preOfferInfo.offerType, preOfferInfo.collateralRate, depositAmount, false, Math.Rounding.Floor
);
...
}
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-PreMarkets-abortBidTaker-amount-wrong-StockInfo-points

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.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!