Summary
Optimizaiton, make code more readbale, save more gas
Vulnerability Details
Impact
Tools Used
Recommendations
1. Apply magic number
uint256 private constant START_TIME = 1723752000;
uint256 private constant NUM_MATCHES = 9;
uint64 private constant MATCH_DURATION = 68400;
uint64 private constant PREDICTION_DURATION = 3600;
function makePrediction(
uint256 matchNumber,
ScoreBoard.Result prediction
) public payable {
...
if (
block.timestamp >
START_TIME + matchNumber * MATCH_DURATION - PREDICTION_DURATION
) {
revert ThePredicter__PredictionsAreClosed();
}
...
}
2.module function
function checkPlayerPredictions(address player) internal returns (bool) {
return playersPredictions[player].isPaid[i] && playersPredictions[player].predictions[i] != Result.Pending
}
function getPlayerScore(address player) public view returns (int8 score) {
for (uint256 i = 0; i < NUM_MATCHES; ++i) {
if (checkPlayerPredictions(player)) {
score += playersPredictions[player].predictions[i] == results[i]
? int8(2)
: -1;
}
}
}
function setPrediction(
address player,
uint256 matchNumber,
Result result
) public {
if (block.timestamp <= START_TIME + matchNumber * MATCH_DURATION - PREDICTION_DURATION)
playersPredictions[player].predictions[matchNumber] = result;
playersPredictions[player].predictionsCount = 0;
for (uint256 i = 0; i < NUM_MATCHES; ++i) {
if (checkPlayerPredictions(player)) ++playersPredictions[player].predictionsCount;
}
}
function clearPredictionsCount(address player) public onlyThePredicter {
playersPredictions[player].predictionsCount = 0;
}
function getPlayerScore(address player) public view returns (int8 score) {
for (uint256 i = 0; i < NUM_MATCHES; ++i) {
if (checkPlayerPredictions(player)) {
score += playersPredictions[player].predictions[i] == results[i]
? int8(2)
: -1;
}
}
}
Modfiy loop format to save gas, all places which apply loop can do same adjustment.
function getPlayerScore(address player) public view returns (int8 score) {
for (uint256 i = 0; i < NUM_MATCHES; ++i) {
if (checkPlayerPredictions(player,i)) {
score += playersPredictions[player].predictions[i] == results[i]
? int8(2)
: -1;
}
}
uint256 i;
for(;i < NUM_MATCHES;){
unchecked {
if (checkPlayerPredictions(player,i)) {
score += playersPredictions[player].predictions[i] == results[i]
? int8(2)
: -1;
}
++i;
}
}
}
function checkPlayerPredictions(
address player,
uint256 matchNumber
) public returns (bool) {
require(matchNumber < NUM_MATCHES, "Invalid match number");
return
playersPredictions[player].isPaid[matchNumber] &&
playersPredictions[player].predictions[matchNumber] != Result.Pending;
}
Below judge can change to modifer
if (msg.sender != organizer) {
revert ThePredicter__UnauthorizedAccess();
}