The _getWinnerShares() function iterates through all addresses in the usersAddress array to calculate the total shares for the winning country. However, the usersAddress array grows indefinitely as users join the event, and the same user can be added multiple times through repeated calls to joinEvent(). This creates a Denial-of-Service vulnerability where the gas cost of setting the winner becomes prohibitively expensive.
Likelihood:
The usersAddress array grows with every call to joinEvent() without any duplication checks
The same user can be added multiple times by repeatedly calling the function
An attacker can spam the contract with many addresses to make the array extremely large
The owner must call setWinner() after the event ends, making this vulnerability unavoidable
Impact:
Permanent denial of service - once the array becomes too large, setWinner() will exceed block gas limits and become uncallable
Locked funds - users cannot withdraw their assets if the winner cannot be set
Bricked contract - the entire vault becomes unusable as the core functionality is disabled
Join event with same address multiple times,setWinner() becomes too expensive to call when array is large
Replace the looping calculation with a mapping that tracks total shares per country:
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.