The protocol expects users to first call deposit and then subsequently call joinEvent. This allows users to join a team and have their shares correctly recorded in userSharesToCountry. This mapping is later used to calculate totalWinningShares for the winning team so that vault assets can be distributed proportionally to winners based on their shares.
However, if a user deposits, joins the event, and then continues to deposit without calling joinEvent again, the additional shares from subsequent deposits will not be reflected in userSharesToCountry. As a result, when calculating totalWinningShares, the protocol will underestimate the true number of shares belonging to users on the winning team.
This allows a malicious user to withdraw more assets than their actual share, while other users that redeem later will be unable to claim their portion because the vault has been drained.
The root cause of this issue is the separation of the deposit and joinEvent logic, which leads to inconsistent accounting of participant shares.
Likelihood:
A malicious user can exploit this by depositing a minimal amount, calling joinEvent, and then making additional deposits. Since there is no restriction on depositing after joining, this situation is likely to occur, especially when users want to increase their stake before the event begins.
Impact:
The accounting for reward distribution will be incorrect, resulting in a low totalWinningShares value. Early withdrawers will receive more than they deserve, while later withdrawers may be blocked from claiming because the vault is either empty or holds too low of a balance.
Add this test to your test suite in test/briVault.t.sol.
This test shows that the malicious user (user2), who should have received 50% of the vault (10e18), actually receives 66.7% (13.33e18). When the other legitimate winner attempts to withdraw, the transaction reverts because the vault no longer holds enough tokens.
To prevent this issue, integrate the deposit and joinEvent logic. Doing so ensures that each deposit is tied to a specific team and that all shares are correctly included in team accounting.
It will also be be necessary to update the joinEvent logic to account for multiple deposits and attempts to change teams.
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.