From 162b3e357a1ed81f973c4015b2f258d01305759c Mon Sep 17 00:00:00 2001 From: Uncle Fatso Date: Tue, 22 Jul 2025 16:12:52 +0300 Subject: [PATCH] new tests for gatekeeper on staking Signed-off-by: Uncle Fatso --- src/Staking.sol | 2 ++ test/staking/Staking.t.sol | 72 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/Staking.sol b/src/Staking.sol index 3e2d13d..4a1ff69 100644 --- a/src/Staking.sol +++ b/src/Staking.sol @@ -139,6 +139,7 @@ contract GhostStaking is IStaking, GhostAccessControlled { bytes32 receiver, uint256 amount ) external override { + IGHST(ghst).burn(msg.sender, amount); IGatekeeper(gatekeeper).ghost(receiver, amount); } @@ -149,6 +150,7 @@ contract GhostStaking is IStaking, GhostAccessControlled { uint256 s ) external override { IGatekeeper(gatekeeper).materialize(receiver, amount, rx, s); + IGHST(ghst).mint(receiver, amount); } function rebase() public override returns (uint256 bounty) { diff --git a/test/staking/Staking.t.sol b/test/staking/Staking.t.sol index dbb8413..e72280a 100644 --- a/test/staking/Staking.t.sol +++ b/test/staking/Staking.t.sol @@ -10,6 +10,7 @@ import "../../src/StakingDistributor.sol"; import "../../src/Treasury.sol"; import "../../src/Staking.sol"; import "../../src/mocks/ERC20Mock.sol"; +import "../../src/Gatekeeper.sol"; contract StakingTest is Test { address constant initializer = 0x0000000000000000000000000000000000000001; @@ -33,8 +34,10 @@ contract StakingTest is Test { GhostStaking staking; GhostTreasury treasury; GhostAuthority authority; + Gatekeeper gatekeeper; uint256 public constant amount = 69; + uint256 public constant bigAmount = amount * 1e9; event DistributorSet(address distributor); event WarmupSet(uint256 warmup); @@ -62,6 +65,7 @@ contract StakingTest is Test { treasury = new GhostTreasury(address(ftso), 69, address(authority)); stnk.initialize(address(staking), address(treasury), address(ghst)); ghst.initialize(address(staking)); + gatekeeper = new Gatekeeper(address(staking), 0); vm.stopPrank(); } @@ -507,6 +511,74 @@ contract StakingTest is Test { assertEq(ftso.balanceOf(address(staking)), 2 * postBounty + bounty); } + function test_arbitraryAddressCouldNotAddGatekeeper(address someone, address maybeGatekeeper) public { + vm.assume(maybeGatekeeper != address(0) && someone != governor); + vm.expectRevert(); + vm.prank(someone); + staking.setDistributor(maybeGatekeeper); + } + + function test_governorCouldSetGatekeeper(address maybeGatekeeper) public { + vm.assume(maybeGatekeeper != address(0)); + assertEq(staking.gatekeeper(), address(0)); + vm.prank(governor); + staking.setGatekeeperAddress(maybeGatekeeper); + assertEq(staking.gatekeeper(), maybeGatekeeper); + } + + function test_couldNotGhostIfNoGatekeeper() public { + assertEq(staking.ghostedSupply(), 0); + vm.expectRevert(); + staking.ghost(bytes32(abi.encodePacked(alice)), amount); + assertEq(staking.ghostedSupply(), 0); + } + + function test_couldNotMaterializeIfNoGatekeeper() public { + assertEq(staking.ghostedSupply(), 0); + vm.expectRevert(); + staking.materialize(alice, amount, 0, 0); // dummy rx and s + assertEq(staking.ghostedSupply(), 0); + } + + function test_couldNotGhostTokensIfNoGhst() public { + assertEq(staking.gatekeeper(), address(0)); + vm.prank(governor); + staking.setGatekeeperAddress(address(gatekeeper)); + assertEq(staking.gatekeeper(), address(gatekeeper)); + + assertEq(staking.ghostedSupply(), 0); + vm.expectRevert(); + vm.prank(alice); + staking.ghost(bytes32(abi.encodePacked(alice)), amount); + assertEq(staking.ghostedSupply(), 0); + } + + function test_correctlyGhostTokens() public { + assertEq(staking.gatekeeper(), address(0)); + vm.prank(governor); + staking.setGatekeeperAddress(address(gatekeeper)); + assertEq(staking.gatekeeper(), address(gatekeeper)); + + _prepareAndRoll(alice, bigAmount, true, true); + uint256 aliceBalance = stnk.balanceOf(alice); + + vm.startPrank(alice); + stnk.approve(address(staking), aliceBalance); + uint256 ghstBalance = staking.wrap(alice, aliceBalance); + vm.stopPrank(); + + assertEq(staking.ghostedSupply(), 0); + assertEq(stnk.circulatingSupply(), bigAmount - 1); // precision fix + assertEq(ghst.totalSupply(), ghstBalance); + + vm.prank(alice); + staking.ghost(bytes32(abi.encodePacked(alice)), ghstBalance); + + assertEq(staking.ghostedSupply(), ghstBalance); + assertEq(stnk.circulatingSupply(), bigAmount - 1); // precision fix + assertEq(ghst.totalSupply(), 0); + } + function _mintAndApprove(address who, uint256 value) internal { vm.prank(vault); ftso.mint(who, value);