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

[M-1] Players can't withdraw their rewards if they make a single prediction.

Summary

Players are not ilegible for reward according to Scorboard::isEligibleForReward() unless they make at least TWO predictions instead of ONE.

Vulnerability Details

According to Scorboard::isEligibleForReward(), players are not ilegible for a reward if they make a single prediction only, which makes them unable to withdraw their rewards even if thy are correct ones.

function isEligibleForReward(address player) public view returns (bool) {
return
results[NUM_MATCHES - 1] != Result.Pending &&
@> playersPredictions[player].predictionsCount > 1;
}
PoC

Add the following to ThePrediter.test.sol test file:

function test_rewardEligibility() public {
// 1. Give stranger some funds
vm.startPrank(stranger);
vm.deal(stranger, 1 ether);
thePredicter.register{value: 0.04 ether}();
vm.stopPrank();
// 2. The organizer approves the player
vm.startPrank(organizer);
thePredicter.approvePlayer(stranger);
// 3. The organizer sets the results for match 0
scoreBoard.setResult(0, ScoreBoard.Result.Draw);
vm.stopPrank();
// 4. "stranger" makes a prediction
vm.warp(2);
vm.startPrank(stranger);
thePredicter.makePrediction{value: 0.0001 ether}(
0,
ScoreBoard.Result.Draw
);
vm.stopPrank();
// 5. Check that "stranger" score is equal to 2 (1 correct prediction)
assertEq(scoreBoard.getPlayerScore(stranger), 2);
// 6. Withdraw reward => expect revert
vm.expectRevert(
abi.encodeWithSelector(
ThePredicter__NotEligibleForWithdraw.selector
)
);
vm.startPrank(stranger);
thePredicter.withdraw();
vm.stopPrank();
// 7. check failure of reward withdrawal
// Intial balance: 1 ether
// Entrance fee: 0.04
// Prediction fee: 0.0001
// Reward: 0.04
assertEq(stranger.balance, 0.9599 ether);
}

The test above proves that the player doesn't get any rewards for their correct prediction.

Impact

  1. Players Cannot Withdraw Rewards: Players are unable to withdraw their rightfully earned rewards. This represents a critical failure in the contract's primary function of distributing rewards to successful predictors.

  2. Forced Additional Participation: Players are obliged to make a second prediction to access their rewards. This requirement:

  • Forces unwanted participation, potentially against the player's wishes or strategy.

  • Increases the financial burden on players, as they may need to pay additional fees for predictions.

  • Could lead to players making rushed or ill-considered predictions just to access their existing rewards.

Tools Used

  • Manual review.

  • Foundry (for running test cases)

Recommendations

Fix the ilgiblity condition in Scorboard::isEligibleForReward() as follows:

function isEligibleForReward(address player) public view returns (bool) {
return
results[NUM_MATCHES - 1] != Result.Pending &&
- playersPredictions[player].predictionsCount > 1;
+ playersPredictions[player].predictionsCount > 0;
}
Updates

Lead Judging Commences

NightHawK Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

The eligibility criteria is wrong

Players with only one prediction cannot withdraw.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.