1
0
forked from mico/idle_moloch

Additional randomness tests plus removed withdraw

This commit is contained in:
mic0 2024-10-30 19:14:22 +01:00
parent 2e5d2143a8
commit 44f3e97de8
Signed by: mico
GPG Key ID: A3F8023524CF1C8D
4 changed files with 36 additions and 47 deletions

View File

@ -143,12 +143,6 @@ contract RaidGeld is ERC20, Ownable, Constants {
return 4;
}
// Allows the owner to withdraw DAO tokens
function withdraw() external onlyOwner {
uint256 amount = daoToken.balanceOf(address(this));
daoToken.transfer(owner(), amount);
}
// Manual minting for itchy fingers
function raid() external onlyActiveSession {
performRaid(msg.sender);
@ -264,7 +258,7 @@ contract RaidGeld is ERC20, Ownable, Constants {
_burn(msg.sender, geld_to_burn);
uint256 reward = RaidGeldUtils.calculateBossReward(boss_to_attack.level, BUY_IN_DAO_TOKEN_AMOUNT);
players[msg.sender].total_rewards += reward;
daoToken.transferFrom(address(this), msg.sender, reward);
daoToken.transfer(msg.sender, reward);
if (boss_to_attack.level == 6) {
// User ascends! Moloch is defeated, user can start a new run
players[msg.sender].prestige_level += 1;

View File

@ -2,7 +2,6 @@
pragma solidity ^0.8.13;
import {Army} from "../src/RaidGeldStructs.sol";
import {console} from "forge-std/Test.sol";
library RaidGeldUtils {
uint256 public constant PRECISION = 10000;
@ -98,7 +97,7 @@ library RaidGeldUtils {
// TODO: This could as well just be pre-calculated
uint256 cumulativeChance = getBossCumulativeChance(bossLevel); // 0 - 1e18 range
uint256 rewardMultiplier = ((2 * (1e18 - cumulativeChance)) ** 2) / 1e18;
return (baseReward * rewardMultiplier);
return (baseReward * rewardMultiplier) / 1e18;
}
// Calculates whether user survives the fight
@ -130,7 +129,8 @@ library RaidGeldUtils {
// TODO: Implement actual randomness
function random(uint256 prevrandao, uint256 min, uint256 max) internal pure returns (uint256) {
// returns 0 - 100
require(max >= min, "Max must be greater than or equal to min");
require(max > min, "Max must be greater than min");
require(max < type(uint256).max, "Dont use largest possible uint");
uint256 range = max - min + 1;
return min + (uint256(keccak256(abi.encodePacked(prevrandao))) % range);
}

View File

@ -134,38 +134,7 @@ contract raid_geldTest is Test, Constants {
assertEq(army.champion.level, 0);
}
function test_03_dao_token_can_be_withdrawn() public {
uint256 initialBalance = raid_geld.daoToken().balanceOf(address(raid_geld));
// Switch to Player 1 and register it
vm.startPrank(player1);
// doesnt test player emitted event because other events get emitted before it
registerPlayerWithDaoToken();
// Switch back to owner and withdraw funds
vm.startPrank(owner);
raid_geld.withdraw();
uint256 newBalance = raid_geld.daoToken().balanceOf(address(owner));
uint256 newContractBalance = raid_geld.daoToken().balanceOf(address(raid_geld));
// contract balance should be empty
assertEq(newContractBalance, 0);
// owner should have the extra funds
assertGt(newBalance, initialBalance);
}
function test_04_only_owner_can_withdraw() public {
// Register player 1
vm.startPrank(player1);
registerPlayer();
// attempt to withdraw with player 1, it should fail
vm.expectRevert();
raid_geld.withdraw();
}
function test_05_is_registered() public {
function test_03_is_registered() public {
bool is_registered = raid_geld.isRegistered(player1);
assertEq(is_registered, false);
vm.startPrank(player1);
@ -179,7 +148,7 @@ contract raid_geldTest is Test, Constants {
assertEq(is_registered, true);
}
function test_06_add_unit() public {
function test_04_add_unit() public {
vm.startPrank(player1);
// Making sure event is emitted when player is registered
@ -229,7 +198,7 @@ contract raid_geldTest is Test, Constants {
assertLt(income_per_sec, new_income_per_sec);
}
function test_07_raid() public {
function test_05_raid() public {
// Let some time pass so we dont start at block timestamp 0
vm.warp(120);
@ -286,13 +255,13 @@ contract raid_geldTest is Test, Constants {
assertLt(last_raided_at, last_raided_at_2);
}
function test_08_attack_boss() public {
function test_06_attack_boss() public {
// Let some time pass so we dont start at block timestamp 0
vm.warp(120);
// Register player 1
vm.startPrank(player1);
registerPlayer();
registerPlayerWithDaoToken();
raid_geld.addUnit(0, 1);
Boss memory boss = raid_geld.getBoss(player1);

View File

@ -88,7 +88,33 @@ contract raid_geldTest is Test {
}
}
function test_2_calculateBossFight_probabilities() public {
function test_21_random(uint256 seed, uint256 min, uint256 max) public pure {
vm.assume(min < max);
vm.assume(max < type(uint256).max);
uint256 random = RaidGeldUtils.random(seed, min, max);
vm.assertTrue(random >= min && random <= max, "random() fell outside its range");
}
function test_22_random_range(uint256 min, uint256 max) public {
vm.assume(max > min);
vm.assume(max - min < 100);
vm.assume(max < type(uint256).max);
uint256 range = max - min + 1;
bool[] memory seen = new bool[](range);
uint256 count = 0;
for (uint256 i = 0; i < 100000; i++) {
uint256 result = RaidGeldUtils.random(block.prevrandao + i, min, max);
uint256 index = result - min;
if (!seen[index]) {
seen[index] = true;
count++;
}
if (count == range) break;
}
assertEq(count, range, "Not all values in the interval were generated");
}
function test_3_calculateBossFight_probabilities() public {
uint256[7] memory probabilities =
[uint256(99), uint256(89), uint256(80), uint256(70), uint256(62), uint256(51), uint256(40)];
uint256 totalRuns = 1000;