Normal behavior:
When the tournament ends, the owner should call setWinner() to finalize results and allow winning users to withdraw. The function internally calls _getWinnerShares() to sum all winning user shares efficiently.
Issue:
The contract stores every participant’s address in usersAddress each time joinEvent() is called.
Then, _getWinnerShares() loops over all entries in this array:
Since usersAddress is unbounded, anyone can repeatedly call joinEvent() (or many addresses can join) to inflate the array indefinitely.
When the owner later calls setWinner(), the transaction may run out of gas, permanently blocking finalization and all withdrawals — a Denial of Service.
Likelihood:
Reason 1: This occurs whenever many users or a single attacker join the event multiple times, creating a large usersAddress array.
Reason 2: It also occurs naturally with high participation; gas grows linearly with array length, making setWinner() revert once array size exceeds gas limits.
Impact:
Prevents the owner from finalizing the tournament — locking all deposits and making withdrawals impossible.
Creates a permanent Denial of Service that halts the entire contract lifecycle.
An attacker can deliberately fill the usersAddress array to make setWinner() uncallable:
Deploy the vault and start registration.
Before eventStartDate, attacker repeatedly calls:
The loop in _getWinnerShares() now iterates over 10 000+ entries.
When the owner calls setWinner(), gas exceeds block limit → revert → contract frozen.
Use constant-time share aggregation instead of iterating through every participant.
Maintain a per-country total shares counter during joinEvent() and cancelParticipation().
Explanation:
Instead of calculating the winner’s total shares at the end with a for-loop, update a running counter whenever users join or leave.
This makes _getWinnerShares() O(1) instead of O(n).
The _getWinnerShares() function is intended to iterate through all users and sum their shares for the winning country, returning the total.
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.