Bid Beasts

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

[L-1] First Bid Cannot Equal minPrice, Violating Principle of Least Surprise

First Bid Cannot Equal minPrice, Violating Principle of Least Surprise

Description

  • An auction's minPrice should represent the lowest acceptable bid. A user should be able to place a bid equal to this price.

  • The check for the first bid requires that msg.value be strictly greater than (>) the minPrice. This prevents users from placing a bid exactly equal to the minimum price, which is counter-intuitive and undocumented behavior.

// src/BidBeastsNFTMarketPlace.sol
if (previousBidAmount == 0) {
requiredAmount = listing.minPrice;
// @> Use of `>` prevents bidding the exact minPrice
require(msg.value > requiredAmount, "First bid must be > min price");
listing.auctionEnd = block.timestamp + S_AUCTION_EXTENSION_DURATION;

Risk

Likelihood: Medium

  • This will occur whenever a user attempts to open bidding at the exact minimum price.

Impact: Low

  • Funds are not at risk.

  • A function is incorrect, causing user transactions to revert unexpectedly and creating a slight disruption in protocol functionality.

Proof of Concept

Both test_placeSubsequentBid_RefundsPreviousand test_placeFirstBid revert because the user places a bid with the minimum amount.

function test_placeFirstBid() public {
_mintNFT();
_listNFT();
vm.prank(BIDDER_1);
>@ market.placeBid{value: MIN_PRICE}(TOKEN_ID); //placing with with MIN_VALUE will revert
BidBeastsNFTMarket.Bid memory highestBid = market.getHighestBid(TOKEN_ID);
assertEq(highestBid.bidder, BIDDER_1);
assertEq(highestBid.amount, MIN_PRICE);
assertEq(market.getListing(TOKEN_ID).auctionEnd, block.timestamp + market.S_AUCTION_EXTENSION_DURATION());
}
function test_placeSubsequentBid_RefundsPrevious() public {
_mintNFT();
_listNFT();
vm.prank(BIDDER_1);
>@ market.placeBid{value: MIN_PRICE}(TOKEN_ID); //placing with with MIN_VALUE will revert( same as before)
uint256 bidder1BalanceBefore = BIDDER_1.balance;
uint256 secondBidAmount = MIN_PRICE * 120 / 100; // 20% increase
vm.prank(BIDDER_2);
market.placeBid{value: secondBidAmount}(TOKEN_ID);
// Check if bidder 1 was refunded
assertEq(BIDDER_1.balance, bidder1BalanceBefore + MIN_PRICE, "Bidder 1 was not refunded");
BidBeastsNFTMarket.Bid memory highestBid = market.getHighestBid(TOKEN_ID);
assertEq(highestBid.bidder, BIDDER_2, "Bidder 2 should be the new highest bidder");
assertEq(highestBid.amount, secondBidAmount, "New highest bid amount is incorrect");
}

Recommended Mitigation

Consider using >=:

// src/BidBeastsNFTMarketPlace.sol
- 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 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!