cancelParticipation() function only resets stakedAsset[msg.sender] and burns the user’s ERC4626 shares. It does not clear other state variables modified during joinEvent(), such as userToCountry, userSharesToCountry, usersAddress numberOfParticipants and totalParticipantShares counters.When a user cancels participation, the contract should fully remove the user from all participation-related state (staked amount, assigned country, per-country shares, and their presence in the participant list) so they are excluded from any later calculations (e.g., winner-share aggregation).
cancelParticipation() only clears stakedAsset and burns the caller’s shares, but it does not clear participation mappings (userToCountry, userSharesToCountry, usersAddress, numberOfParticipants, totalParticipantShares), so cancelled participants remain counted in later winner-share calculations — resulting in incorrect totals and misallocated payouts.
Likelihood:
cancelParticipation() is a normal user operation and the cleanup omission is easy to trigger.
Any user who calls cancelParticipation() will create the problematic state; realistic in normal usage or tests.
Impact:
Incorrect accounting in winner-share aggregation.
Cancelled participants remain counted, inflating totalWinnerShares for the winning country.
Can cause incorrect reward calculations (over- or under-allocation), wrong payouts, or withdrawal logic breakage.
As the test shows after the cancellation by user2 the winner amount is 3940000000000000000
After cancellation by winner amount should be 1970000000000000000
Just clear all the mappings and rduce the variables
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.