The contract uses payable(address).call{value: amount}("") to transfer ETH to user-controlled addresses in withdrawWinnings() and withdrawPlatformFees().
If the target address is not an Externally Owned Account (EOA) but a contract, the low-level call will invoke the contract’s fallback() or receive() function, which may contain malicious logic such as re-entrancy.
Likelihood:High
These functions allow sending ETH to arbitrary addresses without checking whether the recipient is a contract.
When the recipient is a contract, the fallback or receive function is triggered, allowing it to perform arbitrary logic, including re-entrant calls.
Impact:High
Can cause the re-entrant issue(etc. take away all the ether of the Game contract).
It could also cause cross-function re-entrancy, bypassing access control or logic assumptions elsewhere in the contract.
Note: While nonReentrant provides protection against direct re-entrancy in the current context, relying solely on modifiers is not always sufficient.
For example, if future changes introduce internal calls, delegatecalls, or access through another entry point, the low-level call may still become a reentrancy vector.
In addition, the fallback or receive function of the recipient may contain side effects that interfere with contract logic or gas usage, even without reentrancy.
A malicious contract can exploit the low-level call as follows:
In this example, when the Game contract sends ETH to the malicious contract, it triggers the fallback function, which re-enters the vulnerable withdrawWinnings() logic before the previous withdrawal finalizes.
Option 1: Use transfer() or send() instead of call
These have fixed gas stipends and are safer for simple transfers (but less flexible).
Note: transfer() reverts on failure, while send() returns false.
Option 2: Validate recipient is an EOA before sending ETH
Use extcodesize to detect whether the address is a contract:
The only party affected is the "attacker". Info at best.
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.