Under normal operation, each participant is expected to join the event once, associating their deposited shares with a single country. At the end of the event, the contract aggregates total winning shares to distribute rewards fairly among participants who selected the winning country.
The issue is that joinEvent() allows users to call it multiple times, pushing their address repeatedly into usersAddress and incrementing counters each time. _getWinnerShares() then iterates over this array and adds each user’s shares to totalWinnerShares without resetting or checking for duplicates. This causes share double-counting, inflated totals, distorted payouts, and potential denial of service.
Likelihood:
Users can repeatedly call joinEvent() before the event starts, since there is no guard against multiple joins.
The owner must call setWinner() at the end of the event, which triggers _getWinnerShares(). This function loops through all entries in usersAddress, meaning any user can cause the total computation or gas cost to explode.
Impact:
Double-counting of shares inflates totalWinnerShares, causing incorrect withdrawal payouts (winners receive less per share).
Excessive entries in usersAddress can cause out-of-gas denial of service when calling setWinner(), preventing event finalization and locking user funds.
Explanation:
Since _getWinnerShares() sums shares for every entry in usersAddress, the attacker’s balance is added multiple times. Because withdrawal amount is computed as assetToWithdraw = shares * vaultAsset / totalWinnerShares, the inflated denominator reduces everyone’s payout, even though the attacker’s actual share count did not increase.
revent duplicate joins by enforcing a one-time participation per user or per country. Track join state in joinEvent() and update _getWinnerShares() to reset totalWinnerShares before aggregation.
Functions updated: joinEvent, _getWinnerShares
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.