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

Incorrect timing for when predictions are closed for 9 games

Summary

The makePrediction function in the ThePredicter contract contains a bug in calculating the prediction deadline. The function incorrectly uses 68400 seconds (19 hours) to determine the cutoff time for predictions. This miscalculation results in inaccurate timing for the remaining 8 matches, allowing users to submit predictions after the prediction period has ended and potentially even during the match itself. This undermines the integrity of the prediction system and can lead to unfair advantages and distorted outcomes.

Vulnerability Details

https://github.com/Cyfrin/2024-07-the-predicter/blob/839bfa56fe0066e7f5610197a6b670c26a4c0879/src/ThePredicter.sol#L93

The function uses 68400 seconds to calculate the prediction deadline, which results in incorrect timing. The problem arises because 68400 seconds does not accurately represent the time from one match to the next, nor does it correctly set the prediction deadline to 19:00:00 UTC on match days. This miscalculation means that predictions might be closed at unintended times, causing disruptions in the prediction process.

Below is the test script using Foundry to show that a player can place a prediction after the prediction deadline

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "forge-std/Test.sol";
import "../src/ThePredicter.sol";
import "../src/ScoreBoard.sol";
contract ThePredicterTest is Test {
ThePredicter public thePredicter;
ScoreBoard public scoreBoard;
address public owner = address(1);
address public player = address(2);
uint256 public predictionFee = 0.01 ether;
uint256 public entranceFee = 0.04 ether;
uint256 public START_TIME = 1723740000; // Example START_TIME: August 15, 2024, 20:00:00 UTC
function setUp() public {
vm.deal(owner, 1 ether);
vm.deal(player, 1 ether);
vm.startPrank(owner);
scoreBoard = new ScoreBoard();
thePredicter = new ThePredicter(entranceFee, predictionFee, START_TIME, address(scoreBoard));
vm.stopPrank();
}
function testPredictionAfterDeadline() public {
vm.startPrank(player);
// Advance time to after the prediction deadline for matchNumber 0
vm.warp(START_TIME + 68400); // 68400 seconds after START_TIME (19 hours)
// Ensure player can still make a prediction after the deadline
vm.expectRevert(ThePredicter__PredictionsAreClosed.selector);
thePredicter.makePrediction{value: predictionFee}(0, ScoreBoard.Result.Win);
vm.stopPrank();
}
}

Impact

Predictions may be closed at unintended times, disrupting the prediction process.

Tools Used

manual review

Foundry

Recommendations

Use 86400 seconds (24 hours) to move the time forward by a day for each match and subtract 3600 seconds (1 hour) to set the deadline to 19:00:00 UTC.

if (block.timestamp > START_TIME + matchNumber * 86400 - 3600) {
revert ThePredicter__PredictionsAreClosed();
}
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.