If those pending users want to cancel their registration, the funds will not be available to refund them, so the cancellation will revert.
If those players are approved by the organizer, the entrance fees that would be used for the player's rewards will not be there, so the ThePredicter.withdraw function will revert before having transferred all the corresponding rewards to the players.
The following PoC based on test already present in the repository show how this issue could arise and affect the withrdraw and cancelRegistration functions:
pragma solidity ^0.8.13;
import {Test, console} from "forge-std/Test.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ThePredicter} from "../src/ThePredicter.sol";
import {ScoreBoard} from "../src/ScoreBoard.sol";
contract IncorrectWithrawPredictionFeesAmountTest is Test {
ThePredicter public thePredicter;
ScoreBoard public scoreBoard;
address public organizer = makeAddr("organizer");
address public stranger = makeAddr("stranger");
uint256 entranceFee = 0.04 ether;
uint256 predictionFee = 0.0001 ether;
function setUp() public {
vm.startPrank(organizer);
scoreBoard = new ScoreBoard();
thePredicter = new ThePredicter(
address(scoreBoard),
entranceFee,
predictionFee
);
scoreBoard.setThePredicter(address(thePredicter));
vm.stopPrank();
}
function test_incorrectWitdrawPrediction_pendingPlayersCannotCancelRegistration() public {
vm.startPrank(stranger);
vm.deal(stranger, 1 ether);
thePredicter.register{value: entranceFee}();
vm.stopPrank();
uint256 organizerBalanceBefore = organizer.balance;
vm.startPrank(organizer);
thePredicter.withdrawPredictionFees();
vm.stopPrank();
uint256 organizerBalanceAfter = organizer.balance;
assertEq(organizerBalanceAfter, organizerBalanceBefore + entranceFee);
vm.startPrank(stranger);
vm.expectRevert();
thePredicter.cancelRegistration();
vm.stopPrank();
}
function test_incorrectWitdrawPrediction_approvedPlayersCannotReceiveRewards() public {
address stranger2 = makeAddr("stranger2");
address stranger3 = makeAddr("stranger3");
vm.startPrank(stranger);
vm.deal(stranger, 1 ether);
thePredicter.register{value: 0.04 ether}();
vm.stopPrank();
vm.startPrank(stranger2);
vm.deal(stranger2, 1 ether);
thePredicter.register{value: 0.04 ether}();
vm.stopPrank();
vm.startPrank(stranger3);
vm.deal(stranger3, 1 ether);
thePredicter.register{value: 0.04 ether}();
vm.stopPrank();
vm.startPrank(organizer);
thePredicter.withdrawPredictionFees();
vm.stopPrank();
vm.startPrank(organizer);
thePredicter.approvePlayer(stranger);
thePredicter.approvePlayer(stranger2);
thePredicter.approvePlayer(stranger3);
vm.stopPrank();
vm.startPrank(stranger);
thePredicter.makePrediction{value: 0.0001 ether}(
1,
ScoreBoard.Result.Draw
);
thePredicter.makePrediction{value: 0.0001 ether}(
2,
ScoreBoard.Result.Draw
);
thePredicter.makePrediction{value: 0.0001 ether}(
3,
ScoreBoard.Result.Draw
);
vm.stopPrank();
vm.startPrank(stranger2);
thePredicter.makePrediction{value: 0.0001 ether}(
1,
ScoreBoard.Result.Draw
);
thePredicter.makePrediction{value: 0.0001 ether}(
2,
ScoreBoard.Result.First
);
thePredicter.makePrediction{value: 0.0001 ether}(
3,
ScoreBoard.Result.First
);
vm.stopPrank();
vm.startPrank(stranger3);
thePredicter.makePrediction{value: 0.0001 ether}(
1,
ScoreBoard.Result.First
);
thePredicter.makePrediction{value: 0.0001 ether}(
2,
ScoreBoard.Result.First
);
thePredicter.makePrediction{value: 0.0001 ether}(
3,
ScoreBoard.Result.First
);
vm.stopPrank();
vm.startPrank(organizer);
scoreBoard.setResult(0, ScoreBoard.Result.First);
scoreBoard.setResult(1, ScoreBoard.Result.First);
scoreBoard.setResult(2, ScoreBoard.Result.First);
scoreBoard.setResult(3, ScoreBoard.Result.First);
scoreBoard.setResult(4, ScoreBoard.Result.First);
scoreBoard.setResult(5, ScoreBoard.Result.First);
scoreBoard.setResult(6, ScoreBoard.Result.First);
scoreBoard.setResult(7, ScoreBoard.Result.First);
scoreBoard.setResult(8, ScoreBoard.Result.First);
vm.stopPrank();
vm.startPrank(stranger2);
vm.expectRevert();
thePredicter.withdraw();
vm.stopPrank();
vm.startPrank(stranger3);
vm.expectRevert();
thePredicter.withdraw();
vm.stopPrank();
}
}
Incorrect computation of transferred funds.