Tadle

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

Incorrect update of abort status in `listOffer` function

Vulnerability Details

The abortAskOffer function allows an ask offer maker to abort their offer and reclaim their collateral, while takers of the offer can retrieve their deposits. In Turbo mode, if an original offer has subsequent trades, it cannot be aborted. To enforce this, the listOffer function attempts to update the status of the original offer to SubOfferListed when a sub-offer is created from an original Turbo mode offer, this is intended to prevent the original offer from being aborted when calling abortAskOffer. The issue is that listOffer does not correctly update the origin offer status to SubOfferListed:

function listOffer(
address _stock,
uint256 _amount,
uint256 _collateralRate
) external payable {
// ...
/// @dev change abort offer status when offer settle type is turbo
if (makerInfo.offerSettleType == OfferSettleType.Turbo) {
address originOffer = makerInfo.originOffer;
>>> OfferInfo memory originOfferInfo = offerInfoMap[originOffer];
if (_collateralRate != originOfferInfo.collateralRate) {
revert InvalidCollateralRate();
}
>>> originOfferInfo.abortOfferStatus = AbortOfferStatus.SubOfferListed;
}
// ...
}

In the above code, the originOfferInfo variable is incorrectly defined with the memory keyword instead of storage. As a result, the update originOfferInfo.abortOfferStatus = AbortOfferStatus.SubOfferListed; does not persist after the transaction, making the original offers in Turbo mode incorrectly abortable.

Impact

The listOffer function does not update the abort status of the original offer, allowing offers in Turbo mode with subsequent offers to be aborted when they should not be.

Tools Used

Manual Review

Recommendations

Update the originOfferInfo variable's location from memory to storage:

function listOffer(
address _stock,
uint256 _amount,
uint256 _collateralRate
) external payable {
// ...
/// @dev change abort offer status when offer settle type is turbo
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 about 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.