From 59a13fec9d0b1047959c91e5ec4a8e61d0b45d89 Mon Sep 17 00:00:00 2001 From: Uncle Fatso Date: Mon, 14 Sep 2026 11:03:55 +0300 Subject: [PATCH] remove governance feature from GhostERC20 contract Signed-off-by: Uncle Fatso --- deployer.sh | 15 +- src/GhstERC20.sol | 39 +- test/governance/GhostGovernor.t.sol | 647 ---------------------------- test/tokens/Ghst.t.sol | 25 +- 4 files changed, 9 insertions(+), 717 deletions(-) delete mode 100644 test/governance/GhostGovernor.t.sol diff --git a/deployer.sh b/deployer.sh index 8f29ed7..314743a 100644 --- a/deployer.sh +++ b/deployer.sh @@ -3,7 +3,7 @@ set -e AVAILABLE_NETWORKS=(anvil-localnet sepolia-testnet hoodi-testnet mordor-testnet) NETWORK="${AVAILABLE_NETWORKS[0]}" START=1 -END=13 +END=12 VERIFY_NEEDED="--verify" LEGACY_FLAGS="" @@ -25,10 +25,9 @@ usage() { echo "7) BondDepository" echo "8) StakingDistributor" echo "9) BondingCalculator" - echo "10) Governor" - echo "11) AfterPartyFirst" - echo "12) AfterPartySecond" - echo "13) AfterPartyThird" + echo "10) AfterPartyFirst" + echo "11) AfterPartySecond" + echo "12) AfterPartyThird" echo "69) Gatekeeper" exit 1 } @@ -111,12 +110,10 @@ for i in $(seq $START $END); do elif [ "9" == "$i" ]; then CONTRACT="BondingCalculator" elif [ "10" == "$i" ]; then - CONTRACT="Governor" - elif [ "11" == "$i" ]; then CONTRACT="AfterPartyFirst" - elif [ "12" == "$i" ]; then + elif [ "11" == "$i" ]; then CONTRACT="AfterPartySecond" - elif [ "13" == "$i" ]; then + elif [ "12" == "$i" ]; then CONTRACT="AfterPartyThird" elif [ "69" == "$i" ]; then CONTRACT="Gatekeeper" diff --git a/src/GhstERC20.sol b/src/GhstERC20.sol index edd638a..ffcf179 100644 --- a/src/GhstERC20.sol +++ b/src/GhstERC20.sol @@ -2,25 +2,17 @@ pragma solidity ^0.8.20; import {ERC20} from "@openzeppelin-contracts/token/ERC20/ERC20.sol"; -import {ERC20Permit} from "@openzeppelin-contracts/token/ERC20/extensions/ERC20Permit.sol"; -import {ERC20Votes} from "@openzeppelin-contracts/token/ERC20/extensions/ERC20Votes.sol"; -import {Nonces} from "@openzeppelin-contracts/utils/Nonces.sol"; import {ISTNK} from "./interfaces/ISTNK.sol"; import {IGHST} from "./interfaces/IGHST.sol"; import {FullMath} from "./libraries/FullMath.sol"; -contract Ghost is IGHST, ERC20, ERC20Permit, ERC20Votes { +contract Ghost is IGHST, ERC20 { address public override staking; address public override stnk; address private _initializer; - error GhostDelegationIsBuiltIn(); - - constructor(address _stnk, string memory name, string memory symbol) - ERC20(name, symbol) - ERC20Permit(name) - { + constructor(address _stnk, string memory name, string memory symbol) ERC20(name, symbol) { stnk = _stnk; _initializer = msg.sender; } @@ -41,21 +33,6 @@ contract Ghost is IGHST, ERC20, ERC20Permit, ERC20Votes { _burn(_from, _amount); } - function delegate(address) public override pure { - revert GhostDelegationIsBuiltIn(); - } - - function delegateBySig( - address, - uint256, - uint256, - uint8, - bytes32, - bytes32 - ) public override pure { - revert GhostDelegationIsBuiltIn(); - } - function index() public view override returns (uint256) { return ISTNK(stnk).index(); } @@ -67,16 +44,4 @@ contract Ghost is IGHST, ERC20, ERC20Permit, ERC20Votes { function balanceTo(uint256 _amount) public view override returns (uint256) { return FullMath.mulDiv(_amount, 1e18, index()); } - - function nonces(address owner) public view override(ERC20Permit, Nonces) returns (uint256) { - return super.nonces(owner); - } - - function delegates(address account) public pure override returns (address) { - return account; - } - - function _update(address from, address to, uint256 amount) internal override(ERC20, ERC20Votes) { - super._update(from, to, amount); - } } diff --git a/test/governance/GhostGovernor.t.sol b/test/governance/GhostGovernor.t.sol deleted file mode 100644 index c21956e..0000000 --- a/test/governance/GhostGovernor.t.sol +++ /dev/null @@ -1,647 +0,0 @@ -pragma solidity 0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {Strings} from "@openzeppelin-contracts/utils/Strings.sol"; - -import {Ghost} from "../../src/GhstERC20.sol"; -import {Stinky} from "../../src/StinkyERC20.sol"; -import {GhostGovernor} from "../../src/governance/GhostGovernor.sol"; - -import {IGovernor} from "@openzeppelin-contracts/governance/IGovernor.sol"; -import {IVotes} from "@openzeppelin-contracts/governance/utils/IVotes.sol"; -import {SafeERC20} from "@openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; - -contract GhostGovernorExposed is GhostGovernor { - constructor( - IVotes _ghst, - uint48 _initialVoteExtension, - uint48 _initialVotingDelay, - uint32 _initialVotingPeriod, - uint256 _initialProposalThreshold, - uint256 _quorumFraction - ) GhostGovernor( - _ghst, - _initialVoteExtension, - _initialVotingDelay, - _initialVotingPeriod, - _initialProposalThreshold, - _quorumFraction - ) {} - - function isValidDescriptionForProposer( - address proposer, - string memory description - ) public view returns (bool) { - return super._isValidDescriptionForProposer(proposer, description); - } - - function quorumReached(uint256 proposalId) public view returns (bool) { - return super._quorumReached(proposalId); - } - - function voteSucceeded(uint256 proposalId) public view returns (bool) { - return super._voteSucceeded(proposalId); - } -} - -contract GhostGovernorTest is Test { - using Strings for address; - using SafeERC20 for Ghost; - - uint48 public constant VOTE_EXTENSION = 69; - uint48 public constant VOTING_DELAY = 420; - uint32 public constant VOTING_PERIOD = 1337; - uint256 public constant PROPOSAL_THRESHOLD = 69 * 1e18; - uint256 public constant QUORUM_FRACTION = 20; // percent - - address constant INIT = 0x0000000000000000000000000000000000000001; - address constant ALICE = 0x0000000000000000000000000000000000000002; - address constant BOB = 0x0000000000000000000000000000000000000003; - address constant CAROL = 0x0000000000000000000000000000000000000004; - address constant DAVE = 0x0000000000000000000000000000000000000005; - address constant EVE = 0x0000000000000000000000000000000000000006; - - GhostGovernorExposed public governor; - Stinky public stnk; - Ghost public ghst; - - function setUp() public { - vm.startPrank(INIT); - stnk = new Stinky(10819917194513808e56, "Stinky Test Name", "STNKTST"); - ghst = new Ghost(address(stnk), "Ghost Test Name", "GHSTTST"); - ghst.initialize(INIT); - governor = new GhostGovernorExposed( - ghst, - VOTE_EXTENSION, - VOTING_DELAY, - VOTING_PERIOD, - PROPOSAL_THRESHOLD, - QUORUM_FRACTION - ); - vm.stopPrank(); - - vm.prank(ALICE); - ghst.approve(address(governor), type(uint256).max); - - vm.prank(BOB); - ghst.approve(address(governor), type(uint256).max); - - vm.prank(CAROL); - ghst.approve(address(governor), type(uint256).max); - } - - function test_correctGovernanceName() public view { - assertEq(governor.name(), "GhostGovernorV1"); - } - - function test_correctGovernanceVersion() public view { - assertEq(governor.version(), "1"); - } - - function test_correctGovernanceConfig() public view { - assertEq(governor.COUNTING_MODE(), "support=bravo&quorum=for"); - } - - function test_correctGovernanceProposalThreshold() public view { - assertEq(governor.proposalThreshold(), PROPOSAL_THRESHOLD); - } - - function test_correctGovernanceVotingDelay() public view { - assertEq(governor.votingDelay(), VOTING_DELAY); - } - - function test_correctGovernanceVotingPeriod() public view { - assertEq(governor.votingPeriod(), VOTING_PERIOD); - } - - function test_correctGovernanceVoteExtension() public view { - assertEq(governor.lateQuorumVoteExtension(), VOTE_EXTENSION); - } - - function test_correctGovernanceQuorumFraction() public view { - assertEq(governor.quorumNumerator(), QUORUM_FRACTION); - } - - function test_validDescriptionForProposer( - string memory description, - address proposer, - bool includeProposer - ) public view { - string memory finalDescription = description; - - if (includeProposer) { - finalDescription = string.concat( - description, - "#proposer=", - Strings.toHexString(proposer) - ); - } - - bool isValid = governor.isValidDescriptionForProposer(proposer, finalDescription); - assertTrue(isValid); - } - - function test_invalidDescriptionForProposer( - string memory description, - address commitProposer, - address actualProposer - ) public view { - vm.assume(commitProposer != actualProposer); - - string memory wrongDescription = string.concat( - description, - "#proposer=", - Strings.toHexString(commitProposer) - ); - - bool isValid = governor.isValidDescriptionForProposer(actualProposer, wrongDescription); - assertFalse(isValid); - } - - function test_succeededOnAbsoluteMajority() public { - vm.startPrank(INIT); - ghst.mint(ALICE, PROPOSAL_THRESHOLD); - ghst.mint(BOB, 555 * 1e17); - ghst.mint(CAROL, 345 * 1e17 + 1); - ghst.mint(DAVE, 21 * 1e18); - vm.stopPrank(); - - vm.roll(block.number + 1); - - (uint256 proposalId,,,,) = _proposeDummy(ALICE, 69); - _waitForActive(proposalId); - - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Active)); - _castVoteWrapper(proposalId, BOB, 1, true, true); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Succeeded)); - - vm.expectRevert(); - vm.prank(CAROL); - governor.castVote(proposalId, 0); - - vm.expectRevert(); - vm.prank(DAVE); - governor.castVote(proposalId, 0); - } - - function test_defeatedOnAbsoluteMajority() public { - vm.startPrank(INIT); - ghst.mint(ALICE, PROPOSAL_THRESHOLD); - ghst.mint(BOB, 555 * 1e17); - ghst.mint(CAROL, 345 * 1e17 + 1); - ghst.mint(DAVE, 21 * 1e18); - vm.stopPrank(); - - vm.roll(block.number + 1); - - (uint256 proposalId,,,,) = _proposeDummy(ALICE, 69); - _waitForActive(proposalId); - - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Active)); - _castVoteWrapper(proposalId, BOB, 0, true, false); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Active)); - _castVoteWrapper(proposalId, CAROL, 0, true, false); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Defeated)); - - vm.expectRevert(); - vm.prank(DAVE); - governor.castVote(proposalId, 1); - } - - function test_onlyOneActiveProposal() public { - uint256 amount = PROPOSAL_THRESHOLD; - vm.startPrank(INIT); - ghst.mint(ALICE, amount); - ghst.mint(BOB, 2 * amount); - ghst.mint(CAROL, 3 * amount); - vm.stopPrank(); - - vm.roll(block.number + 1); - - (uint256 proposalId,,,,) = _proposeDummy(ALICE, 69); - _waitForActive(proposalId); - - vm.prank(ALICE); - assertEq(governor.releaseLocked(proposalId), 0); - assertEq(governor.lockedAmounts(proposalId), amount); - assertEq(ghst.balanceOf(ALICE), 0); - - (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) = governor.proposalVotes(proposalId); - assertEq(againstVotes, 0); - assertEq(forVotes, amount); - assertEq(abstainVotes, 0); - - _castVoteWrapper(proposalId, BOB, 1, true, true); - (againstVotes, forVotes, abstainVotes) = governor.proposalVotes(proposalId); - assertEq(againstVotes, 0); - assertEq(forVotes, 3 * amount); - assertEq(abstainVotes, 0); - - assertEq(ghst.balanceOf(ALICE), 0); - assertEq(ghst.balanceOf(BOB), 2 * amount); - assertEq(ghst.balanceOf(CAROL), 3 * amount); - - _waitForSucceed(proposalId); - - vm.prank(ALICE); - assertEq(governor.releaseLocked(proposalId), amount); - assertEq(governor.lockedAmounts(proposalId), 0); - assertEq(ghst.balanceOf(ALICE), amount); - - vm.prank(ALICE); - assertEq(governor.releaseLocked(proposalId), 0); - assertEq(governor.lockedAmounts(proposalId), 0); - assertEq(ghst.balanceOf(ALICE), amount); - - assertEq(ghst.balanceOf(ALICE), amount); - assertEq(ghst.balanceOf(BOB), 2 * amount); - assertEq(ghst.balanceOf(CAROL), 3 * amount); - - (proposalId,,,,) = _proposeDummy(BOB, 420); - _waitForActive(proposalId); - - _castVoteWrapper(proposalId, ALICE, 1, true, true); - _castVoteWrapper(proposalId, CAROL, 1, true, true); - - vm.roll(block.number + 3); - - (uint256 newProposalId,,,,) = _proposeDummy(CAROL, 1337); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Succeeded)); - assertEq(uint8(governor.state(newProposalId)), uint8(IGovernor.ProposalState.Pending)); - - assertEq(ghst.balanceOf(ALICE), amount); - assertEq(ghst.balanceOf(BOB), 0); - assertEq(ghst.balanceOf(CAROL), 0); - - vm.prank(BOB); - assertEq(governor.releaseLocked(proposalId), 2 * amount); - assertEq(governor.lockedAmounts(proposalId), 0); - assertEq(ghst.balanceOf(BOB), 2 * amount); - - vm.prank(CAROL); - assertEq(governor.releaseLocked(newProposalId), 0); - assertEq(governor.lockedAmounts(newProposalId), 3 * amount); - assertEq(ghst.balanceOf(CAROL), 0); - } - - function test_proposalCountWorks() public { - assertEq(governor.proposalCount(), 0); - - uint256 i = 1; - for (; i < 69; ) { - { - uint256 amount = governor.activeProposedLock() + PROPOSAL_THRESHOLD; - - if (amount + ghst.totalSupply() > type(uint208).max) { - break; - } - - vm.prank(INIT); - ghst.mint(ALICE, amount); - vm.roll(block.number + 1); - } - - ( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) = _proposeDummy(ALICE, i); - - { - ( - address[] memory thisTargets, - uint256[] memory thisValues, - bytes[] memory thisCalldatas, - bytes32 thisDescriptionHash - ) = governor.proposalDetails(proposalId); - - assertEq(thisTargets.length, targets.length); - assertEq(thisValues.length, values.length); - assertEq(thisCalldatas.length, calldatas.length); - - assertEq(thisTargets[0], targets[0]); - assertEq(thisValues[0], values[0]); - assertEq(thisCalldatas[0], calldatas[0]); - assertEq(thisDescriptionHash, keccak256(bytes(description))); - } - - { - ( - uint256 otherProposalId, - address[] memory otherTargets, - uint256[] memory otherValues, - bytes[] memory otherCalldatas, - bytes32 otherDescriptionHash - ) = governor.proposalDetailsAt(i - 1); - - assertEq(otherTargets.length, targets.length); - assertEq(otherValues.length, values.length); - assertEq(otherCalldatas.length, calldatas.length); - - assertEq(otherProposalId, governor.hashProposal(targets, values, calldatas, keccak256(bytes(description)))); - assertEq(otherTargets[0], targets[0]); - assertEq(otherValues[0], values[0]); - assertEq(otherCalldatas[0], calldatas[0]); - assertEq(otherDescriptionHash, keccak256(bytes(description))); - } - - assertEq(governor.proposalCount(), i); - unchecked { ++i; } - } - } - - function test_preventLateQuorumWorks() public { - vm.startPrank(INIT); - ghst.mint(ALICE, PROPOSAL_THRESHOLD); - ghst.mint(BOB, 50 * 1e18); - ghst.mint(CAROL, 100 * 1e18); - ghst.mint(DAVE, 100 * 1e18); - ghst.mint(EVE, 500 * 1e18); - vm.stopPrank(); - - vm.roll(block.number + 1); - (uint256 proposalId,,,,) = _proposeDummy(ALICE, 69); - - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Pending)); - vm.roll(block.number + VOTING_DELAY + 1); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Active)); - - assertEq(governor.voteOf(proposalId, BOB), 0); - assertEq(governor.voteOf(proposalId, CAROL), 0); - assertEq(governor.voteOf(proposalId, DAVE), 0); - assertEq(governor.voteOf(proposalId, EVE), 0); - - vm.roll(governor.proposalDeadline(proposalId)); - _castVoteWrapper(proposalId, BOB, 1, false, true); - vm.roll(governor.proposalDeadline(proposalId)); - _castVoteWrapper(proposalId, CAROL, 0, true, false); - vm.roll(governor.proposalDeadline(proposalId)); - _castVoteWrapper(proposalId, DAVE, 1, true, false); - vm.roll(governor.proposalDeadline(proposalId)); - _castVoteWrapper(proposalId, EVE, 1, true, true); - - vm.prank(ALICE); - governor.execute(proposalId); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Executed)); - - assertEq(governor.voteOf(proposalId, BOB), 2); - assertEq(governor.voteOf(proposalId, CAROL), 1); - assertEq(governor.voteOf(proposalId, DAVE), 2); - assertEq(governor.voteOf(proposalId, EVE), 2); - } - - function test_quorumNumeratorWorks() public { - uint256 numerator = governor.quorumNumerator(); - uint256 denominator = governor.quorumDenominator(); - uint256 currentBlock = block.number; - - vm.startPrank(INIT); - ghst.mint(ALICE, 1 * 1e18); - ghst.mint(BOB, 69 * 1e18); - ghst.mint(CAROL, 420 * 1e18); - ghst.mint(DAVE, 1337 * 1e18); - ghst.mint(EVE, 69420 * 1e18); - vm.stopPrank(); - - vm.roll(currentBlock + 2); - assertEq(governor.quorum(currentBlock), 71247 * 1e18 * numerator / denominator); - } - - function test_votingPowerTransfer() public { - vm.startPrank(INIT); - ghst.mint(ALICE, 35 * 1e18); - ghst.mint(BOB, 34 * 1e18); - vm.stopPrank(); - - vm.roll(block.number + 1); - - vm.expectRevert(); - vm.prank(ALICE); - ghst.delegate(ALICE); - - vm.expectRevert(); - vm.prank(BOB); - ghst.delegate(BOB); - - _assertVotesEqualToBalance(); - - vm.prank(ALICE); - ghst.safeTransfer(BOB, 420); - _assertVotesEqualToBalance(); - - uint256 aliceBalance = ghst.balanceOf(ALICE); - vm.prank(ALICE); - ghst.safeTransfer(BOB, aliceBalance); - _assertVotesEqualToBalance(); - - vm.prank(BOB); - ghst.safeTransfer(CAROL, 1337); - _assertVotesEqualToBalance(); - - uint256 bobBalance = ghst.balanceOf(BOB); - vm.prank(BOB); - ghst.safeTransfer(CAROL, bobBalance); - _assertVotesEqualToBalance(); - - vm.expectRevert(); - vm.prank(CAROL); - ghst.delegate(CAROL); - - assertEq(ghst.getVotes(ALICE), 0); - assertEq(ghst.getVotes(BOB), 0); - assertEq(ghst.getVotes(CAROL), 69 * 1e18); - - assertEq(ghst.balanceOf(ALICE), 0); - assertEq(ghst.balanceOf(BOB), 0); - assertEq(ghst.balanceOf(CAROL), 69 * 1e18); - - vm.prank(INIT); - ghst.burn(CAROL, 69 * 1e18); - - assertEq(ghst.getVotes(CAROL), 0); - assertEq(ghst.balanceOf(CAROL), 0); - assertEq(ghst.totalSupply(), 0); - } - - function test_changesOfTotalSupplyHasNoAffectOnPastTotalSupply() public { - vm.prank(INIT); - ghst.mint(ALICE, 100); - - vm.roll(block.number + 1); - assertEq(ghst.getPastTotalSupply(block.number - 1), 100); - assertEq(ghst.totalSupply(), 100); - - vm.prank(INIT); - ghst.burn(ALICE, 50); - - vm.roll(block.number + 1); - assertEq(ghst.getPastTotalSupply(block.number - 2), 100); - assertEq(ghst.getPastTotalSupply(block.number - 1), 50); - assertEq(ghst.totalSupply(), 50); - - vm.prank(INIT); - ghst.mint(BOB, 150); - - vm.roll(block.number + 1); - assertEq(ghst.getPastTotalSupply(block.number - 3), 100); - assertEq(ghst.getPastTotalSupply(block.number - 2), 50); - assertEq(ghst.getPastTotalSupply(block.number - 1), 200); - assertEq(ghst.totalSupply(), 200); - } - - function test_proposeAutoForVote() public { - vm.startPrank(INIT); - ghst.mint(ALICE, PROPOSAL_THRESHOLD); - vm.stopPrank(); - - vm.roll(block.number + 1); - (uint256 proposalId,,,,) = _proposeDummy(ALICE, 69); - - (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) = governor.proposalVotes(proposalId); - assertEq(forVotes, PROPOSAL_THRESHOLD); - assertEq(againstVotes, 0); - assertEq(abstainVotes, 0); - - vm.roll(block.number + 1); - - vm.expectRevert(); - vm.prank(ALICE); - governor.castVote(proposalId, 1); - } - - function test_releaseAfterDefeated() public { - vm.startPrank(INIT); - ghst.mint(ALICE, PROPOSAL_THRESHOLD); - ghst.mint(BOB, PROPOSAL_THRESHOLD); - ghst.mint(CAROL, PROPOSAL_THRESHOLD); - vm.stopPrank(); - - vm.roll(block.number + 1); - (uint256 proposalId,,,,) = _proposeDummy(ALICE, 69); - - assertEq(governor.releaseLocked(proposalId), 0); - assertEq(ghst.balanceOf(ALICE), 0); - assertEq(ghst.balanceOf(address(governor)), PROPOSAL_THRESHOLD); - - _waitForActive(proposalId); - _castVoteWrapper(proposalId, BOB, 0, true, false); - _castVoteWrapper(proposalId, CAROL, 0, true, false); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Defeated)); - - assertEq(governor.releaseLocked(proposalId), PROPOSAL_THRESHOLD); - assertEq(ghst.balanceOf(ALICE), PROPOSAL_THRESHOLD); - assertEq(ghst.balanceOf(address(governor)), 0); - } - - function test_releaseAfterSucceeded() public { - vm.startPrank(INIT); - ghst.mint(ALICE, PROPOSAL_THRESHOLD); - ghst.mint(BOB, PROPOSAL_THRESHOLD); - ghst.mint(CAROL, PROPOSAL_THRESHOLD); - vm.stopPrank(); - - vm.roll(block.number + 1); - (uint256 proposalId,,,,) = _proposeDummy(ALICE, 69); - - assertEq(governor.releaseLocked(proposalId), 0); - assertEq(ghst.balanceOf(ALICE), 0); - assertEq(ghst.balanceOf(address(governor)), PROPOSAL_THRESHOLD); - - _waitForActive(proposalId); - _castVoteWrapper(proposalId, BOB, 1, true, true); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Succeeded)); - - assertEq(governor.releaseLocked(proposalId), PROPOSAL_THRESHOLD); - assertEq(ghst.balanceOf(ALICE), PROPOSAL_THRESHOLD); - assertEq(ghst.balanceOf(address(governor)), 0); - } - - function test_releaseAfterDeadline() public { - vm.startPrank(INIT); - ghst.mint(ALICE, PROPOSAL_THRESHOLD); - ghst.mint(BOB, 420 * PROPOSAL_THRESHOLD); - vm.stopPrank(); - - vm.roll(block.number + 1); - (uint256 proposalId,,,,) = _proposeDummy(ALICE, 69); - - assertEq(governor.releaseLocked(proposalId), 0); - assertEq(ghst.balanceOf(ALICE), 0); - assertEq(ghst.balanceOf(address(governor)), PROPOSAL_THRESHOLD); - - _waitForActive(proposalId); - vm.roll(block.number + governor.proposalDeadline(proposalId)); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Defeated)); - - assertEq(governor.releaseLocked(proposalId), PROPOSAL_THRESHOLD); - assertEq(ghst.balanceOf(ALICE), PROPOSAL_THRESHOLD); - assertEq(ghst.balanceOf(address(governor)), 0); - } - - function _proposeDummy(address who, uint256 index) - private - returns ( - uint256 proposalId, - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - string memory description - ) - { - targets = new address[](1); - targets[0] = address(uint160(index + 1)); // forge-lint: disable-line(unsafe-typecast) - - values = new uint256[](1); - values[0] = 0; - - calldatas = new bytes[](1); - calldatas[0] = abi.encodeWithSignature("setVotingDelay(uint48)", 0); - - description = string.concat("Proposal #", Strings.toString(index)); - - vm.prank(who); - proposalId = governor.propose( - targets, - values, - calldatas, - description - ); - - vm.roll(block.number + 1); - } - - function _castVoteWrapper( - uint256 proposalId, - address who, - uint8 vote, - bool isQuorumReached, - bool isVoteSucceeded - ) private { - assertEq(governor.hasVoted(proposalId, who), false); - vm.prank(who); - governor.castVote(proposalId, vote); - assertEq(governor.hasVoted(proposalId, who), true); - assertEq(governor.quorumReached(proposalId), isQuorumReached); - assertEq(governor.voteSucceeded(proposalId), isVoteSucceeded); - } - - function _assertVotesEqualToBalance() private view { - assertEq(ghst.getVotes(ALICE), ghst.balanceOf(ALICE)); - assertEq(ghst.getVotes(BOB), ghst.balanceOf(BOB)); - assertEq(ghst.getVotes(CAROL), ghst.balanceOf(CAROL)); - } - - function _waitForActive(uint256 proposalId) private { - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Pending)); - vm.roll(block.number + VOTING_DELAY + 1); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Active)); - } - - function _waitForSucceed(uint256 proposalId) private { - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Active)); - vm.roll(governor.proposalDeadline(proposalId) + 1); - assertEq(uint8(governor.state(proposalId)), uint8(IGovernor.ProposalState.Succeeded)); - } -} diff --git a/test/tokens/Ghst.t.sol b/test/tokens/Ghst.t.sol index ff0d3d9..82822c8 100644 --- a/test/tokens/Ghst.t.sol +++ b/test/tokens/Ghst.t.sol @@ -7,18 +7,10 @@ import {Stinky} from "../../src/StinkyERC20.sol"; import {GhostAuthority} from "../../src/GhostAuthority.sol"; import {GhostStaking} from "../../src/Staking.sol"; -import {ERC20PermitTest} from "./Permit.t.sol"; import {ERC20AllowanceTest} from "./Allowance.t.sol"; import {ERC20TransferTest} from "./Transfer.t.sol"; -import {ERC20VotesTest} from "./Votes.t.sol"; -contract GhostTest is - Test, - ERC20PermitTest, - ERC20AllowanceTest, - ERC20TransferTest, - ERC20VotesTest -{ +contract GhostTest is Test, ERC20AllowanceTest, ERC20TransferTest { uint256 constant public INITIAL_INDEX = 10819917194513808e56; address constant INITIALIZER = 0x0000000000000000000000000000000000000001; @@ -59,10 +51,8 @@ contract GhostTest is ghst.initialize(address(staking)); vm.stopPrank(); - initializePermit(address(ghst), AMOUNT, MAX_AMOUNT); initializeAllowance(ALICE, BOB, address(ghst), AMOUNT, MAX_AMOUNT, AMOUNT); initializeTransfer(ALICE, BOB, address(ghst), AMOUNT, MAX_AMOUNT); - initializeVotes(ALICE, BOB, address(ghst), AMOUNT); } function test_isConstructedCorrectly() public view { @@ -157,19 +147,6 @@ contract GhostTest is _mintTokens(who, value); } - function _mintPermitTokens(address who, uint256 value) internal override { - _mintTokens(who, value); - } - - function _mintVotesTokens(address who, uint256 value) internal override { - _mintTokens(who, value); - } - - function _burnVotesTokens(address who, uint256 value) internal override { - vm.prank(address(staking)); - ghst.burn(who, value); - } - function _getCurrentTotalSupply() internal override view returns (uint256) { return ghst.totalSupply(); }