In Solidity, even with a nonReentrant
modifier, it is a best practice to update contract state before making external calls, such as .call{value: amount}
. This protects against reentrancy bugs, especially if the modifier is removed, modified, or bypassed later.
In the current withdrawWinnings()
function, the contract makes an external call to msg.sender
before updating the user's pendingWinnings
balance. This creates a vulnerable structure where the control flow is handed to an external address while the internal state is not yet cleaned up.
Likelihood:
This is not exploitable with the current nonReentrant
in place.
However, it's a commonly misused pattern that opens risk during refactoring, modifier removal, inheritance override, or future multi-function interactions.
Impact:
If a future version introduces a state update after a reentrant-safe assumption is broken, a reentrancy exploit could occur.
Trust and safety assumptions of the contract's withdrawal pattern could be violated.
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.