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;
emit joinedEvent(msg.sender, countryId);
}
function test_MultipleJoinEventInflatesShares() public {
vm.startPrank(user1);
IERC20(weth).approve(address(briVault), 10000e18);
briVault.deposit(1000e18, user1);
briVault.joinEvent(0);
briVault.joinEvent(5);
briVault.joinEvent(10);
vm.stopPrank();
uint256 userActualShares = briVault.balanceOf(user1);
uint256 totalParticipants = briVault.numberOfParticipants();
uint256 totalShares = briVault.totalParticipantShares();
console.log("User's actual shares:", userActualShares);
console.log("Total participants (should be 1):", totalParticipants);
console.log("Total shares recorded:", totalShares);
assertEq(totalParticipants, 3);
assertEq(totalShares, userActualShares * 3);
vm.prank(owner);
briVault.setWinner(10);
uint256 totalWinnerShares = briVault.totalWinnerShares();
console.log("Total winner shares (inflated):", totalWinnerShares);
assertEq(totalWinnerShares, userActualShares * 3);
+ // Tracks whether a user has already joined the event
+ mapping(address => bool) public hasJoined;
+ // Error to revert when user tries to join multiple times
+ error alreadyJoined();
function joinEvent(uint256 countryId) public {
+ // Check if user already joined
+ if (hasJoined[msg.sender]) {
+ revert alreadyJoined();
+ }
+
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;
+ // Mark user as having joined
+ hasJoined[msg.sender] = true;
emit joinedEvent(msg.sender, countryId);
}
+ // Update cancelParticipation to reset the hasJoined flag
function cancelParticipation () public {
if (block.timestamp >= eventStartDate){
revert eventStarted();
}
uint256 refundAmount = stakedAsset[msg.sender];
stakedAsset[msg.sender] = 0;
uint256 shares = balanceOf(msg.sender);
_burn(msg.sender, shares);
IERC20(asset()).safeTransfer(msg.sender, refundAmount);
+ // Allow user to join again after cancellation
+ hasJoined[msg.sender] = false;
}