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

Player cant change prediction without sending the predictionFee again

Summary

as stated in the documentation that no second prediction fee is due if any Player desires to change an already paid prediction but actually player can only change their prediction by paying again.

Vulnerability Details

the problem occur because the makePrediction always checks wheter the msg.value equal to prediction fee. and to change predictions, player can only do this by calling the function.

ThePredicter.sol:

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();
}
scoreBoard.confirmPredictionPayment(msg.sender, matchNumber);
scoreBoard.setPrediction(msg.sender, matchNumber, prediction);
}
POC

add the following code to ThePredicter.test.sol:

function test_POCChangePredictionAfterPayingFees() public {
vm.startPrank(stranger);
vm.warp(1);
vm.deal(stranger, 1 ether);
thePredicter.register{value: 0.04 ether}();
vm.stopPrank();
vm.startPrank(organizer);
vm.warp(2);
thePredicter.approvePlayer(stranger);
vm.stopPrank();
vm.startPrank(stranger);
thePredicter.makePrediction{value: 0.0001 ether}(0, ScoreBoard.Result.Draw);
vm.expectRevert(abi.encodeWithSelector(ThePredicter__IncorrectPredictionFee.selector));
thePredicter.makePrediction(0, ScoreBoard.Result.First);
vm.stopPrank();
}

then run the command forge test --mt test_POCChangePredictionAfterPayingFees
the result should PASS, indicating the call revert using ThePredicter__IncorrectPredictionFee

Ran 1 test for test/ThePredicter.test.sol:ThePredicterTest
[PASS] test_POCChangePredictionAfterPayingFees() (gas: 188072)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 925.20µs (142.78µs CPU time)

Impact

the protocol are not working as documented, making players pay again if they want to change prediction.

Tools Used

foundry

Recommendations

add a way to checks whether the player already paid or not before checking the msg.value:

ThePredicter.sol:

contract ThePredicter {
.
.
.
address public organizer;
address[] public players;
uint256 public entranceFee;
uint256 public predictionFee;
ScoreBoard public scoreBoard;
mapping(address players => Status) public playersStatus;
+ mapping(address => mapping(uint256 => bool)) public hasPaid;
.
.
.
function makePrediction(uint256 matchNumber, ScoreBoard.Result prediction) public payable {
+ if (!hasPaid[msg.sender][matchNumber]) {
+ if (msg.value != predictionFee) {
+ revert ThePredicter__IncorrectPredictionFee();
+ }
+ }
- if (msg.value != predictionFee) {
- revert ThePredicter__IncorrectPredictionFee();
- }
if (block.timestamp > START_TIME + matchNumber * 68400 - 68400) {
revert ThePredicter__PredictionsAreClosed();
}
scoreBoard.confirmPredictionPayment(msg.sender, matchNumber);
+ hasPaid[msg.sender][matchNumber] = true;
scoreBoard.setPrediction(msg.sender, matchNumber, prediction);
}

after that run the command forge test --mt test_POCChangePredictionAfterPayingFees
the test result should FAIL, indicating the call are not reverted:

Failing tests:
Encountered 1 failing test in test/ThePredicter.test.sol:ThePredicterTest
[FAIL. Reason: call did not revert as expected] test_POCChangePredictionAfterPayingFees() (gas: 239638)
Updates

Lead Judging Commences

NightHawK Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

farismaulana Submitter
11 months ago
NightHawK Lead Judge
11 months ago
farismaulana Submitter
11 months ago
NightHawK Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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