Bid Beasts

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

Bid Increment Precision Loss Vulnerability in the `BidBeastsNFTMarketPlace.sol` contract

Description

  • Bid increments should ensure meaningful price increases to maintain competitive auction dynamics.

  • The bid increment calculation uses integer division that can result in zero increment for small bid amounts, allowing subsequent bidders to bid the same amount.

requiredAmount = (previousBidAmount / 100) * (100 + S_MIN_BID_INCREMENT_PERCENTAGE);

Risk

Likelihood:

  • Occurs for any bid amount less than 100 wei

  • More likely with low-value NFT auctions

Impact:

  • Bidders can outbid others without increasing the price

  • Auction mechanism becomes ineffective for price discovery

Proof of Concept

function test_HIGH_BidIncrementPrecisionLoss() public {
uint256 tokenId = _mintAndListNFT(ALICE, 1, 0); // Very low min price
// First bid with very small amount
uint256 firstBid = 4; // 4 wei
vm.prank(BOB);
market.placeBid{value: firstBid}(tokenId);
// Calculate required increment: (4 / 100) * 105 = 0 * 105 = 0
// So next bid only needs to be >= 4, not > 4
uint256 requiredAmount = (firstBid / 100) * (100 + 5); // This equals 0
// VULNERABILITY: Charlie can bid the same amount due to precision loss
vm.prank(CHARLIE);
market.placeBid{value: firstBid}(tokenId); // Same amount should work due to >= check
// Charlie becomes highest bidder without actually increasing bid meaningfully
BidBeastsNFTMarket.Bid memory highestBid = market.getHighestBid(tokenId);
assertEq(highestBid.bidder, CHARLIE, "Charlie should be highest bidder");
assertEq(highestBid.amount, firstBid, "Bid amount should be same as first bid");
}

Recommended Mitigation

} else {
- requiredAmount = (previousBidAmount / 100) * (100 + S_MIN_BID_INCREMENT_PERCENTAGE);
+ uint256 increment = (previousBidAmount * S_MIN_BID_INCREMENT_PERCENTAGE + 99) / 100; // Round up
+ requiredAmount = previousBidAmount + (increment == 0 ? 1 : increment); // Ensure minimum increment of 1 wei
require(msg.value >= requiredAmount, "Bid not high enough");
Updates

Lead Judging Commences

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

BidBeasts Marketplace: Integer Division Precision Loss

Integer division in requiredAmount truncates fractions, allowing bids slightly lower than intended.

Support

FAQs

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