Bid Beasts

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

Premature Event Emission in Buy Now Logic in the `BidBeastsNFTMarketplace::placeBid()` function

Description

  • Events should accurately reflect when actions occur and contain correct parameters that match the actual transaction state.

  • The BidBeastsNFTMarketplace::placeBid() function incorrectly emits an AuctionSettled event with msg.value instead of the actual sale price during buy now purchases, and emits the event before the auction is actually settled.

require(msg.sender != previousBidder, "Already highest bidder");
@> emit AuctionSettled(tokenId, msg.sender, listing.seller, msg.value);

Risk

Likelihood:

  • Occurs every time someone uses the buy now feature

  • Event listeners and analytics will receive incorrect information

Impact:

  • Misleading event logs for external systems and indexers

  • Incorrect price data being recorded in events

Proof of Concept

function test_HIGH_PrematureEventEmissionBuyNow() public {
uint256 tokenId = _mintAndListNFT(ALICE, MIN_PRICE, BUY_NOW_PRICE);
// First bidder places a regular bid
vm.prank(BOB);
market.placeBid{value: MIN_PRICE + 0.1 ether}(tokenId);
// Second bidder triggers buy now
vm.prank(CHARLIE);
// VULNERABILITY: AuctionSettled event is emitted with wrong parameters during buy now
vm.expectEmit(true, true, false, false);
emit BidBeastsNFTMarket.AuctionSettled(
tokenId,
CHARLIE,
ALICE,
BUY_NOW_PRICE // Event shows BUY_NOW_PRICE but actual msg.value might be higher
);
market.placeBid{value: BUY_NOW_PRICE}(tokenId);
// The event should be emitted by _executeSale, not during placeBid
// This creates confusion about when the auction actually settled
}

Recommended Mitigation

// --- Buy Now Logic ---
if (listing.buyNowPrice > 0 && msg.value >= listing.buyNowPrice) {
uint256 salePrice = listing.buyNowPrice;
uint256 overpay = msg.value - salePrice;
// EFFECT: set winner bid to exact sale price (keep consistent)
bids[tokenId] = Bid(msg.sender, salePrice);
listing.listed = false;
if (previousBidder != address(0)) {
_payout(previousBidder, previousBidAmount);
}
- require(msg.sender != previousBidder, "Already highest bidder");
- emit AuctionSettled(tokenId, msg.sender, listing.seller, msg.value);
// NOTE: using internal finalize to do transfer/payouts. _executeSale will assume bids[tokenId] is the final winner.
_executeSale(tokenId);
// Refund overpay (if any) to buyer
if (overpay > 0) {
_payout(msg.sender, overpay);
}
return;
}
Updates

Lead Judging Commences

cryptoghost Lead Judge 2 months 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.

Give us feedback!