Tadle

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

Bidtaker Can't Withdraw All Their funds When Maker Aborts ask Offer

Summary

When a user creates an ask offer, he can call preMarktes::abortAskOffer to cancel it and retrieve his full collateral. Similarly, a bid taker should be able to call preMarktes::abortBidTaker to withdraw all of their collateral. However, due to a miscalculation of the depositAmount in the preMarktes::abortBidTaker function, users (bidTakers) are unable to withdraw the full amount of their funds.

Vulnerability Details

The miscalculation occurs in the following code, which determines the depositAmount for the bid taker:

https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L671

uint256 depositAmount = stockInfo.points.mulDiv(
preOfferInfo.points,
preOfferInfo.amount,
Math.Rounding.Floor
);

This calculation compute:

depositAmount = (stockInfo.points * preOfferInfo.points) / preOfferInfo.amount

But should be :

depositAmount = (stockInfo.points * preOfferInfo.amount) / preOfferInfo.points

This incorrect formula results in a significantly lower depositAmount, preventing the bid taker from withdrawing the full collateral they originally deposited.

Poof of Concept

  1. Alice creates an ask offer:

  • collateral = 10 000 usdc

  • points = 1 000

  1. Bob buys 100 points from Alice:

  • collateral = 1 000 usdc

  • points = 100

  1. Alice calls abortAskOffer to retrieve her collateral.

  2. bob then call abortBidTaker :

  • the code process

uint256 depositAmount = stockInfo.points.mulDiv(
preOfferInfo.points,
preOfferInfo.amount,
Math.Rounding.Floor
);
  • Calculation:

    depositAmount = ( 100 × 1000) / 10000 = 10

Bob is only able to claim 10 USDC, despite having originally deposited 1,000 USDC.

impact

  • Bid takers like Bob may be unable to recover the full amount of their deposited collateral due to the miscalculation. This results in a direct financial loss for users, which can erode trust in the platform.

  • The inability to withdraw full collateral can significantly damage the platform’s reputation. Users who experience losses may spread negative feedback, reducing the platform's credibility and deterring potential users.

Tools Used

manual review, foundry

Recommendations

To ensure that "bid takers" can withdraw the full amount of their deposited collateral, the depositAmount calculation in the abortBidTaker function should be corrected. Specifically, the following formula should be used:

uint256 depositAmount = stockInfo.points.mulDiv(
preOfferInfo.amount,
preOfferInfo.points,
Math.Rounding.Floor
);
Updates

Lead Judging Commences

0xnevi Lead Judge about 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.