Bid Beasts

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

[M-04] Integer overflow in bid calculations allows extreme bid amounts

Root + Impact

Description

The withdrawAllFailedCredits function should follow the check-effect-interact pattern to prevent reentrancy attacks. This ensures atomic operations and prevents malicious contracts from manipulating state during external calls.

The specific issue is that the function makes an external ETH transfer call before updating the contract state, creating a potential reentrancy vulnerability where malicious contracts could re-enter the function during the external call while state is inconsistent.

// Root cause in the codebase
function withdrawAllFailedCredits(address _receiver) external {
uint256 amount = failedTransferCredits[_receiver];
require(amount > 0, "No credits to withdraw");
failedTransferCredits[_receiver] = 0; // @> State update after external call (wrong order)
(bool success, ) = payable(msg.sender).call{value: amount}(""); // @> External call before state update
require(success, "Withdraw failed");
}

Risk

Likelihood:

  • Reentrancy attacks require malicious contracts to be deployed

  • Any user can trigger the reentrancy pattern by calling with malicious contracts

  • Requires specific conditions but is technically exploitable

Impact:

  • Potential state manipulation during external calls

  • Violation of security best practices (check-effect-interact)

  • Could lead to more complex attack vectors when combined with other vulnerabilities

  • Risk of double-spending or state corruption scenarios

Proof of Concept

Maximum uint256 values can be submitted without bounds checking:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {Test} from "forge-std/Test.sol";
import {BidBeastsNFTMarketPlace} from "../src/BidBeastsNFTMarketPlace.sol";
contract OverflowTest is Test {
BidBeastsNFTMarketPlace marketplace;
function testExtremeBid() public {
uint256 maxBid = type(uint256).max;
marketplace.placeBid{value: maxBid}(1);
// Results in UI display issues and potential calculation errors
}
}

Recommended Mitigation

Add reasonable upper bounds to prevent extreme edge cases.

function placeBid(uint256 tokenId) external payable {
require(msg.value > 0, "Bid must be greater than 0");
+ require(msg.value <= 10000 ether, "Bid amount too large");
uint256 currentBid = auction.highestBid;
require(msg.value > currentBid, "Bid must be higher");
auction.highestBid = msg.value;
}
Updates

Lead Judging Commences

cryptoghost Lead Judge 2 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!