Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test sequential extension contract #60

Merged
merged 1 commit into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions contracts/CompoundGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {ICompoundTimelock} from "@openzeppelin/contracts/vendor/compound/ICompou
import {GovernorSettingsUpgradeable} from "contracts/extensions/GovernorSettingsUpgradeable.sol";
import {GovernorPreventLateQuorumUpgradeable} from "contracts/extensions/GovernorPreventLateQuorumUpgradeable.sol";
import {IComp} from "contracts/interfaces/IComp.sol";
import {GovernorAlphaInterface} from "contracts/GovernorBravoInterfaces.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {GovernorBravoDelegateStorageV1} from "contracts/GovernorBravoInterfaces.sol";

/// @title CompoundGovernor
/// @author [ScopeLift](https://scopelift.co)
Expand Down Expand Up @@ -64,8 +64,8 @@ contract CompoundGovernor is
uint96 expiration;
}

GovernorBravoDelegateStorageV1 private constant compoundGovernorBravo =
GovernorBravoDelegateStorageV1(0xc0Da02939E1441F497fd74F78cE7Decb17B66529);
GovernorAlphaInterface private constant compoundGovernorBravo =
GovernorAlphaInterface(0xc0Da02939E1441F497fd74F78cE7Decb17B66529);

/// @notice Address which manages whitelisted proposals and whitelist accounts.
/// @dev This address has the ability to set account whitelist expirations and can be changed through the governance
Expand Down
121 changes: 121 additions & 0 deletions contracts/test/GovernorSequentialProposalIdUpgradeable.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity 0.8.26;

import {CompoundGovernorTest} from "contracts/test/helpers/CompoundGovernorTest.sol";
import {IGovernor} from "contracts/extensions/IGovernor.sol";
import {GovernorAlphaInterface} from "contracts/GovernorBravoInterfaces.sol";

/// @notice Most governance operations that take a proposal ID parameter (queue, execute, cancel)
/// are extensively tested in CompoundGovernor.t.sol. This test file focuses on the rest of the functionalities.
contract GovernorSequentialProposalIdUpgradeableTest is CompoundGovernorTest {
GovernorAlphaInterface internal constant compoundGovernorBravo =
GovernorAlphaInterface(0xc0Da02939E1441F497fd74F78cE7Decb17B66529);

function _buildBasicProposal(uint256 _newThreshold, string memory _description)
internal
view
returns (Proposal memory _proposal)
{
address[] memory _targets = new address[](1);
_targets[0] = address(governor);

uint256[] memory _values = new uint256[](1);
_values[0] = 0;

bytes[] memory _calldatas = new bytes[](1);
_calldatas[0] = _buildProposalData("setProposalThreshold(uint256)", abi.encode(_newThreshold));
_proposal = Proposal(_targets, _values, _calldatas, _description);
}
}

contract ProposalCount is GovernorSequentialProposalIdUpgradeableTest {
function test_ReturnsCorrectProposalCount() public {
assertEq(governor.proposalCount(), compoundGovernorBravo.proposalCount());
}

function testFuzz_ProposalCreatedEventEmittedWithEnumeratedProposalId(uint256 _newValue) public {
_newValue = bound(_newValue, INITIAL_PROPOSAL_THRESHOLD, INITIAL_PROPOSAL_THRESHOLD + 10);
address _proposer = _getRandomProposer();
string memory _description = "Checking for enumearted proposal IDs on events";
Proposal memory _firstProposal = _buildBasicProposal(_newValue, "First proposal to get and ID");
uint256 _firstProposalId = _submitProposal(_proposer, _firstProposal);
uint256 _originalProposalCount = governor.proposalCount();
Proposal memory _proposal = _buildBasicProposal(_newValue, _description);
vm.expectEmit();
emit IGovernor.ProposalCreated(
_firstProposalId + 1,
_proposer,
_proposal.targets,
_proposal.values,
new string[](_proposal.targets.length),
_proposal.calldatas,
block.number + INITIAL_VOTING_DELAY,
block.number + INITIAL_VOTING_DELAY + INITIAL_VOTING_PERIOD,
_description
);
uint256 _proposalId = _submitProposal(_proposer, _proposal);
assertEq(_proposalId, _firstProposalId + 1);
assertEq(governor.proposalCount(), _originalProposalCount + 1);
}

function testFuzz_ProposalIdsAreSequential(uint256 _newValue) public {
_newValue = bound(_newValue, INITIAL_PROPOSAL_THRESHOLD, INITIAL_PROPOSAL_THRESHOLD + 10);
Proposal memory _proposal1 = _buildBasicProposal(_newValue, "Set New Proposal Threshold");
uint256 _proposalId1 = _submitProposal(_proposal1);
Proposal memory _proposal2 = _buildBasicProposal(_newValue + 1, "Second Proposal");
uint256 _proposalId2 = _submitProposal(_proposal2);
assertEq(_proposalId2, _proposalId1 + 1);
}
}

contract GetNextProposalId is GovernorSequentialProposalIdUpgradeableTest {
function testFuzz_ReturnsCorrectNextProposalId(uint256) public {
uint256 _nextProposalId = governor.getNextProposalId();
assertEq(_nextProposalId, compoundGovernorBravo.proposalCount());
assertTrue(_nextProposalId > 0);
}
}

contract HashProposal is GovernorSequentialProposalIdUpgradeableTest {
function testFuzz_ReturnsCorrectProposalId() public {
address[] memory _targets = new address[](1);
uint256[] memory _values = new uint256[](1);
bytes[] memory _calldatas = new bytes[](1);
bytes32 _descriptionHash = keccak256(bytes("An Empty Proposal"));

uint256 _proposalId = governor.hashProposal(_targets, _values, _calldatas, _descriptionHash);
assertEq(_proposalId, governor.getNextProposalId());
assertTrue(_proposalId > 0);
}
}

contract ProposalDetails is GovernorSequentialProposalIdUpgradeableTest {
function testFuzz_ReturnsCorrectProposalDetails(
address _expectedTarget,
uint256 _expectedValue,
bytes memory _expectedCalldatas,
string memory _expectedDescription
) public {
address[] memory _targets = new address[](1);
_targets[0] = _expectedTarget;
uint256[] memory _values = new uint256[](1);
_values[0] = _expectedValue;
bytes[] memory _calldatas = new bytes[](1);
_calldatas[0] = _expectedCalldatas;

Proposal memory _proposal = Proposal(_targets, _values, _calldatas, _expectedDescription);
uint256 _proposalId = _submitProposal(_proposal);

(
address[] memory _returnedTargets,
uint256[] memory _returnedValues,
bytes[] memory _returnedCalldatas,
bytes32 _returnedDescriptionHash
) = governor.proposalDetails(_proposalId);

assertEq(_returnedTargets[0], _expectedTarget);
assertEq(_returnedValues[0], _expectedValue);
assertEq(_returnedCalldatas[0], _expectedCalldatas);
assertEq(keccak256(bytes(_expectedDescription)), _returnedDescriptionHash);
}
}
Loading