Normal behavior: After the event ends and the winner is set, winners should be able to withdraw. If no user picked the winner, there must be a clear recovery path so funds are not permanently locked (e.g., owner rescue or proportional refund to participants).
Issue: The contract allows setting a winner with no participants. The guarded withdraw() only allows addresses whose picked country matches the winner, so all calls revert with didNotWin(). There is no admin rescue or fallback refund path. As a result, all vault funds are permanently locked.
Likelihood: Medium
Occurs whenever the owner sets a winner that nobody picked (e.g., by mistake or by design).
Common in tournaments with many options.
Impact: High
All vault assets remain locked forever. Neither users nor owner can recover the tokens.
Breaks game economics and leads to permanent loss of funds.
No recovery path of the funds by the owner.
Description:
user1 joins country 7; user2 joins country 8.
Owner sets winner to country 6, which has no participants.
All withdraw() attempts revert with didNotWin()
funds are stuck, no user can claim
no recovery function for the owner to claim the funds
Prevent setting a winner with zero participants (simple, safest): after computing totalWinnerShares, require it to be > 0 and revert otherwise. The owner must pick a country that has participants.
Alternatively or additionally, add a recovery path when totalWinnerShares == 0: owner sweep to a treasury or implement proportional refunds to all participants using their shares.
Optional owner rescue when no winners (choose one policy and document it clearly):
When no one bet on the winning team, making totalWinnerShares = 0, causing division by zero in withdraw and preventing any withdrawals.
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.