Bid Beasts

First Flight #49
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

Win the bid each time with DOS attack

Root + Impact

Description

  • Normal behavior :
    When the next bidder places a bid, the former bidder gets refunded.

  • Problem here :
    If the former bidder is a contract that can not accept native tokens / eth, then when the next bidder places a bid, the former bidder will not be able de get refunded and the whole transaction will revert. It means his bid will always be in place until the end of the auction. He will always win the auction.


    https://github.com/CodeHawks-Contests/2025-09-bid-beasts/blob/main/src/BidBeastsNFTMarketPlace.sol#L173

// EFFECT: update highest bid
bids[tokenId] = Bid(msg.sender, msg.value);
if (previousBidder != address(0)) {
_payout(previousBidder, previousBidAmount);//<@ Here the previous bidder is supposed to get refunded
}

Risk

Likelihood: High

  • Each time a new bidder will be bidding, the transaction will revert and no new bid will be placed.

Impact: High

  • An attacker can place the first bid at the minimum price, and he will always win the bid. The auction protocol becomes unfair to other participants and loses its value.

Recommended Mitigation

Do not accept smart contracts nor smart accounts as bidders.
Or wrap the native tokens before sending them back to the former bidder, this way the refund will always go through.

This process won't change the fact that the transaction will revert:

https://github.com/CodeHawks-Contests/2025-09-bid-beasts/blob/main/src/BidBeastsNFTMarketPlace.sol#L224-L233

/**
* @notice A payout function that credits users if a direct transfer fails.
*/
function _payout(address recipient, uint256 amount) internal {
if (amount == 0) return;
(bool success, ) = payable(recipient).call{value: amount}("");
if (!success) {
failedTransferCredits[recipient] += amount;
}
}

A solution would be to add a "try/catch" mechanism :

try {
... // do the refund
}catch { //if it fails
failedTransferCredits[recipient] += amount; //credit user
}
Updates

Lead Judging Commences

cryptoghost Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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