Description
Users already approved by the organizer can register and pay the entry fee again.
Impact
Users already approved can pay the entry fee again and become a user with the pendent status, not be able to play again, needing the approve of the organizer.
Proof of Concept
Add the following code to the test/ThePredicter.test.sol
:
function test_UserAlreadyApprovedCannotRegisterAgain() public {
vm.startPrank(stranger);
vm.deal(stranger, 1 ether);
thePredicter.register{value: 0.04 ether}();
assertEq(thePredicter.playersStatus(stranger) == ThePredicter.Status.Pending, true, "stranger status should be pending");
vm.startPrank(organizer);
thePredicter.approvePlayer(stranger);
assertEq(thePredicter.playersStatus(stranger) == ThePredicter.Status.Approved, true, "stranger status should be approved");
vm.startPrank(stranger);
vm.expectRevert();
thePredicter.register{value: 0.04 ether}();
assertEq(thePredicter.playersStatus(stranger) == ThePredicter.Status.Approved, true, "stranger status should keep approved");
}
Run with: forge test --match-test test_PlayersAlreadyApprovedCannotRegisterAgain -vvv
Recommend Mitigation:
Add a new error to use when an user try to register again:
error ThePredicter__IncorrectEntranceFee();
error ThePredicter__RegistrationIsOver();
error ThePredicter__IncorrectPredictionFee();
error ThePredicter__AllPlacesAreTaken();
error ThePredicter__CannotParticipateTwice();
error ThePredicter__NotEligibleForWithdraw();
error ThePredicter__PredictionsAreClosed();
error ThePredicter__UnauthorizedAccess();
+ error ThePredicter__UserAlreadyApproved();
And add the check on ThePredicter:register
:
function register() public payable {
+ if (playersStatus[msg.sender] == Status.Approved) {
+ revert ThePredicter__UserAlreadyApproved();
+ }
if (msg.value != entranceFee) {
revert ThePredicter__IncorrectEntranceFee();
}
if (block.timestamp > START_TIME - 14400) {
revert ThePredicter__RegistrationIsOver();
}
if (playersStatus[msg.sender] == Status.Pending) {
revert ThePredicter__CannotParticipateTwice();
}
playersStatus[msg.sender] = Status.Pending;
}