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 ThePredicterTest is Test {
ThePredicter public thePredicter;
ScoreBoard public scoreBoard;
address public organizer = makeAddr("Ivan");
function setUp() public {
vm.startPrank(organizer);
scoreBoard = new ScoreBoard();
thePredicter = new ThePredicter(
address(scoreBoard),
0.04 ether,
0.0001 ether
);
scoreBoard.setThePredicter(address(thePredicter));
vm.stopPrank();
}
function setUpPlayersRegistrationAndApproval() private{
for (uint256 i = 0; i < 30; ++i) {
address user = makeAddr(string.concat("user", Strings.toString(i)));
vm.startPrank(user);
vm.deal(user, 1 ether);
thePredicter.register{value: 4e16}();
vm.stopPrank();
vm.startPrank(organizer);
thePredicter.approvePlayer(user);
vm.stopPrank();
}
}
function test_AnyAccountCanMakePredictionsAndWin() public{
setUpPlayersRegistrationAndApproval();
uint256 vaultBalBefore = address(thePredicter).balance;
address unregistered_account = makeAddr("unregistered");
vm.startPrank(unregistered_account);
vm.deal(unregistered_account, 1 ether);
thePredicter.makePrediction{value: 0.0001 ether}(0, ScoreBoard.Result.First);
thePredicter.makePrediction{value: 0.0001 ether}(1, ScoreBoard.Result.First);
vm.deal(unregistered_account, 0 ether);
vm.stopPrank();
uint256 playerBalBefore = unregistered_account.balance;
for(uint i = 0; i < 8; ++i){
address player = thePredicter.players(i);
vm.startPrank(player);
vm.deal(player, 1 ether);
thePredicter.makePrediction{value: 0.0001 ether}(0, ScoreBoard.Result.First);
thePredicter.makePrediction{value: 0.0001 ether}(1, ScoreBoard.Result.First);
thePredicter.makePrediction{value: 0.0001 ether}(2, ScoreBoard.Result.Draw);
thePredicter.makePrediction{value: 0.0001 ether}(3, ScoreBoard.Result.First);
thePredicter.makePrediction{value: 0.0001 ether}(4, ScoreBoard.Result.Second);
thePredicter.makePrediction{value: 0.0001 ether}(5, ScoreBoard.Result.Draw);
thePredicter.makePrediction{value: 0.0001 ether}(6, ScoreBoard.Result.Second);
thePredicter.makePrediction{value: 0.0001 ether}(7, ScoreBoard.Result.Draw);
thePredicter.makePrediction{value: 0.0001 ether}(8, ScoreBoard.Result.Draw);
vm.stopPrank();
vm.deal(player, 0);
}
for(uint i = 0; i < 7; ++i){
address player = thePredicter.players(i);
vm.startPrank(unregistered_account);
scoreBoard.setPrediction(player, 0, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(player, 1, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(player, 2, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(player, 3, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(player, 4, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(player, 5, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(player, 6, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(player, 7, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(player, 8, ScoreBoard.Result.Pending);
vm.stopPrank();
}
address scape_goat = thePredicter.players(7);
vm.startPrank(unregistered_account);
scoreBoard.setPrediction(scape_goat, 0, ScoreBoard.Result.First);
scoreBoard.setPrediction(scape_goat, 1, ScoreBoard.Result.First);
scoreBoard.setPrediction(scape_goat, 2, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(scape_goat, 3, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(scape_goat, 4, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(scape_goat, 5, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(scape_goat, 6, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(scape_goat, 7, ScoreBoard.Result.Pending);
scoreBoard.setPrediction(scape_goat, 8, ScoreBoard.Result.Pending);
vm.stopPrank();
vm.startPrank(organizer);
scoreBoard.setResult(0, ScoreBoard.Result.First);
scoreBoard.setResult(1, ScoreBoard.Result.First);
scoreBoard.setResult(2, ScoreBoard.Result.Draw);
scoreBoard.setResult(3, ScoreBoard.Result.Second);
scoreBoard.setResult(4, ScoreBoard.Result.Draw);
scoreBoard.setResult(5, ScoreBoard.Result.First);
scoreBoard.setResult(6, ScoreBoard.Result.Draw);
scoreBoard.setResult(7, ScoreBoard.Result.First);
scoreBoard.setResult(8, ScoreBoard.Result.First);
vm.stopPrank();
vm.prank(unregistered_account);
thePredicter.withdraw();
uint256 vaultBalAfter = address(thePredicter).balance;
uint256 playerBalAfter = unregistered_account.balance;
assertEq(vaultBalBefore, 1.2 ether);
assertEq(vaultBalAfter, 0.0074 ether);
assertEq(playerBalBefore, 0 ether);
assertEq(playerBalAfter, 1.2 ether);
}
}