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

Misaligned Prediction Deadlines and Silent Prediction Failures in ScoreBoard Contract

Summary

The ScoreBoard::setPrediction function contains two issues related to prediction deadlines: an incorrect implementation of the match schedule and an unnecessary deadline check that could lead to silent failures in setting predictions.

Vulnerability Details

First: Incorrect Prediction Deadline Implementation: The current implementation in ScoreBoard.sol uses an incorrect calculation for prediction deadlines:

if (block.timestamp <= START_TIME + matchNumber * 68400 - 68400)

This creates a window of approximately 19 hours between each match, which doesn't align with the intended daily match schedule and prediction deadlines as specified in the README.md:

"The start of the tournament is set to Thu Aug 15 2024 20:00:00 UTC. A total of 9 matches will be played."

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

Second: Redundant and Potentially Conflicting Deadline Check:

The Conflicting Deadline Check issue arises from having two separate timestamp checks in different contracts for the same prediction deadline.

In ThePredicter.sol, we have:

if (block.timestamp > START_TIME + matchNumber * 68400 - 68400) {
revert ThePredicter__PredictionsAreClosed();
}

While in ScoreBoard.sol, we have:

if (block.timestamp <= START_TIME + matchNumber * 68400 - 68400)
playersPredictions[player].predictions[matchNumber] = result;

These checks are not only redundant but can lead to a vulnerability:

  1. A user calls ThePredicter::makePrediction function just before the deadline.

  2. The transaction passes the first deadline check.

  3. However, before the ScoreBoard::setPrediction function is executed, a malicious actor could:

    1. Front-run the transaction with a high-gas-price transaction that takes just enough time to push the block.timestamp over the deadline.

    2. Or, if the malicious actor is a miner, they could manipulate the block timestamp slightly.

  4. Now, when ScoreBoard::setPrediction is called, the second deadline check fails

  5. As a result, the prediction result is not set, even though the user called makePrediction in time.

Impact

  1. The incorrect deadline implementation results in misaligned prediction windows, potentially allowing predictions after matches have started or preventing valid predictions.

  2. The ineffective deadline check in setPrediction could cause predictions to silently fail, leading to a mismatch between a user's intended prediction and the actual stored prediction.

Tools Used

Manual review

Recommendations

Remove the deadline check from the ScoreBoard::setPrediction function, relying on the check in ThePredicter::makePrediction function instead.
And set ScoreBoard::setPredictionfunction as internal or add the modifier onlyThePredicter to make sure only predicted can call this function.

Updates

Lead Judging Commences

NightHawK Lead Judge 11 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.