Bid Beasts

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

Auction Duration Extension can cause an aution to hold infintely if no `buyNowPrice` is set for the NFT sale.

Root + Impact

Auction Duration Extension can cause an aution to hold infintely if no buyNowPrice is set for the NFT sale.

Description

If an NFT is listed without a buyNowPrice set, then its auction has no price cap, and bids are allowed to be placed until the auction deadline is met which is 3 days after the first bid is placed as stated in the documentation.

However, due to the increment of the Listing.auctionEnd by S_AUCTION_EXTENSION_DURATION anytime a bid is placed and Listing.auctionEnd is less than 15 minutes, and the lack of a time cap implementation of 3 days in the code,the auction could potentially run infintely as new bid are being placed.
The affected code:

function placeBid(uint256 tokenId) external payable isListed(tokenId) {
.
.
.
@> if (timeLeft < S_AUCTION_EXTENSION_DURATION) {
console.log("CODE IS REACHED");
@> listing.auctionEnd = listing.auctionEnd + S_AUCTION_EXTENSION_DURATION;
emit AuctionExtended(tokenId, listing.auctionEnd);
}
.
.
.
}
https://github.com/CodeHawks-Contests/2025-09-bid-beasts/blob/449341c55a57d3f078d1250051a7b34625d3aa04/src/BidBeastsNFTMarketPlace.sol#L164

Risk

Likelihood:

  • Reason 1: Auction time is extended whenever a new bid is placed, before the last 15 minutes of the auction

Impact:

  • The auction runs infinitely

Proof of Concept

  • This shows users placing a bid during the last 15 minutes of the auction.

Place the following code in BidBeastsNFTMarketTest.t.sol

function testAuctionEndCap() public warmMarket {
vm.prank(BIDDER_1);
vm.warp(block.timestamp + 5 minutes);
market.placeBid{value: MIN_PRICE + 0.5 ether}(TOKEN_ID);
vm.prank(BIDDER_2);
vm.warp(block.timestamp + 10 minutes);
market.placeBid{value: MIN_PRICE + 1 ether}(TOKEN_ID);
vm.prank(BIDDER_1);
vm.warp(block.timestamp + 11 minutes);
market.placeBid{value: MIN_PRICE + 2 ether}(TOKEN_ID);
vm.prank(BIDDER_2);
vm.warp(block.timestamp + 12 minutes);
market.placeBid{value: MIN_PRICE + 3 ether}(TOKEN_ID);
vm.prank(BIDDER_1);
vm.warp(block.timestamp + 13 minutes);
market.placeBid{value: MIN_PRICE + 4 ether}(TOKEN_ID);
vm.prank(BIDDER_2);
vm.warp(block.timestamp + 5 minutes);
market.placeBid{value: MIN_PRICE + 5 ether}(TOKEN_ID);
}

Recommended Mitigation

  • Set the Listing.auctionEnd to the deadline (3 days) when the first bid is place

  • Check that the current block.timestamp is less than Listing.auctionEnd before an action is taken

  • Check that the current block.timestamp is greater than Listing.auctionEnd before an auction can be settled

Updates

Lead Judging Commences

cryptoghost Lead Judge 2 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

ntdegenerate Submitter
2 months ago
cryptoghost Lead Judge
2 months ago
cryptoghost Lead Judge 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BidBeast Marketplace: Auction Duration Miscalculation

BidBeast marketplace contains a flaw in its auction timing mechanism. This causes the contract to miscalculate the actual end time of an auction, resulting in auctions that either conclude prematurely or run longer than specified.

Support

FAQs

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

Give us feedback!