Bid Beasts

First Flight #49
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

unlistNFT does not remove the unlisted tokenId from the state variable

Root + Impact

Description

  • unlistNFT transfers the NFT back to the seller but only sets listing.listed = false. The rest of the listings[tokenId] struct (seller, minPrice, buyNowPrice, etc.) remains in storage, leaving stale data that can confuse other contract logic or off-chain indexers and wastes storage. The unlisted NFT token should either be removed from the listings state variable or listed flag must be marked as false in the state variable.

// Root cause in the codebase with @> marks to highlight the relevant section
function unlistNFT(uint256 tokenId) external isListed(tokenId) isSeller(tokenId, msg.sender) {
require(bids[tokenId].bidder == address(0), "Cannot unlist, a bid has been placed");
Listing storage listing = listings[tokenId];
listing.listed = false;
BBERC721.transferFrom(address(this), msg.sender, tokenId);
emit NftUnlisted(tokenId);
}

Risk

Likelihood:

  • Medium — likely to occur when seller attempts unlist after listing.

  • It occurs everytime when the owner tries to unlist the tokens

Impact:

  • High — token effectively locked inside marketplace; subsequent operations may fail or revert.

Proof of Concept

// Manual review

Recommended Mitigation

- function unlistNFT(uint256 tokenId) external isListed(tokenId) isSeller(tokenId, msg.sender) {
- require(bids[tokenId].bidder == address(0), "Cannot unlist, a bid has been placed");
- Listing storage listing = listings[tokenId];
- listing.listed = false;
- emit NftUnlisted(tokenId);
- }
+ function unlistNFT(uint256 tokenId) external isListed(tokenId) isSeller(tokenId, msg.sender) nonReentrant {
+ require(bids[tokenId].bidder == address(0), "Cannot unlist, a bid has been placed");
+ Listing storage listing = listings[tokenId];
+
+ delete listings[tokenId];
+
+ BBERC721.safeTransferFrom(address(this), listing.seller, tokenId);
+ emit NftUnlisted(tokenId);
+ }
Updates

Lead Judging Commences

cryptoghost Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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