cancelParticipation() function burns a user’s vault shares and refunds their deposit, but does not clear their recorded userSharesToCountry entry, this causes legitimate winners to receive a smaller payout than they deserve.When a participant cancels before the event starts, their deposited stake is refunded and their ERC4626 shares are burned. However, the user’s recorded participation data (userSharesToCountry and usersAddress) is not cleared or updated.
Later, during setWinner(), the contract calls _getWinnerShares() which aggregates all users’ shares from userSharesToCountry to compute totalWinnerShares. Because canceled users remain in this mapping with their old share values, their “ghost shares” are still included in the total. This artificially inflates the denominator used in the withdraw() payout calculation, reducing the payout for legitimate winners and leaving residual assets stranded in the vault.
Likelihood:
Any normal user cancelling their participation triggers the condition. No special privileges or attack sequence are needed.
Impact:
Incorrect accounting leads to:
Miscalculated totalWinnerShares
Reduced withdrawals for valid winners
Permanent funds are locked in the vault
The bug directly undermines the fairness and correctness of the reward distribution mechanism.
Add the following code to briVault.t.sol
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.