Bid Beasts

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

First successful bid unlists NFT from marketplace and prevents auction from even starting

Root + Impact

The first successful bid placed for an NFT on the BidBeastNFTMarketPlace unlists the NFT from the marketplace and sends it bidder even if the bidder might not be the highest bidder.

Description

When the very first bidder successfully places a bid on a listed NFT, the NFT is unlisted, and bidding ends before other bidders even have a chance to bid.

  • Describe the normal behavior in one or more sentences

Normal expected behaviour should be the seller listing NFT on the marketplace and buyers (bidders) bidding above the minimum price until the auction ends.

  • Explain the specific issue or problem in one or more sentences

Bidding is prematurely terminated after the first bidder successfully bids, leading to denial of service to subsequent bidders.

// Root cause in the codebase with @> marks to highlight the relevant section

Risk

Likelihood: HIGH

  • Reason 1: This occurs when an NFT is listed and a bidder bids above the buyNowPrice

  • Reason 2

Impact:

  • Impact 1: First bidder ends auctions even if he might not be the highest bidder, since others cannot even bid as the NFT is now unlisted.

Proof of Concept

The solidity code below shows a clear PoC for the described vulnerability:

  • SELLERlists NFT for sale

  • BIDDER_1 places a bid

  • NFT is unlisted

  • BIDDER_2 tries to place a higher bid and is denied since the NFT is no longer listed on the marketplace.


function test_settleAuctionSuccessfully() public {
// owner mints nft to seller
vm.startPrank(OWNER);
nft.mint(SELLER);
vm.stopPrank();
// seller lists nft on marketplace
vm.startPrank(SELLER);
nft.approve(address(market), TOKEN_ID);
market.listNFT(TOKEN_ID, MIN_PRICE, BUY_NOW_PRICE);
vm.stopPrank();
vm.warp(block.timestamp + 1 days);
// first bidder places a bid
vm.prank(BIDDER_1);
market.placeBid{value: 10 ether}(TOKEN_ID);
// second bidder places a higher bid
// this second bid will fail since the first bid was successful and unlisted the nft
vm.prank(BIDDER_2);
market.placeBid{value: 15 ether}(TOKEN_ID);
// all code below will revert with NFT is not listed error
// fast forward time to end the auction
// ends after 3 days
vm.warp(block.timestamp + 2 days);
// anyone calls finalize auction
vm.prank(BIDDER_1);
market.settleAuction(TOKEN_ID);
// assertions
assertEq(nft.ownerOf(TOKEN_ID), BIDDER_1, "NFT should be transferred to highest bidder");
}

Recommended Mitigation

The listed field should be true since the auction has not ended, which allows other bidders to outbid the first bidder

- remove this code
- listing.listed = false;
- _executeSale(tokenId);
+ add this code
+ listing.listed = true;
Updates

Lead Judging Commences

cryptoghost Lead Judge 28 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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