Root Cause: No transfer or accounting for the dethroned king’s share on each new claim -> Impact: Early participants never recoup their stake until end, breaking expected pay-out flow and enabling griefing.
The claimThrone() function fails to distribute any payout to the previous king when a new claimant usurps the throne. Instead, it simply:
Collects the full msg.value.
Deducts a platform fee.
Adds the remainder entirely to the pot.
Updates currentKing and related state.
Because previousKingPayout is declared but never used, dethroned players receive zero immediate compensation and must wait until game end (via declareWinner()) to recover their funds plus the pot. This is likely contrary to the intended design—each dethronement should pay out the outgoing king a portion of the stake. Omitting this logic:
Locks up user funds in the pot.
Forces all but the final winner to endure unbounded delay before recovering their stake.
Exposes the game to griefers who can repeatedly claim with minimal increments, ballooning the pot and withholding payouts.
Affected Function: Game.sol::claimThrone()
Likelihood: High
The local variable previousKingPayout is initialized to 0 and never updated.
No code pays or credits the outgoing currentKing.
All incoming ETH beyond the platform fee goes into pot, not to the dethroned player.
Impact: High
Fund Lockup: Dethroned players’ ETH remains inaccessible until very late (end of game), harming UX and introducing unnecessary risk.
Liquidity Risk: Early participants lose liquidity; they cannot reuse or withdraw their stake in a timely manner.
Griefing Potential: Attackers can repeatedly dethrone with minimal increments-each time withholding payouts-and force players into a “hold until ruin” scenario.
Economic Disincentive: Rational players may avoid participation if payouts are uncertain or excessively delayed.
Real-World Parallel: In the Fomo3D game, a similar design led to massive pot growth and delayed payouts-culminating in a single winner taking ~$2.1 M after days of lockup and speculation.
Tools Used:
Foundry Test Suite
Chat-GPT AI Assistance (Report Grammar Check & Improvements)
Manual Review
Step-by-step:
Open test/Game.t.sol.
Paste the above test function.
Run:
Observe that Player1 never receives compensation after being replaced.
Scenario:
Player1 pays the initial claimFee (e.g., 1 ETH) to become king.
Player2 pays the next, higher claimFee (e.g., 1.1 ETH) to dethrone Player1.
Expected: Player1 should immediately receive at least their original 1 ETH (or some share).
Actual: Player1’s balance or pendingWinnings[player1] remains zero.
Repeated dethronements exacerbate this: early participants have funds tied up with no interim liquidity.
Implement Previous-King Payout Logic:
Before deducting platform fees, calculate and transfer (or credit) the outgoing king’s share:
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.