Bid Beasts

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

Premature AuctionSettled Emission Causing Frontend Delisting

Premature AuctionSettled Emission Causing Frontend Delisting

Description

AuctionSettled event signals auction completion and NFT transfer to winner. In placeBid, it emits prematurely during regular bidding, misleading frontend to delist active auctions prematurely.

require(msg.sender != previousBidder, "Already highest bidder");
@>emit AuctionSettled(tokenId, msg.sender, listing.seller, msg.value);@>
// --- Regular Bidding Logic ---
uint256 requiredAmount;

Risk

Likelihood:

  • During multi-bid auctions where frontend polls events for status.

  • When bidders refresh views relying on AuctionSettled for delisting.

Impact:

  • Hides active NFTs from potential bidders, reducing participation.

  • Sellers lose visibility, potentially lowering final sale prices.

Proof of Concept

Lists NFT, places first bid expecting AuctionSettled event, checks listing still active and timer running to show wrong early signal.

// add event to test file
event AuctionSettled(uint256 tokenId, address winner, address seller, uint256 price);
function testPrematureAuctionSettledEmission() public {
_mintNFT();
_listNFT();
// BIDDER_1 places first bid
vm.deal(BIDDER_1, MIN_PRICE + 0.01 ether);
vm.expectEmit(true, true, false, true);
emit BidBeastsNFTMarket.AuctionSettled(TOKEN_ID, BIDDER_1, SELLER, MIN_PRICE + 0.01 ether);
vm.prank(BIDDER_1);
market.placeBid{value: MIN_PRICE + 0.01 ether}(TOKEN_ID);
// Auction still active despite emission
BidBeastsNFTMarket.Listing memory listing = market.getListing(TOKEN_ID);
assertTrue(listing.listed);
assertEq(listing.auctionEnd, block.timestamp + 15 minutes);
}

Recommended Mitigation

Cuts out early AuctionSettled emit in bidding; keeps only right BidPlaced event after update.

require(msg.sender != previousBidder, "Already highest bidder");
- emit AuctionSettled(tokenId, msg.sender, listing.seller, msg.value);
// --- Regular Bidding Logic ---
uint256 requiredAmount;
if (previousBidAmount == 0) {
requiredAmount = listing.minPrice;
require(msg.value > requiredAmount, "First bid must be > min price");
listing.auctionEnd = block.timestamp + S_AUCTION_EXTENSION_DURATION;
emit AuctionExtended(tokenId, listing.auctionEnd);
} else {
requiredAmount = (previousBidAmount / 100) * (100 + S_MIN_BID_INCREMENT_PERCENTAGE);
require(msg.value >= requiredAmount, "Bid not high enough");
uint256 timeLeft = 0;
if (listing.auctionEnd > block.timestamp) {
timeLeft = listing.auctionEnd - block.timestamp;
}
if (timeLeft < S_AUCTION_EXTENSION_DURATION) {
listing.auctionEnd = listing.auctionEnd + S_AUCTION_EXTENSION_DURATION;
emit AuctionExtended(tokenId, listing.auctionEnd);
}
}
// EFFECT: update highest bid
bids[tokenId] = Bid(msg.sender, msg.value);
if (previousBidder != address(0)) {
_payout(previousBidder, previousBidAmount);
}
emit BidPlaced(tokenId, msg.sender, msg.value);
Updates

Lead Judging Commences

cryptoghost Lead Judge about 1 month ago
Submission Judgement Published
Validated
Assigned finding tags:

BidBeasts Marketplace: Incorrect Event Emission

placeBid emits AuctionSettled even though the auction hasn’t ended, causing misleading event logs.

Support

FAQs

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