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

Anyone can change player-predicted results after they set it once

[H-01] Anyone can change player-predicted results after they set it once

Summary

Players can pay for their prediction fee for each game and set their predictions using ThePredicter::makePrediction, but after that any one can just call the ScoreBoard::setPredictions to change the prediction set by players because it lacks access control.

Vulnerability Details

the setPredction function is created to allow players change their predictions, but since it lacks access control anyone can change the players predictions if they have payed for it beforehand.

function setPrediction(
address player,
uint256 matchNumber,
Result result
) public {
if (block.timestamp <= START_TIME + matchNumber * 68400 - 68400)
playersPredictions[player].predictions[matchNumber] = result;
playersPredictions[player].predictionsCount = 0;
for (uint256 i = 0; i < NUM_MATCHES; ++i) {
if (
playersPredictions[player].predictions[i] != Result.Pending &&
playersPredictions[player].isPaid[i]
) ++playersPredictions[player].predictionsCount;
}
}

Impact

A malicouse player/user can change others predictions and make themself the winner.

Proof of Concept

Add the following test to the exsiting test suit.

function test_ScoreCanBeChangedByAnyone() public {
vm.startPrank(stranger);
vm.deal(stranger, 0.0003 ether);
vm.stopPrank();
vm.warp(2);
vm.startPrank(organizer);
scoreBoard.setResult(0, ScoreBoard.Result.First);
vm.stopPrank();
vm.startPrank(stranger);
thePredicter.makePrediction{value: 0.0001 ether}(
0,
ScoreBoard.Result.First
);
vm.stopPrank();
ScoreBoard.Result result = scoreBoard.getPlayerResultForGame(
stranger,
0
);
assert(result == ScoreBoard.Result.First);
vm.prank(address(123)); // any address can DO it!!!
scoreBoard.setPrediction(stranger, 0, ScoreBoard.Result.Second);
result = scoreBoard.getPlayerResultForGame(stranger, 0);
assert(result == ScoreBoard.Result.Second);
}

Tools Used

Manual Reivew

Recommendations

Add access control so that only the msg.sender can change their own predictions not others.

function setPrediction(
address player,
uint256 matchNumber,
Result result
) public {
+ if (msg.sender != player) revert();
if (block.timestamp <= START_TIME + matchNumber * 68400 - 68400)
playersPredictions[player].predictions[matchNumber] = result;
playersPredictions[player].predictionsCount = 0;
for (uint256 i = 0; i < NUM_MATCHES; ++i) {
if (
playersPredictions[player].predictions[i] != Result.Pending &&
playersPredictions[player].isPaid[i]
) ++playersPredictions[player].predictionsCount;
}
}
Updates

Lead Judging Commences

NightHawK Lead Judge 11 months ago
Submission Judgement Published
Validated
Assigned finding tags:

setPrediction lacks access control

setPrediction has no access control and allows manipulation to Players' predictions.

Support

FAQs

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