The contract maintains a dynamic list of all participants in usersAddress. When the winner is set, the contract computes the total winning stake:
This loop runs on-chain inside setWinner():
Since usersAddress grows without limit, a sufficiently large number of participants will push setWinner() over the block gas limit, causing it to revert permanently.
When this happens:
winner is never set,
withdraw() cannot be used by anyone,
all assets become permanently locked in the vault.
This is a Permanent Denial of Service affecting all users.
Likelihood: Medium/Low
Chances of a protocol getting users in such a massive amount ain't that easy, unless it becomes way more popular.
Even one attacker can mass-join using cheap addresses to force setWinner to revert.
Impact: High
Winner cannot be finalized.
No one can withdraw.
All funds become permanently stuck.
Protocol becomes unusable.
Add test_gasLimit to briVault.t.sol:
Run the test using the following command:
Logs:
Implement a limit on how many users can participate such that the gas limit doesn't reach to the full. And use the existing numberOfParticipants variable.
Store totalParticipantShares by country at join time:
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.