Duplicating entries in usersAddress allows a participant to inflate totalWinnerShares, shrinking every winner's withdrawal and trapping assets in the vault (Medium).
joinEvent() pushes msg.sender into usersAddress on every call without preventing duplicates. During settlement, _getWinnerShares() iterates over that array and sums userSharesToCountry[user][winnerCountryId], so the same participant contributes their shares multiple times:
A winner who (accidentally or maliciously) calls joinEvent() multiple times makes totalWinnerShares larger than the actual circulating winner shares, so every subsequent withdrawal uses an inflated denominator and pays out less than the correct pro-rata amount.
Any participant can grief all winners by repeatedly joining before eventStartDate. No privileged access is required. The attack is especially harmful when multiple winners exist, because honest winners cannot detect or mitigate the manipulation before funds are lost.
Winners receive less than their fair share of the vault assets.
Remaining assets become permanently stuck in the vault after all shares are burned.
Alice and Bob each deposit 100 tokens and join the same country before the start date.
Alice (maliciously or due to a UI bug) calls joinEvent() twice; usersAddress becomes [Alice, Alice, Bob].
After the event ends, the owner calls setWinner() with that country. _getWinnerShares() records 300 shares even though only 200 actually exist.
Bob withdraws and receives 100 * 200 / 300 ≈ 66.66 tokens. Alice then withdraws and receives the same amount. The remaining ~66.66 tokens remain trapped in the vault.
Prevent duplicate registration by ensuring each participant can only join once, for example:
Alternatively, deduplicate usersAddress or maintain a separate structure (such as a mapping plus an index array) that only records each address once.
Ensure _getWinnerShares() starts from a clean totalWinnerShares and, if possible, derive the denominator from a deduplicated set of active winner addresses.
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.