When a user cancels particiaption, their deposited funds should be fully refunded, and the vault's internal accounting should reflect that the user is no loger an active participant. This means their contribution to totalParticipantShares, numberOfParticipants, and any winner-related state should be cleared, ensuring that subsequent calculations only include active participants.
However, in the current implementation of cancelParticipation(), the function only refunds the user's staked tokens and burns their vault shares but fails to update internal state variables such as totalParticipantShares, numberOfParticipants, and userSharesToCountry. As a result, the vault continuous to treat cancelled participants as active, inflating totals and corrupting winner share calculations. This leads to incorrect winner payouts and leftover funds after withdrawals.
Likelihood: High
This occurs whenever a participant cancels after calling joinEvent().
Impact: High
Cancelled participants remain counted, inflating totals and corrupting reward distribution, causing underpayment to winners and leaving unclaimed funds locked in the vault.
The following test case provides a proof of concept in which the participant who cancelled has join the winner country.
The recommended mitigation is to clean up the protocol's state properly
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.