Bid Beasts

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

Strict Greater-Than check prevents minimum price bidding

Inconsistent validation logic prevents bidding at the seller-defined minimum price

Description

  • For this auction, there's a BidBeastsNFTMarketPlace::Listing.minPrice set by the seller, which, as the name suggests, is the minimum price at which the seller is willing to sell their NFT.

  • But the contract enforces that the first bid must be strictly greater than this minPrice, preventing bids exactly at minPrice (line 151 in BidBeastsNFTMarketPlace::placeBid):

    if (previousBidAmount == 0) {
    requiredAmount = listing.minPrice;
    @> require(msg.value > requiredAmount, "First bid must be > min price");

  • Plus, it can be seen that both BidBeastsNFTMarketPlace::settleAuction and BidBeastsNFTMarketPlace::takeHighestBid functions checks if the highest bid is greater than or equal to (>=) the minPrice, indicating the seller's intent to accept bids at minPrice (lines 186 and 196 respectively):

    function settleAuction(uint256 tokenId) external isListed(tokenId) {
    ...
    @> require(bids[tokenId].amount >= listing.minPrice, "Highest bid did not meet min price");
    ...
    }
    function takeHighestBid(uint256 tokenId) external isListed(tokenId) isSeller(tokenId, msg.sender) {
    ...
    @> require(bid.amount >= listings[tokenId].minPrice, "Highest bid is below min price");
    ...
    }

  • This discrepancy forces bidders to overpay by at least 1 wei, creating unnecessary friction.

Risk

Likelihood: Medium

  • Occurs when a bidder tries to bid exactly at minPrice for the first bid.

Impact: Low

  • Bidders can't bid at the exact minimum price

  • No funds at risk, just a minimal overpayment of 1 wei

Proof of Concept

  • Add the following test test_cannotBidAtMinPrice in the test file:

    function test_cannotBidAtMinPrice() public {
    // Mint and list NFT
    _mintNFT();
    _listNFT(); // MIN_PRICE = 1 ether
    console.log("Minimum price set at:", MIN_PRICE);
    // Attempt to place a bid exactly at min price
    vm.prank(BIDDER_1);
    vm.expectRevert("First bid must be > min price");
    market.placeBid{value: MIN_PRICE}(TOKEN_ID);
    // Place a valid first bid above min price
    uint256 validBid = MIN_PRICE + 1 wei;
    vm.prank(BIDDER_1);
    market.placeBid{value: validBid}(TOKEN_ID);
    (, uint256 amount) = market.bids(TOKEN_ID);
    console.log();
    console.log("Valid first bid placed:", amount);
    }

  • Run the above test using the command:

    forge test --mt test_cannotBidAtMinPrice -vv

  • The output we get:

    Ran 1 test for test/BidBeastsMarketPlaceTest.t.sol:BidBeastsNFTMarketTest
    [PASS] test_cannotBidAtMinPrice() (gas: 309520)
    Logs:
    Minimum price set at: 1000000000000000000
    Valid first bid placed: 1000000000000000001
    Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.14ms (197.40µs CPU time)

Recommended Mitigation

Change the strict greater-than (>) to greater-than-or-equal-to (>=) in the placeBid function:

// line 151 in placeBid
- require(msg.value > requiredAmount, "First bid must be > min price");
+ require(msg.value >= requiredAmount, "First bid must be >= min price");
Updates

Lead Judging Commences

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

BidBeasts Marketplace: First Bid > Instead of >=

First bid validation uses > instead of >=, preventing valid starting bids.

Support

FAQs

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