Tadle

Tadle
DeFi
30,000 USDC
View results
Submission Details
Severity: high
Valid

An overinflated Maker refund in the `PreMarkets.abortAskOffer()` function when `collateralRatio > 100%` can lead to a loss of funds.

Summary

There is an invalid calculation of the totalDepositAmount in the PreMarkets.abortAskOffer() function that results in an overinflated Maker refund when the collateralRatio > 100%. As a result, the Maker receives a larger refund than expected, while the Taker receives the compensation as expected. This discrepancy leads to a loss of funds for the protocol and other users, as an attacker exploiting this issue can extract all the funds from the system.

Vulnerability Details

In the PreMarkets.abortAskOffer() function, the calculation for totalDepositAmount is as follows:

File: PreMarkets.sol
607: uint256 totalDepositAmount = OfferLibraries.getDepositAmount(
608: offerInfo.offerType,
609: offerInfo.collateralRate,
610: totalUsedAmount,
611: false, // <== should be true, as this is also a calculation for Maker
612: Math.Rounding.Ceil
613: );

The issue here is that totalDepositAmount should also be calculated from the Maker's perspective and account for the collateral ratio, similar to the calculations for transferAmount done earlier.

If totalDepositAmount is not counted as a Maker deposit, the following line will result in an excessively large refund for the Maker:

File: PreMarkets.sol
616: uint256 makerRefundAmount;
617: if (transferAmount > totalDepositAmount) {
618: makerRefundAmount = transferAmount - totalDepositAmount; // <== totalDepositAmount is calculated without collateral ratio
619: } else {
620: makerRefundAmount = 0;
621: }

An attacker can exploit this issue to extract all funds from the system. Here is how:

  1. The attacker, as a Maker, creates an Ask offer with a 100000% collateral ratio, with 50 points for 50 USDC, and deposits 50000 USDC as collateral.

  2. The attacker, as a Taker, takes this Ask offer and buys 25 points for 25 USDC.

  3. The Ask offer is aborted, and the Maker receives a 49975 USDC refund. The offer is marked as Settled.

  4. The attacker, as a Taker, calls DeliveryPlace.closeBidTaker() and receives 25000 USDC as compensation for not receiving the Points tokens.

As a result, the attacker can extract 24975 USDC from the protocol. This exploit can be achieved within a single transaction, and a flash loan can be used, meaning the attacker does not need to possess 50k USDC as collateral initially.

Impact

  • Loss of funds.

Tools Used

  • Manual review.

Recommendations

Use true for the _isMaker parameter in the OfferLibraries.getDepositAmount() function to ensure accurate calculations of totalDepositAmount.

Updates

Lead Judging Commences

0xnevi Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-PreMarkets-abortAskOffer-isMaker-false

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

Appeal created

0xnevi Lead Judge
10 months ago
0xnevi Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-PreMarkets-closeBidTaker-lack-check-abort-status-drain

Valid high, for unsettled ask offers by the original maker, the initial remaining maker collateral is already refunded as seen [here](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L624-L629)

Support

FAQs

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