The settleAuction function enables any user to finalize an auction once the auction end time has passed and the highest bid meets or exceeds the minimum price, by executing the sale which transfers the NFT to the winning bidder, calculates and accumulates fees, pays out the seller, and emits an event.
Multiple concurrent calls to settleAuction for the same tokenId can result in only one successful execution while others fail after partial processing if the payout fails, potentially causing inconsistencies in failedTransferCredits additions without completing the full finalization for subsequent calls, as the function lacks reentrancy guards or atomicity checks beyond the isListed modifier.
Likelihood:
Multiple transactions mine in the same block targeting the same ended auction.
Network congestion delays transaction confirmations allowing overlapping settlement attempts.
Impact:
Failed transactions consume gas without effect, wasting user resources.
Inconsistent state if payout fails in the successful call, leading to misplaced credits in failedTransferCredits.
The withdrawAllFailedCredits function allows a user to withdraw accumulated failed transfer credits for a specified receiver by transferring the amount to msg.sender if the transfer succeeds, and resetting the credit to zero.
The function reads the credit amount from failedTransferCredits[_receiver] but resets failedTransferCredits[msg.sender] to zero, creating a mismatch where credits for _receiver are read but msg.sender's credits are cleared, potentially allowing unauthorized clearing of credits or withdrawal of wrong amounts if _receiver differs from msg.sender.
Likelihood:
Users specify a _receiver different from msg.sender in the function call.
Malicious actors exploit the function by providing arbitrary _receiver addresses.
Impact:
Wrong user's credits get withdrawn to msg.sender, leading to fund theft.
Legitimate credits for msg.sender remain uncleared while another's are reset.
Auctions proceed with bidding, and upon ending, can be settled if the highest bid meets the minPrice, or unlisted by the seller if no bids were placed.
If an auction receives bids but the highest does not meet minPrice, it remains listed indefinitely without ability to settle (due to require(bids.amount >= minPrice)) or unlist (due to require(bidder == address(0)) in unlistNFT), trapping the NFT in a permanent listed state where the seller cannot recover it.
Likelihood:
Bidders place amounts below minPrice before auction ends.
Auction ends without meeting minPrice threshold.
Impact:
Seller unable to retrieve or relist the NFT, causing permanent lockup.
Marketplace credibility suffers from stuck auctions.
The unlistNFT function permits the seller to remove a listed NFT from the marketplace if no bids have been placed, by checking if the bidder address is zero and transferring the NFT back.
The check solely relies on bids[tokenId].bidder == address(0), which may not account for scenarios where bids were placed but later invalidated or deleted without fully resetting the bid struct, or if tokenId reuse/sequence issues allow interference from prior listings, potentially allowing unlisting with lingering bid data or preventing it erroneously.
Likelihood:
Bids get partially reset in other functions without clearing bidder.
TokenIds get relisted without fully deleting prior bid data.
Impact:
Seller unable to unlist despite no active bids, locking NFT.
Potential unlisting with unrefunded bids, leading to fund loss for bidders.
withdrawAllFailedCredits allows any user to withdraw another account’s failed transfer credits due to improper use of msg.sender instead of _receiver for balance reset and transfer.
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.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.