Tadle

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

Incorrect collateralRate usage in listOffer() when we use protect mode

Summary

In protect mode, when users listOffer(), the transferred collateral amount is calculated based on variable offerInfo.collateralRate. But when we update this offer's collateral rate, we use variable _collateralRate. Users can get profit via the difference between offerInfo.collateralRate and _collateralRate.

Vulnerability Details

The trader can resell the points via listOffer(). In protected mode, the trader resell the points with chosen price and collateralRate. The chosen price and collateralRate may be different with the pre offer.
The problem is that we calculate the collateral amount based on preOffer's collateral rate, and update the newly offerInfoMap's information with users input _collateralRate. The trader may get profit via the difference between offerInfo.collateralRate and _collateralRate.

For example:

  • Alice creates one ask offer with collateral rate 120%.

  • Bob creates one bid taker to match Alice's offer.

  • Now Bob resell the points via listOffer() with collateral rate 200%. The actual collateral amount Bob adds into the capitalPool is amount * 120%. But the system will record the collateral wtih 200%.

  • If bob closes the offer directly, the refund collateral amount will be calculated with collateral rate 200%. And bob can get more collateral than expected.

function listOffer(
address _stock,
uint256 _amount,
uint256 _collateralRate
) external payable {
...
if (makerInfo.offerSettleType == OfferSettleType.Protected) {
// @audit confirmed here we should use _collateralRate to calculate the collateralRate.
uint256 transferAmount = OfferLibraries.getDepositAmount(
offerInfo.offerType,
@==> offerInfo.collateralRate,
_amount,
true,
Math.Rounding.Ceil
);
ITokenManager tokenManager = tadleFactory.getTokenManager();
tokenManager.tillIn{value: msg.value}(
_msgSender(),
makerInfo.tokenAddress,
transferAmount,
false
);
}
...
offerInfoMap[offerAddr] = OfferInfo({
id: stockInfo.id,
authority: _msgSender(),
maker: offerInfo.maker,
offerStatus: OfferStatus.Virgin,
offerType: offerInfo.offerType,
abortOfferStatus: AbortOfferStatus.Initialized,
points: stockInfo.points,
amount: _amount,
@==> collateralRate: _collateralRate,
usedPoints: 0,
tradeTax: 0,
settledPoints: 0,
settledPointTokenAmount: 0,
settledCollateralAmount: 0
});
}

Impact

Traders can steal the funds in the capital pool via listOffer()/closeOffer() in protect mode.

Tools Used

Manual

Recommendations

In listOffer, the calculation of collateral amount should be based on the newly collateral rate _collateralRate.

Updates

Lead Judging Commences

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

finding-PreMarkets-listOffer-collateralRate-manipulate

Valid high severity, because the collateral rate utilized when creating an offer is stale and retrieved from a previously set collateral rate, it allows possible manipilation of refund amounts using an inflated collateral rate to drain funds from the CapitalPool contract

Support

FAQs

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

Give us feedback!