idle_moloch/test/RaidGeld.t.sol
syahirAmali 0b1499a122
Some checks failed
CI / Foundry project (push) Has been cancelled
CI / Foundry project (pull_request) Has been cancelled
Events test added
2024-10-29 03:03:59 +08:00

285 lines
8.6 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {Test, console} from "forge-std/Test.sol";
import {RaidGeld, Army, Player} from "../src/RaidGeld.sol";
import "../src/RaidGeldUtils.sol";
contract raid_geldTest is Test {
RaidGeld public raid_geld;
address public player1;
address public player2;
address public owner;
event PlayerRegistered(address indexed player, uint256 initialGeld);
event RaidPerformed(
address indexed player,
uint256 totalMinted,
uint256 geldBalance
);
event UnitAdded(
address indexed player,
uint8 unitType,
uint16 nUnits,
uint256 cost,
uint256 geldBalance,
uint16 molochDenierLevel,
uint16 apprenticeLevel,
uint16 anointedLevel,
uint16 championLevel
);
function setUp() public {
owner = address(0x126);
player1 = address(0x123);
vm.deal(owner, 10 ether);
vm.deal(player1, 10 ether);
vm.prank(owner);
raid_geld = new RaidGeld();
}
function registerPlayer() private {
raid_geld.register{value: raid_geld.BUY_IN_AMOUNT()}();
}
function test_00_no_fallback() public {
vm.expectRevert();
// Send Ether with some data to trigger fallback
(bool success, ) = address(raid_geld).call{value: 0.1 ether}("0x1234");
}
function test_01_no_receive() public {
vm.startPrank(player1);
vm.expectRevert();
payable(address(raid_geld)).transfer(0.1 ether);
}
function test_02_registration() public {
vm.startPrank(player1);
uint256 initialBalance = address(raid_geld).balance;
// Making sure event is emitted when player is registered
vm.expectEmit(address(raid_geld));
emit PlayerRegistered(player1, raid_geld.INITIAL_GELD());
// Send registration fee ETH to the contract
registerPlayer();
// Check that initialraid_geld.is received by the player
assertEq(raid_geld.balanceOf(player1), raid_geld.INITIAL_GELD());
// Verify the contract balance is updated
assertEq(
address(raid_geld).balance,
initialBalance + raid_geld.BUY_IN_AMOUNT()
);
// Verify player is set initially
Player memory player = raid_geld.getPlayer(player1);
assertEq(player.total_minted, raid_geld.INITIAL_GELD());
assertEq(player.created_at, block.timestamp);
assertEq(player.last_raided_at, block.timestamp);
Army memory army = raid_geld.getArmy(player1);
assertEq(army.moloch_denier.level, 0);
assertEq(army.apprentice.level, 0);
assertEq(army.anointed.level, 0);
assertEq(army.champion.level, 0);
}
function test_03_funds_can_be_withdrawn() public {
uint256 initialBalance = owner.balance;
// Switch to Player 1 and register it
vm.startPrank(player1);
// Making sure event is emitted when player is registered
vm.expectEmit(address(raid_geld));
emit PlayerRegistered(player1, raid_geld.INITIAL_GELD());
registerPlayer();
// Switch back to owner and withdraw funds
vm.startPrank(owner);
raid_geld.withdraw();
uint256 newBalance = owner.balance;
uint256 newContractBalance = address(raid_geld).balance;
// contract balance should be empty
assertEq(newContractBalance, 0);
// owner should have the extra funds
assertEq(newBalance, initialBalance + raid_geld.BUY_IN_AMOUNT());
}
function test_04_only_owner_can_withdraw() public {
// Register player 1
vm.startPrank(player1);
// Making sure event is emitted when player is registered
vm.expectEmit(address(raid_geld));
emit PlayerRegistered(player1, raid_geld.INITIAL_GELD());
registerPlayer();
// attempt to withdraw with player 1, it should fail
vm.expectRevert();
raid_geld.withdraw();
}
function test_05_is_registered() public {
bool is_registered = raid_geld.isRegistered(player1);
assertEq(is_registered, false);
vm.startPrank(player1);
// Making sure event is emitted when player is registered
vm.expectEmit(address(raid_geld));
emit PlayerRegistered(player1, raid_geld.INITIAL_GELD());
registerPlayer();
is_registered = raid_geld.isRegistered(player1);
assertEq(is_registered, true);
}
function test_06_add_unit() public {
vm.startPrank(player1);
// Making sure event is emitted when player is registered
vm.expectEmit(address(raid_geld));
emit PlayerRegistered(player1, raid_geld.INITIAL_GELD());
registerPlayer();
vm.expectRevert();
// units should be in range
raid_geld.addUnit(100, 1);
// Player should have enough tokens to burn to get units
vm.expectRevert();
raid_geld.addUnit(1, 100);
Army memory army = raid_geld.getArmy(player1);
uint256 unit_level = army.moloch_denier.level;
uint256 balance = raid_geld.balanceOf(player1);
uint256 income_per_sec = army.profit_per_second;
uint256 cost = RaidGeldUtils.calculateUnitPrice(0, 0, 1);
uint256 playerBalance = raid_geld.balanceOf(address(player1));
// Making sure event is emitted when player adds a unit
vm.expectEmit(address(raid_geld));
emit UnitAdded(
address(player1),
0,
1,
cost,
playerBalance - cost,
1,
0,
0,
0
);
// Add 1 unit
raid_geld.addUnit(0, 1);
uint256 unitPrice = RaidGeldUtils.calculateUnitPrice(0, 0, 1);
// Check that those tokens were burnt
// WARN: In addUnit will mint additional tokens but they are not calculated
// into this because the test doesnt move the blockchain so no extra tokens
// are minted to the user
uint256 newBalance = raid_geld.balanceOf(player1);
assertEq(newBalance, balance - unitPrice);
army = raid_geld.getArmy(player1);
// Check that unit level increased
uint256 new_unit_level = army.moloch_denier.level;
assertEq(new_unit_level, unit_level + 1);
// Check that user income per second increased
uint256 new_income_per_sec = army.profit_per_second;
assertLt(income_per_sec, new_income_per_sec);
}
function test_07_raid() public {
// Let some time pass so we dont start at block timestamp 0
vm.warp(120);
// Register player 1
vm.startPrank(player1);
registerPlayer();
uint256 cost = RaidGeldUtils.calculateUnitPrice(0, 0, 1);
uint256 playerBalance = raid_geld.balanceOf(address(player1));
// Making sure event is emitted when player adds a unit
vm.expectEmit(address(raid_geld));
emit UnitAdded(
address(player1),
0,
1,
cost,
playerBalance - cost,
1,
0,
0,
0
);
// bought 1 moloch_denier
raid_geld.addUnit(0, 1);
vm.warp(block.timestamp + 15);
uint256 balance = raid_geld.balanceOf(player1);
Army memory army = raid_geld.getArmy(player1);
Player memory player = raid_geld.getPlayer(player1);
uint256 amountMinted = army.profit_per_second * 15;
// Making sure event is emitted when player performs a raid
vm.expectEmit(address(raid_geld));
emit RaidPerformed(
address(player1),
player.total_minted + amountMinted,
balance + amountMinted
);
// Trigger raid funds minting
raid_geld.raid();
// New balance should be larger
uint256 newBalance = raid_geld.balanceOf(player1);
player = raid_geld.getPlayer(player1);
uint256 last_raided_at = player.last_raided_at;
assertLt(balance, newBalance);
// After wait time passes raid should bring in profits again
vm.warp(block.timestamp + 15);
amountMinted = army.profit_per_second * 15;
emit RaidPerformed(
address(player1),
player.total_minted + amountMinted,
balance + amountMinted
);
raid_geld.raid();
// Balance should reflect that
uint256 newestBalance = raid_geld.balanceOf(player1);
player = raid_geld.getPlayer(player1);
uint256 last_raided_at_2 = player.last_raided_at;
assertLt(newBalance, newestBalance);
assertLt(last_raided_at, last_raided_at_2);
}
}