Tadle

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

Offers can be aborted by maker even if they are listed.

Summary

In theory, offers should not be able to be aborted if they have been bought by takers and their stock listed. If, for instance, a maker is selling 100 points and a taker buys 60 points, if this taker does not list his stock, then the maker can abortAskOffer and all deals between the maker and taker gets cancelled. The maker will get all the collateral refunded and has no liability to settle any token.
So, when abortAskOffer is invoked, if the offer is listed, this function should revert:

if (offerInfo.abortOfferStatus != AbortOfferStatus.Initialized) {
revert InvalidAbortOfferStatus(AbortOfferStatus.Initialized, offerInfo.abortOfferStatus);
}

Vulnerability Details

The issue is that when an offer is listed, the abort offer status is not properly updated. This is from PreMarkets::listOffer:

if (makerInfo.offerSettleType == OfferSettleType.Turbo) {
address originOffer = makerInfo.originOffer;
OfferInfo memory originOfferInfo = offerInfoMap[originOffer];
if (_collateralRate != originOfferInfo.collateralRate) {
revert InvalidCollateralRate();
}
originOfferInfo.abortOfferStatus = AbortOfferStatus.SubOfferListed;
}

As can be seen, originOfferInfo.abortOfferStatus is set to SubOfferListed but originOfferInfo is stored in memory so the state variable is not updated.

PoC

Manual review

Tools Used

Manual review

Recommendations

Modify this in PreMarkets::listOffer:

if (makerInfo.offerSettleType == OfferSettleType.Turbo) {
address originOffer = makerInfo.originOffer;
- OfferInfo memory originOfferInfo = offerInfoMap[originOffer];
+ OfferInfo storage originOfferInfo = offerInfoMap[originOffer];
if (_collateralRate != originOfferInfo.collateralRate) {
revert InvalidCollateralRate();
}
originOfferInfo.abortOfferStatus = AbortOfferStatus.SubOfferListed;
}
Updates

Lead Judging Commences

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

finding-PreMarkets-listOffer-originIOfferInfo-storage-memory

Valid high severity, because the `abortOfferStatus` of the offer is not updated and persist through `storage` when listing an offer for turbo mode within the `offerInfoMap` mapping, it allows premature abortion given the `abortOfferStatus` defaults to `Initialized`, allowing the bypass of this [check](https://github.com/Cyfrin/2024-08-tadle/blob/04fd8634701697184a3f3a5558b41c109866e5f8/src/core/PreMarkets.sol#L552-L557) here and allow complete refund of initial collateral + stealing of trade tax which can potentially be gamed for profits using multiple addresses

Support

FAQs

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

Give us feedback!