Failing to refresh userSharesToCountry after additional deposits lets winners claim more than the vault balance, causing withdrawals to revert and effectively locking their rewards (High).
When a user joins an event, the contract snapshots their current share balance and stores it under the selected country:
If the participant later deposits more tokens, their real share balance (balanceOf(msg.sender)) increases, but userSharesToCountry[msg.sender][countryId] remains stale. When the winner is set, _getWinnerShares() computes the denominator for reward distribution using this outdated snapshot:
During withdraw(), the numerator uses the current (larger) balanceOf(msg.sender), while the denominator is based on the stale snapshot. If the discrepancy is large enough, Math.mulDiv asks the vault to transfer more tokens than it actually holds, causing the ERC20 transfer to revert:
Any honest participant who deposits again after calling joinEvent (and either cannot or does not re-join before eventStartDate) risks hitting a revert when withdrawing after their country wins. No privileged access is needed; this is a realistic loss-of-funds scenario driven by normal user behavior.
Winning users who deposit multiple times cannot withdraw their rewards.
Vault funds remain locked, breaking the payout process for affected winners.
Alice deposits 100 tokens and calls joinEvent(0).
Still before eventStartDate, she deposits another 900 tokens but does not (or cannot) call joinEvent again.
Alice’s team wins; the owner calls setWinner(0).
Alice calls withdraw(). The function attempts to transfer more tokens than exist in the vault and the transaction reverts.
Track incremental share contributions per country instead of overwriting with balanceOf(msg.sender):
Alternatively, move the per-country share accounting into deposit so each mint updates the correct bucket in real time.
Add tests covering multiple deposits between joinEvent and setWinner to ensure withdrawals remain functional.
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.