# Game: reentrancy and bid-min logic flaw drains ETH

Game contract's makeBid had a reentrancy flaw plus a logic error in newBidEtherMin, letting an attacker repeatedly bid minimum+1 and drain ~20 ETH.

- Payout: Real-world hack
- Severity: high
- Program: Game
- Analysis by: DeFiHackLabs
- Disclosed: 2024-02-11
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2024-02/Game_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20240211-game
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:chained vuln:business-logic vuln:reentrancy

**Target:** Ethereum smart contract (Game, 0x52d6...dbd6) makeBid payable function
**Root cause:** makeBid updates/refunds state after an external ETH transfer (reentrancy), and newBidEtherMin() has a logic error allowing bids of min+1 to bypass the require check.
**Steps:**
1. Fund attack contract with 0.6 ETH.
2. Call `Game.makeBid{value: 0.49*balance}()` to become a bidder.
3. In receive(), reenter `makeBadBid()` up to 110 times.
4. makeBadBid computes `badBid = Game.newBidEtherMin() + 1` and calls `Game.makeBid{value: badBid}()`, bypassing `require(msg.value > newBidEtherMin())`.
5. Each reentrant bid triggers a refund back to the attacker's receive(), which reenters again, multiplying returns.
**How found:** Researcher noticed makeBid sends ETH before finalizing state (reentrancy surface) and that newBidEtherMin() logic allowed a min+1 bid to satisfy the require, enabling cheap reentrant bids.
**Exploitation:** Attacker places an initial large bid, then reenters makeBid via the ETH refund callback in receive(), each time bidding newBidEtherMin()+1. The refunds from prior bids are returned repeatedly during reentrancy, netting ~20 ETH profit from the contract.
**Escalation:** Recursive reentrancy loop (up to 110 calls) amplifies the refund extraction.
**Insight:** When a payable bid/auction function refunds the previous bidder via external call before updating state, check whether the minimum-bid getter can be gamed (min+1) so each reentrant call costs almost nothing while refunds compound.
