BriVault

First Flight #52
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

Duplicate entries in usersAddress array

Root + Impact

Description

  • Normal behavior:
    Each participant should only appear once in the usersAddress array to accurately track users for winner share calculations.


  • Specific issue:
    In the joinEvent() function:

  • There is no check to prevent the same address from being added multiple times.

Combined with repeated joinEvent() calls, the usersAddress array can contain duplicate addresses.

  • This impacts _getWinnerShares(), which iterates over usersAddress to calculate totalWinnerShares, potentially inflating winner shares calculations or creating double-counting errors.

// Root cause in the codebase with @> marks to highlight the relevant section
@> usersAddress.push(msg.sender);

Risk

Likelihood:

  • This occurs whenever a user calls joinEvent() multiple times, as there is no check to prevent duplicates.

This also occurs accidentally if a user interacts with the contract repeatedly due to UI errors or retries.

Impact:

  • Rewards can be incorrectly calculated, diluting payouts to legitimate participants.

Attackers can repeatedly join to manipulate totalWinnerShares or their perceived contribution.

Proof of Concept

Explanation:

  • Each call pushes msg.sender into usersAddress, inflating the array.

  • When _getWinnerShares() iterates over usersAddress, the user's shares are counted multiple times, unfairly affecting total winner shares.


contract DuplicateJoin {
function exploit(BriVault vault, uint256 countryId, uint256 times) external {
for (uint256 i = 0; i < times; i++) {
vault.joinEvent(countryId); // multiple entries for the same user
}
}
}

Recommended Mitigation

Brief explanation:

  • Introduce a mapping to track if a user has already joined the event.

  • Prevent duplicate additions to usersAddress:

  • Alternatively, use mapping(address => bool) hasJoined to guard the push.

- remove this code
+ add this code
+ require(bytes(userToCountry[msg.sender]).length == 0, "User already joined");
+ usersAddress.push(msg.sender);
Updates

Appeal created

bube Lead Judge 19 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Duplicate registration through `joinEvent`

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!