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

Predictions close earlier than expected leaving some players unable to make predictions

Summary

According to the readme, predictions should close one hour before each game starts. The implementation does not match this description. The formula for calculating the closing time is incorrect. Here is the formula block.timestamp > START_TIME + matchNumber * 68400 - 68400. 68400 is 19 hours instead of the expected 1 hour which results in predictions closing 19 hours before the game starts i.e. at 1:00 AM instead of 7:00 PM. This formula is used in two functions ThePredicter::makePrediction and ScoreBoard::setPrediction.

Excerpt from the README.md:

Every day from 20:00:00 UTC one match is played. Until 19:00:00 UTC on the day of the match, predictions can be made by any approved Player. Players pay prediction fee when making their first prediction for each match.

Vulnerability Details

The test should pass because the prediction for the first game is placed exactly 1 hour before the match starts.

Place the following test in the ThePredicter.test.sol file:

function testPredictionsCloseEarlierThanExpected() public {
uint256 START_TIME = 1723752000; // Thu Aug 15 2024 20:00:00 GMT+0000
// According to the readme, predictions close one hour before the tournament starts (for the first match)
uint256 PREDICTIONS_CLOSE_TIME = START_TIME - 1 hours;
hoax(stranger);
thePredicter.register{value: 0.04 ether}();
vm.prank(organizer);
thePredicter.approvePlayer(stranger);
// Set time to one hour before tournament start time: Thu Aug 15 2024 19:00:00 GMT+0000
vm.warp(PREDICTIONS_CLOSE_TIME);
vm.prank(stranger);
// The call reverts despite the time being within the expected prediction time
thePredicter.makePrediction{value: 0.0001 ether}(
0,
ScoreBoard.Result.First
);
}

Impact

Players placing their bets within 19 hours before the game starts will be unable to make predictions. Player's chances
of winning the tournament will be reduced when they cannot place bets.

Tools Used

Manual review and unit testing.

Recommendations

Remove the magic number a replace them with constants to make the closing time formula more readable.

+ uint256 public constant PREDICTION_CLOSE_TIME = 1 hours;
.
.
.
function makePrediction(
uint256 matchNumber,
ScoreBoard.Result prediction
) public payable {
if (msg.value != predictionFee) {
revert ThePredicter__IncorrectPredictionFee();
}
- if (block.timestamp > START_TIME + matchNumber * 68400 - 68400) {
+ if (block.timestamp > START_TIME + matchNumber * PREDICTION_CLOSE_TIME - PREDICTION_CLOSE_TIME) {
revert ThePredicter__PredictionsAreClosed();
}
scoreBoard.confirmPredictionPayment(msg.sender, matchNumber);
scoreBoard.setPrediction(msg.sender, matchNumber, prediction);
}
Updates

Lead Judging Commences

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

Match timestamps are incorrect

In both contracts there is a similar error in the computation of the timestamps of the matches.

Support

FAQs

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