Bid Beasts

First Flight #49
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

NFT Becomes Permanently Locked When Auction Ends with Insufficient Bid

Root + Impact

Description

  • A deadlock condition permanently locks an NFT and a bidder's funds within the marketplace contract. This state occurs when an auction receives one or more bids but concludes with the highest bid being less than the seller's required minPrice. In this scenario, the seller is blocked from calling

    unlistNFT because a bid has been placed, and no one can call settleAuction because the final bid is too low. There is no other function to resolve this state.


Risk

Likelihood:

  • This occurs whenever an auction ends after at least one bid has been placed.

  • The highest bid at the end of the auction is less than the minPrice set during the listing

Impact:

  • The seller suffers a permanent, irreversible loss of their NFT.

  • The last bidder suffers a permanent, irreversible loss of their bid amount (ETH).

Proof of Concept

// In unlistNFT, this check blocks the seller
require(bids[tokenId].bidder == address(0), "Cannot unlist, a bid has been placed");
// In settleAuction, this check blocks settlement
require(bids[tokenId].amount >= listings[tokenId].minPrice, "Highest bid did not meet min price");

Recommended Mitigation

// In settleAuction function
function settleAuction(uint256 tokenId) external isListed(tokenId) {
Listing storage listing = listings[tokenId];
require(listing.auctionEnd > 0, "Auction has not started (no bids)");
require(block.timestamp >= listing.auctionEnd, "Auction has not ended");
- require(bids[tokenId].amount >= listing.minPrice, "Highest bid did not meet min price");
- _executeSale(tokenId);
+ if (bids[tokenId].amount >= listing.minPrice) {
+ _executeSale(tokenId);
+ } else {
+ // Cancel the auction: refund bidder and return NFT to seller
+ listing.listed = false;
+ Bid memory lastBid = bids[tokenId];
+ delete bids[tokenId];
+ _payout(lastBid.bidder, lastBid.amount);
+ BBERC721.transferFrom(address(this), listing.seller, tokenId);
+ emit NftUnlisted(tokenId);
+ }
}
Updates

Lead Judging Commences

cryptoghost Lead Judge 28 days ago
Submission Judgement Published
Validated
Assigned finding tags:

BidBeasts Marketplace: Risk of Locked NFTs

Non-safe transferFrom calls can send NFTs to non-compliant contracts, potentially locking them permanently.

Support

FAQs

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