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

Wrong time calculation in `ScoreBoard::setPrediction` prevents players from calling `ThePredicter::makePrediction` for the first round

Description:

Incorrect calculation of time in the time condition of setPrediction prevents players from calling ThePredicter::makePrediction for the first round, because it calculates a time that's before the ScoreBoard::START_TIME.

Impact:

Players won't be able to make predictions for the first round, which makes them lose a point in the game.

Proof of Concept:

Proof of Code

Import the following test to ThePredicter.test.sol:

function test_wrongTimeCalculationInSetPrediction() public {
uint256 START_TIME = 1723752000; // Thu Aug 15 2024 20:00:00 GMT+0000
uint256 MATCH_NUMBER = 0;
// START_TIME - 14400 is the deadline to register
vm.warp(START_TIME - 14400); // Thu Aug 15 2024 16:00:00 GMT+0000
vm.deal(stranger, 1 ether);
vm.prank(stranger);
thePredicter.register{value: 0.04 ether}();
vm.prank(organizer);
thePredicter.approvePlayer(stranger);
uint256 oneSecondAfterDeadlineToMakePredictions = START_TIME + MATCH_NUMBER * 68400 - 68400 + 1;
console.log("One second after deadline time: ", oneSecondAfterDeadlineToMakePredictions);
console.log("Start time: ", START_TIME);
assert(START_TIME > oneSecondAfterDeadlineToMakePredictions);
// The time is set to 1723752000 + 0 * 68400 - 68400 + 1= 1723683601
// This is less than START_TIME which is 1723752000
// Therefore, the prediction for the first match isn't possible
vm.warp(oneSecondAfterDeadlineToMakePredictions);
vm.expectRevert(abi.encodeWithSelector(ThePredicter__PredictionsAreClosed.selector));
vm.prank(stranger);
thePredicter.makePrediction{value: 0.0001 ether}(0, ScoreBoard.Result.Draw);
}

Recommended Mitigation:

Make the following changes to ScoreBoard::setPrediction, to be compliant with this phrase of the documentation:

"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."

That's why we're multiplying matchNumber by 86400 (24 hours) and then adding 82800 (23 hours) to the result:

function setPrediction(address player, uint256 matchNumber, Result result) public {
- if (block.timestamp <= START_TIME + matchNumber * 68400 - 68400) {
+ if (block.timestamp <= START_TIME + matchNumber * 86400 + 82800) {
playersPredictions[player].predictions[matchNumber] = result;
Updates

Lead Judging Commences

NightHawK Lead Judge about 1 year 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.