BriVault

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

Users Can Change Country Multiple Times

Root + Impact

Users can call joinEvent() multiple times to change countries and inflate counters.

Description

  • Users should select one country for the entire tournament.

  • No check prevents calling joinEvent() multiple times with different countries.

function joinEvent(uint256 countryId) public {
// No check if already joined
userToCountry[msg.sender] = teams[countryId]; // @> Overwrites
userSharesToCountry[msg.sender][countryId] = participantShares; // @> New mapping
usersAddress.push(msg.sender); // @> Duplicate
numberOfParticipants++; // @> Inflates
totalParticipantShares += participantShares; // @> Inflates
}

Risk

Likelihood:

  • Users can call repeatedly before event starts

  • No restriction on country changes

  • Trivial to exploit

Impact:

  • numberOfParticipants counts same user multiple times

  • totalParticipantShares becomes inflated

  • usersAddress filled with duplicates

  • Previous country shares orphaned

  • Unfair gaming advantage

Proof of Concept

Here is a PoC of calling joinEvent() multiple times by single user and how states behaves

user.deposit(1000, user);
user.joinEvent(0); // numberOfParticipants = 1
user.joinEvent(5); // numberOfParticipants = 2 (should be 1!)
user.joinEvent(10); // numberOfParticipants = 3 (should be 1!)
// usersAddress = [user, user, user]
// userSharesToCountry[user][0] = shares (orphaned)
// userSharesToCountry[user][5] = shares (orphaned)
// userSharesToCountry[user][10] = shares (current)

Recommended Mitigation

To solve this issue, need to add a new mapping state hasJoinedEvent and will add user record once he joined the event

+ mapping(address => bool) public hasJoinedEvent;
function joinEvent(uint256 countryId) public {
if (stakedAsset[msg.sender] == 0) {
revert noDeposit();
}
+ if (hasJoinedEvent[msg.sender]) {
+ revert("Already joined");
+ }
userToCountry[msg.sender] = teams[countryId];
uint256 participantShares = balanceOf(msg.sender);
userSharesToCountry[msg.sender][countryId] = participantShares;
usersAddress.push(msg.sender);
+ hasJoinedEvent[msg.sender] = true;
numberOfParticipants++;
totalParticipantShares += participantShares;
}
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!