normally, when a user calls cancelParticipation before the event starts, their participation should be completely removed from the system: their shares are burned, their staked assets are refunded, and all state variables tracking their participation should be reset to prevent them from affecting future reward calculations.
cancelParticipation function does not update key state variables (userSharesToCountry, usersAddress[], numberOfParticipants, userToCountry) that track user participation. As a result, when setWinnercalls _getWinnerShares(), it still counts cancelled users' phantom shares. This artificially inflatestotalWinnerShares`, skewing reward calculations so that legitimate winners receive less than they should and leaving part of the funds permanently locked in the contract.
Likelihood:
This vulnerability triggers every time a user who has already joined an event (called joinEvent) subsequently cancels their participation before the event starts
The impact scales linearly with the number of cancellations - each cancelled participant reduces all winners' payouts by their proportional share
Impact:
Direct financial loss for winners: Each legitimate winner receives a reduced payout proportional to the total phantom shares. If 50% of participants cancel, winners receive approximately 50% less than deserved
Permanent fund lock: The difference between what winners receive and the total vault balance remains locked forever in the contract with no recovery mechanism, as the phantom shares can never be redeemed
Add this test to test/briVault.t.sol:
POC: Proves that cancelParticipation breaks reward distribution
Instead of storing all users in an array and iterating in _getWinnerShares(), maintain a running countryToTotalShares mapping updated during joinEvent() and cancelParticipation()
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.