Bid Beasts

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

Premature auction settlement event misleads on auction status

Emitting AuctionSettled event during placeBid misrepresents active auctions as settled, confusing users and off-chain systems

Description

The BidBeastsNFTMarketPlace::AuctionSettled event is intended to signal the final settlement of an auction, indicating the winner, seller, and final price. However, it is incorrectly emitted in the BidBeastsNFTMarketPlace::placeBid function during regular bidding (not buy-now scenarios), despite the auction remaining active. This misrepresents the auction’s status, potentially confusing users and disrupting off-chain applications that rely on event logs.

// --- Buy Now Logic ---
if (listing.buyNowPrice > 0 && msg.value >= listing.buyNowPrice) {
...
}
require(msg.sender != previousBidder, "Already highest bidder");
@> emit AuctionSettled(tokenId, msg.sender, listing.seller, msg.value);
// --- Regular Bidding Logic ---

Risk

Likelihood: High

  • Occurs for every regular bid placed in placeBid, excluding buy-now scenarios.

Impact: Low

  • User Confusion: Users monitoring events think the auction ended when it didn't

  • Integration Issues: Off-chain applications (e.g., frontend, indexers) may incorrectly process auctions as settled, disrupting status displays or bidding interfaces.

Proof of Concept

  • To capture event emissions, import the Vm module in BidBeastsMarketPlaceTest.t.sol:

    import {Test, console, Vm} from "forge-std/Test.sol";

  • Next, add the following test to BidBeastsMarketPlaceTest.t.sol:

    function test_PrematureAuctionSettledEmission() public {
    _mintNFT();
    _listNFT();
    // Place bid - this will incorrectly emit AuctionSettled
    vm.recordLogs();
    vm.prank(BIDDER_1);
    market.placeBid{value: BID_AMOUNT}(TOKEN_ID);
    Vm.Log[] memory logs = vm.getRecordedLogs();
    // Count AuctionSettled events (should be 0, but will be 1)
    uint256 settledEventCount = 0;
    for(uint i = 0; i < logs.length; i++) {
    if(logs[i].topics[0] == keccak256("AuctionSettled(uint256,address,address,uint256)")) {
    settledEventCount++;
    }
    }
    console.log("AuctionSettled emitted during bidding:", settledEventCount);
    console.log("Auction still active?", market.getListing(TOKEN_ID).listed);
    // Now actually settle the auction
    vm.warp(block.timestamp + 16 minutes);
    vm.recordLogs();
    vm.prank(BIDDER_1);
    market.settleAuction(TOKEN_ID); // Emits `AuctionSettled` in `_executeSale()`
    logs = vm.getRecordedLogs();
    settledEventCount = 0;
    for(uint i = 0; i < logs.length; i++) {
    if(logs[i].topics[0] == keccak256("AuctionSettled(uint256,address,address,uint256)")) {
    settledEventCount++;
    }
    }
    console.log("AuctionSettled emitted after settlement:", settledEventCount);
    console.log("Number of times 'AuctionSettled' got emitted: 2 (should be 1)");
    }

  • Finally, run it using the command:

    forge test --mt test_PrematureAuctionSettledEmission -vv

  • The output we get:

    Ran 1 test for test/BidBeastsMarketPlaceTest.t.sol:BidBeastsNFTMarketTest
    [PASS] test_PrematureAuctionSettledEmission() (gas: 330618)
    Logs:
    AuctionSettled event emitted during bidding: 1
    Auction still active? true
    AuctionSettled event emitted after settlement: 1
    Number of times 'AuctionSettled' event got emitted: 2 (should be 1)
    Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.18ms (335.80µs CPU time)

Recommended Mitigation

Simple, and straightforward. Just remove the AuctionSettled event from placeBid function, as it doesn't belong there.

// lines 142-143 in placeBid
require(msg.sender != previousBidder, "Already highest bidder");
- 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.