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

Wrong time calculation closes predictions too early

Summary

Wrong time calculation closes predictions too early

Vulnerability Details

ThePredicter::makePredicter uses wrong formula for calculating when to close predictions.

START_TIME + matchNumber * 68400 - 68400

68400 seconds is 19 hours so predictions will close too early. Substracting this value in second part of formula is also wrong. According to this - predictions for first match will end "Thu Aug 15 2024 1:00:00 GMT+0000" it is 19 hours before start of the tournament.

Same wrong calculations also occurs in ScoreBoard::setPrediction.

Proof Of Concept

Documentation is not clear whether first match starts the same day as tournament or the day after. I assumed that it's the first option

Copy this test to ThePredicter.test.sol

function test_timeCalculation() public{
vm.deal(stranger, 1 ether);
vm.startPrank(stranger);
thePredicter.register{value: thePredicter.entranceFee()}();
uint256 startTime = 1723752000; // Thu Aug 15 2024 20:00:00 GMT+0000
uint256 matchNumber = 1; //second match
vm.warp(startTime + 22 hours); // Thu Aug 16 2024 18:00:00 GMT+0000 - one hour before prediction for second match ends,
// we should be able to make prediction
thePredicter.makePrediction{value: 0.0001 ether}(
matchNumber,
ScoreBoard.Result.Draw
);
}

Run command forge test --mt test_timeCalculation -vvv

We should be able to make prediction but this test will fail and revert with ThePredicter__PredictionsAreClosed() error

Impact

High, predictions are closed too early

Tools Used

Manual review

Recommendations

If first match starts the same day as tournament the proper formula will be

START_TIME + matchNumber * 86400 - 3600

So change this in both functions

ThePredictor.sol

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

ScoreBoard.sol

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