When users call cancelParticipation() after joining an event, the function refunds their deposit but fails to clean up their joinEvent state, leaving stale data that corrupts winner calculations.
Normal behavior expects that when a user cancels participation, all their event-related state should be reset including their team selection, participant count, and share tracking. The user should be completely removed from the event.
The current implementation only clears stakedAsset and burns shares, but leaves all joinEvent state intact including userToCountry, userSharesToCountry, presence in usersAddress[], and numberOfParticipants count.
Likelihood:
Users who want to withdraw their funds before event starts will naturally use this function
No warnings or documentation about the state corruption
Common user flow to change mind about participation
Impact:
User remains in usersAddress[] array, causing _getWinnerShares() to iterate over them
If user's team wins, totalWinnerShares incorrectly includes their phantom shares (now zero)
numberOfParticipants inflated, misrepresenting actual participant count
userToCountry[user] remains set, indicating they're still in event
totalParticipantShares not adjusted, creating accounting mismatch
Winner calculations become incorrect, affecting all winner payouts
Gas wasted iterating over cancelled users in setWinner()
Could cause division errors if all winners cancel but system thinks they exist
Alternative Better Design:
CancelParticipation burns shares but leaves the address inside usersAddress and keeps userSharesToCountry populated.
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.