BriVault::joinEvent allows multiple joins; incorrect share calculation may prevent user withdrawals or cause the withdrawal amount to be less than they should get.BriVault::joinEvent allows a user to join multiple times, and calculates participantShares as balanceOf(msg.sender). As a result, when a user joins multiple events, their balance is repeatedly counted. In addition, usersAddress.push(msg.sender) causes the same user to be pushed into usersAddress multiple times, which leads to totalParticipantShares being recalculated each time and including assets from the user's previous joins.
Because userToCountry[msg.sender] is updated every time joinEvent is called, even if a user voted for the winning country, their record can be overwritten, preventing them from being able to withdraw.
The BriVault::_getWinnerShares function repeatedly counts the same user because the user is pushed into usersAddress multiple times. As a result, totalWinnerShares is calculated multiple times for the same user, causing it to exceed the actual amount.
Likelihood:
When a user joins the event multiple times, the system calculates participantShares using the total balance and pushes the user’s address into usersAddress repeatedly, causing _getWinnerShares to iterate over duplicate entries and the shares to be counted multiple times.
Impact:
Total winner shares become inflated, causing winning users to receive less on withdrawal than they should, and in some cases even less than their original deposit, leading to a loss of funds.
A user may choose the correct winner, but due to incorrect share calculations or overwritten records, they could be prevented from withdrawing their funds.
Place the following code in briVault.t.sol.
The result:
From the results, we can see that totalWinnerShares is greater than the finalized vault balance, and user2 wins but withdraws even less than their deposit.
To allow each user to join only once, use a mapping to track whether a user has already joined and revert if they try again. If multiple joins are allowed, calculate only the newly added shares each time instead of using the msg.sender balance, and avoid pushing the same user multiple times into usersAddress.
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.