Bid Beasts

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

Reentrancy Vulnerability in placeBid Buy-Now Flow

Root + Impact

Description

  • The placeBid function is vulnerable to reentrancy when processing buy-now purchases. After setting the bid and marking the listing as not listed, the function calls _payout to refund the previous bidder before calling _executeSale. The _executeSale function then transfers the NFT and makes another external call to pay the seller. A malicious previous bidder could reenter through their receive function and exploit the inconsistent state where the listing is marked as unlisted but the NFT hasn't been transferred yet.

if (listing.buyNowPrice > 0 && msg.value >= listing.buyNowPrice) {
uint256 salePrice = listing.buyNowPrice;
uint256 overpay = msg.value - salePrice;
// EFFECT: set winner bid to exact sale price (keep consistent)
bids[tokenId] = Bid(msg.sender, salePrice);
listing.listed = false;
if (previousBidder != address(0)) {
_payout(previousBidder, previousBidAmount); // External call before critical state changes
}
// NOTE: using internal finalize to do transfer/payouts
_executeSale(tokenId);

Risk

Likelihood:

  • This occurs whenever a buy-now purchase is executed on a listing that already has an existing bid, since the contract refunds the previous bidder through _payout before completing the NFT transfer.

  • A malicious previous bidder can exploit the refund callback via their receive() function to reenter the contract during this window, while the listing is already marked as unlisted but before _executeSale finalizes the transfer and payments.Impact:

  • A malicious bidder could potentially manipulate the auction state during reentrancy, possibly causing the NFT transfer to fail or manipulating the fee calculation. While the immediate financial impact is limited due to the state changes already made, it could cause accounting inconsistencies or DoS conditions.


Proof of Concept

contract MaliciousBidder {
BidBeastsNFTMarket marketplace;
uint256 targetTokenId;
receive() external payable {
// Reenter during refund
// The listing is marked as unlisted but NFT not transferred yet
// Could attempt to call settleAuction or other functions
marketplace.settleAuction(targetTokenId);
}
}

Recommended Mitigation

Add reentrancy guard or restructure to follow checks-effects-interactions

if (listing.buyNowPrice > 0 && msg.value >= listing.buyNowPrice) {
uint256 salePrice = listing.buyNowPrice;
uint256 overpay = msg.value - salePrice;
address prevBidder = previousBidder;
uint256 prevAmount = previousBidAmount;
// Effects first
bids[tokenId] = Bid(msg.sender, salePrice);
listing.listed = false;
// Execute sale (includes NFT transfer)
_executeSale(tokenId);
// Interactions last
if (prevBidder != address(0)) {
_payout(prevBidder, prevAmount);
}
if (overpay > 0) {
_payout(msg.sender, overpay);
}
}
Updates

Lead Judging Commences

cryptoghost Lead Judge 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BidBeast Marketplace: Reentrancy In PlaceBid

BidBeast Marketplace has a Medium-severity reentrancy vulnerability in its "buy-now" feature that allows an attacker to disrupt the platform by blocking sales or inflating gas fees for legitimate users.

Support

FAQs

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

Give us feedback!