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);
}
Put this test in `briVault.t.sol`
<details>
<summary>POC</summary>
```javascript
function test_CancelDoesNotDecreaseParticipantsArrayOrCount() public {
vm.startPrank(owner);
briVault.setCountry(countries);
vm.stopPrank();
address[5] memory users = [user1, user2, user3, user4, user5];
uint256 amount = 10 ether;
uint256[5] memory teamsIds = [uint256(0), 1, 2, 3, 4];
for (uint256 i = 0; i < users.length; i++) {
vm.startPrank(users[i]);
mockToken.approve(address(briVault), amount);
briVault.deposit(amount, users[i]);
briVault.joinEvent(teamsIds[i]);
vm.stopPrank();
}
uint256 participantsBefore = briVault.numberOfParticipants();
uint256 arrayLenBefore = 0;
for (uint256 i = 0; ; i++) {
try briVault.usersAddress(i) returns (address addr) {
arrayLenBefore++;
} catch {
break;
}
}
vm.startPrank(user5);
briVault.cancelParticipation();
vm.stopPrank();
uint256 participantsAfter = briVault.numberOfParticipants();
uint256 arrayLenAfter = 0;
for (uint256 i = 0; ; i++) {
try briVault.usersAddress(i) returns (address addr) {
arrayLenAfter++;
} catch {
break;
}
}
assertEq(participantsBefore, participantsAfter, "numberOfParticipants changed (expected unchanged)");
assertEq(arrayLenBefore, arrayLenAfter, "usersAddress length changed (expected unchanged)");
console.log("participantsBefore:", participantsBefore);
console.log("participantsAfter :", participantsAfter);
console.log("arrayLenBefore :", arrayLenBefore);
console.log("arrayLenAfter :", arrayLenAfter);
}
```
</details>
1. Add this mapping to contract.
`mapping(address => uint256) private userIndex;`
2. Add this to `briVault::joinEvent`
`userIndex[msg.sender] = usersAddress.length;`
3. Modify `briVault::cancelParticipation`
```diff
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);
+ uint256 idx = userIndex[msg.sender];
+ uint256 lastIndex = usersAddress.length - 1;
+ if (usersAddress.length > 0 && idx < usersAddress.length) {
+ if (idx != lastIndex) {
+ address lastUser = usersAddress[lastIndex];
+ usersAddress[idx] = lastUser;
+ userIndex[lastUser] = idx;
+ }
+ usersAddress.pop();
+ }
+ delete userIndex[msg.sender];
+ if (numberOfParticipants > 0) {
+ numberOfParticipants--;
+ }
+ }
```