The cancelGame
function is vulnerable to a reentrancy attack, allowing a malicious playerA
to repeatedly call cancelGame
during ETH refunds in _cancelGame
. Since the game state remains GameState.Created
after playerB
joins, playerA
can drain the contract's ETH, including playerB
's bet, before playerB
receives a refund.
The cancelGame
function calls _cancelGame
, which transfers ETH to playerA
via .call
. Without a reentrancy guard, a malicious playerA
can reenter cancelGame
during the transfer. The state remains GameState.Created
after playerB
joins, allowing playerA
to cancel the game and exploit reentrancy to siphon multiple refunds, including playerB
's funds.
Vulnerable Code:
Attack Scenario:
Malicious playerA
creates a game with an ETH bet.
playerB
joins, state stays GameState.Created
.
playerA
calls cancelGame
, triggering _cancelGame
.
During playerA
's ETH refund, their receive
function reenters cancelGame
, draining additional ETH, including playerB
's bet.
playerB
receives no refund as the contract’s funds are depleted.
Financial Loss: playerA
can steal playerB
's bet and other contract funds via multiple refunds.
Reputation Damage: Exploits undermine contract trust.
Manual code review
Foundry for exploit simulation
Custom ReentrancyAttack
contract
Add Reentrancy Guard:
Use OpenZeppelin’s ReentrancyGuard
with nonReentrant
on cancelGame
.
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.