The function setWinner() calls _getWinnerShares(), which iterates over every address in the usersAddress array to sum their shares:
If the number of users (usersAddress.length) grows significantly (e.g., thousands of participants or Sybil addresses), this loop will exceed the block gas limit, causing setWinner() to revert.
As a result, the owner will never be able to finalize the tournament, and all funds within the vault will be permanently locked — creating a Denial of Service (DoS) scenario.
Likelihood: Medium
Although not every vault will reach thousands of participants, a Sybil attacker can deliberately create many small deposits to trigger this.
The issue stems from unbounded iteration in an on-chain loop.
Impact: High
setWinner() fails permanently once the array grows too large.
This blocks the entire finalization flow — rewards cannot be distributed, and user funds remain locked indefinitely.
The impact is system-wide and irreversible without redeployment or admin intervention.
The following Foundry test demonstrates how a large usersAddress array causes setWinner() to revert due to gas exhaustion:
Run with:
Expected result:
Avoid iterating over all participants during finalization. Instead, maintain an aggregated counter of total shares per country as deposits occur.
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.