The contract does not include a mechanism to fund the prize pool upon deployment, nor does it validate whether sufficient funds are available to pay the winner. If the first player to win the game does so when the contract balance is insufficient, the prize transfer will revert, leaving the player without their winnings. Additionally, since the withdrawal is implemented using a push-based method, the player will not be able to withdraw their winnings later, even if the contract balance becomes sufficient.
Root Cause:
The contract lacks an initial deposit or funding mechanism to establish a prize pool at deployment.
The endGame function attempts to pay winnings using the transfer method without checking if sufficient funds are available in the contract:
Symptoms:
If the first player to win does so when the contract balance is less than 2 ETH:
The transfer call reverts, and the player receives no winnings.
The player’s wager of 1 ETH may also be lost or unrefunded.
Since the transfer is a push-based method, the player cannot retry withdrawing their winnings, even if the contract is funded later.
Code Affected:
endGame Function:
Behavior Details:
Players rely on the contract’s immediate balance for payouts. If the contract lacks funds at the moment of execution, the winnings are permanently lost.
There is no fallback mechanism to handle insufficient funds or to retry failed payouts.
First Winner’s Financial Loss:
The first player to win may not receive their prize due to insufficient funds in the contract, resulting in financial loss and dissatisfaction.
Loss of Trust and Game Integrity:
Players lose trust in the game if winnings are not reliably paid out. The lack of initial funding damages the protocol’s credibility.
Operational Limitation of Push Method:
Push-based withdrawals prevent retrying payouts if funds are unavailable at the time of execution.
Manual code review.
Require Initial Funding During Deployment:
Modify the contract constructor to enforce a minimum initial funding requirement at deployment. This ensures the prize pool is pre-funded before players participate.
Example:
The owner deploying the contract must send the initial funding amount as part of the deployment transaction.
Add a Deposit Function for Prize Pool Funding:
Provide the contract owner with the ability to deposit additional funds into the prize pool dynamically to ensure ongoing liquidity.
Example:
This function allows the contract to be topped up as needed, ensuring prizes can always be paid out.
Combine Both Approaches:
Implement both initial funding and the ability to deposit additional funds to provide flexibility and maintain a sustainable prize pool:
Require sufficient funding at deployment.
Allow dynamic refills during the contract’s lifetime.
Document Funding Responsibilities:
Include clear instructions in the project documentation that:
Initial funding is required during deployment.
The contract owner must ensure the prize pool remains funded to avoid payout failures.
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.