diff --git a/test/GovernanceContract.t.sol b/test/GovernanceContract.t.sol new file mode 100644 index 0000000..3848b7f --- /dev/null +++ b/test/GovernanceContract.t.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "forge-std/Test.sol"; +import "../contracts/GovernanceContract.sol"; +import "../contracts/VotingContract.sol"; + +contract GovernanceContractTest is Test { + GovernanceContract public governanceContract; + VotingContract public votingContract; + address public owner; + address public voter1; + address public voter2; + + function setUp() public { + owner = makeAddr("owner"); + voter1 = makeAddr("voter1"); + voter2 = makeAddr("voter2"); + + vm.startPrank(owner); + votingContract = new VotingContract(); + governanceContract = new GovernanceContract(address(votingContract)); + + // Give voting power to test accounts + votingContract.grantVotingPower(voter1, 100); + votingContract.grantVotingPower(voter2, 200); + vm.stopPrank(); + } + + function test_CreateProposal() public { + vm.prank(voter1); + uint256 proposalId = governanceContract.createProposal("Test Proposal"); + + (address proposer, string memory description, , , , GovernanceContract.ProposalStatus status, , ) = governanceContract.proposals(proposalId); + + assertEq(proposer, voter1, "Incorrect proposer"); + assertEq(description, "Test Proposal", "Incorrect description"); + assertEq(uint256(status), uint256(GovernanceContract.ProposalStatus.Active), "Incorrect proposal status"); + } + + function testRevert_CreateProposal_EmptyDescription() public { + vm.expectRevert("Description cannot be empty"); + governanceContract.createProposal(""); + } + + function test_Vote() public { + vm.prank(voter1); + uint256 proposalId = governanceContract.createProposal("Test Proposal"); + + vm.prank(voter1); + governanceContract.vote(proposalId, true); + + vm.prank(voter2); + governanceContract.vote(proposalId, false); + + (, , , , , , uint256 totalVotesFor, uint256 totalVotesAgainst) = governanceContract.proposals(proposalId); + + assertEq(totalVotesFor, 100, "Incorrect votes for"); + assertEq(totalVotesAgainst, 200, "Incorrect votes against"); + } + + function testRevert_Vote_AlreadyVoted() public { + vm.prank(voter1); + uint256 proposalId = governanceContract.createProposal("Test Proposal"); + + vm.prank(voter1); + governanceContract.vote(proposalId, true); + + vm.expectRevert("Already voted"); + vm.prank(voter1); + governanceContract.vote(proposalId, false); + } + + function testRevert_Vote_ProposalNotActive() public { + vm.prank(voter1); + uint256 proposalId = governanceContract.createProposal("Test Proposal"); + + // Simulate time passing + vm.warp(block.timestamp + 8 days); + + vm.expectRevert("Proposal not active"); + vm.prank(voter1); + governanceContract.vote(proposalId, true); + } + + function test_FinalizeProposal_Passed() public { + vm.prank(voter1); + uint256 proposalId = governanceContract.createProposal("Test Proposal"); + + vm.prank(voter1); + governanceContract.vote(proposalId, true); + + vm.prank(voter2); + governanceContract.vote(proposalId, true); + + // Simulate time passing + vm.warp(block.timestamp + 8 days); + + governanceContract.finalizeProposal(proposalId); + + (, , , , , GovernanceContract.ProposalStatus status, , ) = governanceContract.proposals(proposalId); + assertEq(uint256(status), uint256(GovernanceContract.ProposalStatus.Passed), "Proposal should be passed"); + } + + function test_FinalizeProposal_Rejected() public { + vm.prank(voter1); + uint256 proposalId = governanceContract.createProposal("Test Proposal"); + + vm.prank(voter1); + governanceContract.vote(proposalId, false); + + vm.prank(voter2); + governanceContract.vote(proposalId, false); + + // Simulate time passing + vm.warp(block.timestamp + 8 days); + + governanceContract.finalizeProposal(proposalId); + + (, , , , , GovernanceContract.ProposalStatus status, , ) = governanceContract.proposals(proposalId); + assertEq(uint256(status), uint256(GovernanceContract.ProposalStatus.Rejected), "Proposal should be rejected"); + } + + function testFuzz_CreateProposal(string memory description) public { + vm.assume(bytes(description).length > 0); + + vm.prank(voter1); + uint256 proposalId = governanceContract.createProposal(description); + + (, string memory storedDescription, , , , , , ) = governanceContract.proposals(proposalId); + assertEq(storedDescription, description, "Fuzzed proposal description mismatch"); + } + + function testGas_CreateProposal() public { + vm.prank(voter1); + governanceContract.createProposal("Gas Benchmark Proposal"); + } + + function testGas_Vote() public { + vm.prank(voter1); + uint256 proposalId = governanceCont \ No newline at end of file