diff --git a/test/staking/Staking.t.sol b/test/staking/Staking.t.sol index f2c0526..26ca8e7 100644 --- a/test/staking/Staking.t.sol +++ b/test/staking/Staking.t.sol @@ -611,6 +611,62 @@ contract StakingTest is Test { staking.ghost(receiver, ghstBalance); } + function test_breakoutLogicWorks() public { + assertEq(staking.gatekeeper(), address(0)); + vm.prank(GOVERNOR); + staking.setGatekeeperAddress(address(gatekeeper)); + assertEq(staking.gatekeeper(), address(gatekeeper)); + + uint256 initialIndex = staking.index(); + bytes32 receiver = bytes32(abi.encodePacked(ALICE)); + uint256 rebased = _prepareAndRoll(ALICE, BIG_AMOUNT, false, false); + + (uint256 deposit, uint256 payout,,) = staking.warmupInfo(ALICE); + assertEq(deposit, rebased); + assertEq(payout, ghst.balanceTo(rebased)); + assertEq(staking.supplyInWarmup(), ghst.balanceFrom(payout)); + + vm.expectRevert(); + vm.prank(BOB); + staking.breakout(receiver, payout); + + + uint256 requestedPayout = 1; + uint256 expectedPayout = 0; + while (expectedPayout < payout / 2) { + uint256 pseudoRandom = uint256(keccak256(abi.encodePacked("salt", requestedPayout, expectedPayout))); + uint256 range = (payout * 3) / 100; + requestedPayout = (pseudoRandom % range) + 1; + + vm.expectEmit(true, true, true, false, address(gatekeeper)); + emit Ghosted(receiver, requestedPayout); + + vm.prank(ALICE); + staking.breakout(receiver, requestedPayout); + expectedPayout += requestedPayout; + + (,uint256 tmpPayout,,) = staking.warmupInfo(ALICE); + assertEq(tmpPayout, payout - expectedPayout); + assertEq(staking.supplyInWarmup(), ghst.balanceFrom(payout - expectedPayout)); + + (,, uint48 end,) = staking.epoch(); + skip(end); + staking.rebase(); + } + + (uint256 newDeposit, uint256 newPayout,,) = staking.warmupInfo(ALICE); + assertEq(newPayout, payout - expectedPayout); + assertEq(staking.supplyInWarmup(), ghst.balanceFrom(payout - expectedPayout)); + assertEq(ftso.balanceOf(ALICE), 0); + + vm.prank(ALICE); + staking.forfeit(); + + uint256 restoredPayout = expectedPayout * initialIndex / 1e18; + assertLt(ftso.balanceOf(ALICE) + restoredPayout, BIG_AMOUNT); + assertEq(newDeposit, ftso.balanceOf(ALICE)); + } + function _mintAndApprove(address who, uint256 value) internal { vm.prank(VAULT); ftso.mint(who, value);