Bid Beasts

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

First Bid Revert Issue When Bid Equals Minimum Price

Root + Impact

Description

  • Normal behavior: When a first bid is placed on an auction, the contract ensures that the bid meets the minimum listing price (minPrice) before accepting it.

Issue: The contract currently requires msg.value > listing.minPrice, which excludes a bid exactly equal to minPrice. This could unintentionally reject valid first bids that are exactly equal to the minimum price.

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);

Risk

Likelihood:

  • Any user attempting to place a first bid exactly equal to the listing’s minimum price will encounter a transaction revert.

Impact:

  • May be perceived as a bug or unfair behavior in the auction logic.

Proof of Concept

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {Test, console} from "forge-std/Test.sol";
import {BidBeastsNFTMarket} from "../src/BidBeastsNFTMarketPlace.sol";
import {BidBeasts} from "../src/BidBeasts_NFT_ERC721.sol";
// A mock contract that cannot receive Ether, to test the payout failure logic.
contract RejectEther {
// Intentionally has no payable receive or fallback
}
contract BidBeastsNFTMarketTest is Test {
// --- State Variables ---
BidBeastsNFTMarket market;
BidBeasts nft;
RejectEther rejector;
// --- Users ---
address public constant OWNER = address(0x1); // Contract deployer/owner
address public constant SELLER = address(0x2);
address public constant BIDDER_1 = address(0x3);
address public constant BIDDER_2 = address(0x4);
// --- Constants ---
uint256 public constant STARTING_BALANCE = 100 ether;
uint256 public constant TOKEN_ID = 0;
uint256 public constant MIN_PRICE = 1 ether;
uint256 public constant BUY_NOW_PRICE = 5 ether;
function setUp() public {
// Deploy contracts
vm.prank(OWNER);
nft = new BidBeasts();
market = new BidBeastsNFTMarket(address(nft));
rejector = new RejectEther();
vm.stopPrank();
// Fund users
vm.deal(SELLER, STARTING_BALANCE);
vm.deal(BIDDER_1, STARTING_BALANCE);
vm.deal(BIDDER_2, STARTING_BALANCE);
}
// --- Helper function to list an NFT ---
function _listNFT() internal {
vm.startPrank(SELLER);
nft.approve(address(market), TOKEN_ID);
market.listNFT(TOKEN_ID, MIN_PRICE, BUY_NOW_PRICE);
vm.stopPrank();
}
// -- Helper function to mint an NFT ---
function _mintNFT() internal {
vm.startPrank(OWNER);
nft.mint(SELLER);
vm.stopPrank();
}
/*//////////////////////////////////////////////////////////////
LISTING TESTS
//////////////////////////////////////////////////////////////*/
function testAuctionSettledAfter3Days() public {
_mintNFT();
_listNFT();
// First bid (3 ether, no buyNow triggered)
vm.prank(BIDDER_1);
vm.expectRevert(bytes("First bid must be > min price"));
market.placeBid{value: 1 ether}(TOKEN_ID);
}
}

Recommended Mitigation

- require(msg.value > requiredAmount, "First bid must be > min price");
+ require(msg.value >= requiredAmount, "First bid must be >=First Bid Revert Issue When Bid Equals Minimum Price min price");
Updates

Lead Judging Commences

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

Give us feedback!