Incomplete state cleanup when users cancel participation leads to incorrect winner share calculations and potential fund loss.
When a user cancels their participation, all related state variables should be cleared to reflect they are no longer participating in the event.
The cancelParticipation() function only resets stakedAsset[msg.sender] and burns shares, but fails to clean up critical state variables including userToCountry, userSharesToCountry, and the user's entry in usersAddress array. It also fails to decrement numberOfParticipants and totalParticipantShares.
Likelihood:
Occurs every single time a user calls cancelParticipation()
This is normal user behavior, not an edge case
State corruption accumulates with each cancellation
Impact:
_getWinnerShares() will count cancelled users' shares in calculation
totalWinnerShares becomes inflated with burned/cancelled shares
Winners receive significantly less funds than deserved
numberOfParticipants becomes permanently incorrect
User can rejoin and appear multiple times in usersAddress
Direct fund loss for legitimate winners
Here is the PoC where a user deposit some amount, join the event and cancel the event. But user amount is still counted in the shares
Here is the simple mitigation to fix this issue
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.