The withdrawWinnings()
function is intended to allow users to securely withdraw their pending winnings. It checks that the user has a positive balance, sends them the funds, and then resets their pending winnings to zero.Explain the specific issue or problem in one or more sentences.
However, the contract first performs the external call to send ETH to the user before updating their internal balance. This exposes the contract to a reentrancy attack, especially if nonReentrant
is removed or bypassed.
Likelihood:
The issue occurs every time a player with a malicious fallback function calls withdrawWinnings()
.
Although nonReentrant
helps, good practice dictates using Checks-Effects-Interactions to avoid dependency on modifiers alone.
Impact:
An attacker could recursively withdraw winnings before their balance is reset.
May lead to draining the contract's ETH balance, affecting all honest participants.
We only audit the current code in scope. We cannot make speculation with respect to how this codebase will evolve in the future. For now there is a nonReentrant modifier which mitigates any reentrancy. CEI is a good practice, but it's not mandatory. Informational
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.