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

Incorrect Time Calculation for Prediction

Summary

ThePredicter.sol::makePrediction()and ScoreBoard.sol::SetPrediction()Calculate the wrong maximum time to submit a prediction for the respective match.

Vulnerability Details

The function lies in both smart contracts, which are ThePredicter.sol::makePrediction()and ScoreBoard::SetPrediction()has the wrong calculation for the maximum limit for submitting a prediction. In the documentation, it stated that

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.

This means the time limit should be limit <= UTC 19:00:00, the calculation on both smart contracts use

block.timestamp <= START_TIME + matchNumber * 68400 - 68400

This is wrong since 1 day in epoch time equals to 86,400and not 68,400. Using only 86,400is also not sufficient, since the maximum time for submitting a prediction is on 19:00 UTC not 20.00 UTC, so the correct calculation is

block.timestamp <= START_TIME + matchNumber * 86400 - 86400 - 3600
// START_TIME + (MatchNumber * 86400) <- Day number X
// - 86400 <- Minus 1 day
// - 3600 <- Minus 1 Hour

Impact

The Prediction for the match after day 1, has a shorter submission limit which starts from few hours earlier (match 2 is 5 hours earlier) to a day earlier (like match 9)

Tools Used

  • Manual Analysis

  • Remix

Recommendations

Change the Time Limist Check on both smart contract into this.

ThePredicter.sol::makePrediction()

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

ScoreBoard.sol::SetPrediction()

function setPrediction(
address player,
uint256 matchNumber,
Result result
) public {
- if (block.timestamp <= START_TIME + matchNumber * 68400 - 68400)
+ if (block.timestamp <= START_TIME + matchNumber * 86400 - 86400 - 3600)
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 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.