Dria

Swan
NFTHardhat
21,000 USDC
View results
Submission Details
Severity: medium
Valid

Malicious seller can DoS buyers by revoking ERC721 token approval

Summary

Seller can list an asset that will be impossible to buy and that will lead to the entire purchase transaction to be reverted.

Vulnerability Details

During the purchase of an asset, the Swan contract attempts to transfer asset from the seller balance:

https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/swan/Swan.sol#L294

// update asset status to be sold
listing.status = AssetStatus.Sold;
// transfer asset from seller to Swan, and then from Swan to buyer
// this ensure that only approval to Swan is enough for the sellers
>>> SwanAsset(_asset).transferFrom(listing.seller, address(this), 1);
SwanAsset(_asset).transferFrom(address(this), listing.buyer, 1);

In normal circumstances it will work since the Swan contract was approved as a token spender: https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/swan/SwanAsset.sol#L41. However, a malicious user, as an owner of the asset, can revoke that approval at any time, for example by calling ERC721.setApprovalForAll(<swan_contract_address>, false) or by transferring an asset token to another address. That will lead to the purchase of that asset to revert. Moreover, because it is expected that all designated assets to be purchased at one shot via calling BuyerAgent.purchase(), such failure will cause an entire transaction to revert:

https://github.com/Cyfrin/2024-10-swan-dria/blob/main/contracts/swan/BuyerAgent.sol#L251

// we purchase each asset returned
for (uint256 i = 0; i < assets.length; i++) {
address asset = assets[i];
// must not exceed the roundly buy-limit
uint256 price = swan.getListingPrice(asset);
spendings[round] += price;
if (spendings[round] > amountPerRound) {
revert BuyLimitExceeded(spendings[round], amountPerRound);
}
// add to inventory
inventory[round].push(asset);
// make the actual purchase
swan.purchase(asset); // <-- will cause entire transaction to revert
}

Impact

Inability to purchase any asset in a round.

Tools Used

Manual review

Recommendations

Transfer an asset token from seller to Swan contract, release it to buyer upon purchase, or return to seller if listing is cancelled.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

DoS in BuyerAgent::purchase

Support

FAQs

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