Normally, users deposit tokens and join a tournament event once, selecting a team. After the tournament ends, winners share the vault proportionally to their deposited shares.
The specific issue is that joinEvent() allows users to call it multiple times. Each call pushes the user’s address into the usersAddress array, which _getWinnerShares() later iterates over. This inflates totalWinnerShares, reducing payouts to honest participants and causing unfair distribution.
Likelihood:
Any tournament participant can call joinEvent() multiple times with minimal technical skill.
The contract does not enforce a single-entry restriction, so multiple calls will always succeed until the event starts.
Impact:
Honest participants receive less than their fair share of the vault, resulting in economic loss.
Attackers can dilute the prize pool, manipulating payouts and breaking tournament integrity.
Explanation: Each repeated call to joinEvent() adds the attacker’s address to usersAddress. When the contract calculates totalWinnerShares, the attacker is counted multiple times, artificially inflating the total and reducing the share of legitimate winners.
Explanation: By tracking whether a user has already joined, the contract ensures that each participant can only join once. This prevents manipulation of usersAddress and ensures fair payout calculations. Adding nonReentrant protects withdrawals from malicious ERC20 token callbacks.
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.