Bid Beasts

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

Misleading AuctionSettled event emitted on every bid (event log inconsistency)

The placeBid function emits the AuctionSettled event every time a new bid is placed, even though the auction has not actually ended.This causes off-chain systems, UIs, and analytics tools to incorrectly assume that the auction is over. This is a logic/event-handling bug that can mislead users and automated systems.

Description

  • Normal behavior: The AuctionSettled event should only be emitted once the auction has truly ended, either via:

    • _executeSale when BuyNow is triggered

    • settleAuction after auction expiry

    • takeHighestBid if the seller accepts the highest bid

  • In the current code, this event is emitted inside placeBid for every new bid, regardless of the auction state

function placeBid(uint256 tokenId) external payable isListed(tokenId) {
// Rest of the function
// Line 147
require(msg.sender != previousBidder, "Already highest bidder");
@> emit AuctionSettled(tokenId, msg.sender, listing.seller, msg.value);

Risk

Likelihood:

  • Any bidder placing a bid will trigger the misleading event — exploitation is trivial.

  • High chance of misleading off-chain observers, analytics, or bots that rely on this event.

Impact:

  • Misleading user interface and automation: Users may believe the auction is over and stop bidding or attempt incorrect actions.

Proof of Concept

  • In the foundry test I have made 2 bids using 2 distant addressed and at both times times the AuctionSettled event is gettin emitted.

function test_EmitEvent() public {
_mintNFT();
_listNFT();
vm.expectEmit(true, true, true, true);
emit AuctionSettled(TOKEN_ID, BIDDER_1, SELLER, 1.2 ether);
vm.prank(BIDDER_1);
market.placeBid{value: 1.2 ether}(TOKEN_ID);
vm.expectEmit(true, true, true, true);
emit AuctionSettled(TOKEN_ID, BIDDER_2, SELLER, 5 ether);
vm.prank(BIDDER_2);
market.placeBid{value: 5 ether}(TOKEN_ID);
address owner = nft.ownerOf(TOKEN_ID);
assertEq(BIDDER_2,owner);
}
/* Output
emit AuctionSettled(tokenId: 0, winner: RIPEMD-160: [0x0000000000000000000000000000000000000003], seller: SHA-256: [0x0000000000000000000000000000000000000002], price: 1200000000000000000 [1.2e18])
│ ├─ emit AuctionExtended(tokenId: 0, newDeadline: 901)
│ ├─ emit BidPlaced(tokenId: 0, bidder: RIPEMD-160: [0x0000000000000000000000000000000000000003], amount: 1200000000000000000 [1.2e18])
│ └─ ← [Stop]
├─ [0] VM::expectEmit(true, true, true, true)
│ └─ ← [Return]
├─ emit AuctionSettled(tokenId: 0, winner: Identity: [0x0000000000000000000000000000000000000004], seller: SHA-256: [0x0000000000000000000000000000000000000002], price: 5000000000000000000 [5e18])
*/

Recommended Mitigation

  • Remove this code completely from line 147 because even if the auction is getting settled because of the person is buying the nft not bidding for it. The event is getting emitted in the _executeSale as well.

_executeSale- emit AuctionSettled(tokenId, msg.sender, listing.seller, 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.