[H-4] Users Can Join Event Multiple Times, with briVault::joinEvent() Breaking Winner Share Calculations
Description
The `briVault::joinEvent()` function does not prevent users from calling it multiple times
```solidity
function joinEvent(uint256 countryId) public {
if (stakedAsset[msg.sender] == 0) {
revert noDeposit();
}
if (countryId >= teams.length) {
revert invalidCountry();
}
if (block.timestamp > eventStartDate) {
revert eventStarted();
}
userToCountry[msg.sender] = teams[countryId];
uint256 participantShares = balanceOf(msg.sender);
userSharesToCountry[msg.sender][countryId] = participantShares;
usersAddress.push(msg.sender);
numberOfParticipants++;
totalParticipantShares += participantShares;
}
```
This allows:
1. Multiple `usersAddress[]` entries for same user
2. Inflated `numberOfParticipants` count
3. Users can change predictions without clearing old ones
4. `_getWinnerShares()` counts same user multiple times
Risk
Likelihood:
High — since joinEvent() doesn’t restrict multiple entries from the same user, exploitation is simple and likely. Users can repeatedly join to inflate their share count, directly breaking winner share calculations and skewing payouts in their favor.
Impact:
`totalWinnerShares` becomes inflated
Winner payouts get incorrectly diluted
State corruption in participant tracking
Users can manipulate their share calculations
Proof of Concept
Recommended Mitigation
- remove this code
+ add this code
Prevent multiple joins
```diff
function joinEvent(uint256 countryId) public {
if (stakedAsset[msg.sender] == 0) {
revert noDeposit();
}
// Prevent joining twice
+ if (bytes(userToCountry[msg.sender]).length > 0) {
+ revert alreadyJoined();
+ }
if (countryId >= teams.length) {
revert invalidCountry();
}
if (block.timestamp > eventStartDate) {
revert eventStarted();
}
userToCountry[msg.sender] = teams[countryId];
uint256 participantShares = balanceOf(msg.sender);
userSharesToCountry[msg.sender][countryId] = participantShares;
usersAddress.push(msg.sender);
numberOfParticipants++;
totalParticipantShares += participantShares;
emit joinedEvent(msg.sender, countryId);
}
```