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 2 months 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.

Give us feedback!