diff --git a/src/interface/IGovernor.sol b/src/interface/IGovernor.sol index 7d15622..315d0eb 100644 --- a/src/interface/IGovernor.sol +++ b/src/interface/IGovernor.sol @@ -90,7 +90,7 @@ interface IGovernor { * {proposalDeadline}, this doesn't use the governor clock, and instead relies on the executor's clock which may be * different. In most cases this will be a timestamp. */ - function proposalEta(uint256 proposalId) external view returns (uint256); + function proposaleta(uint256 proposalId) external view returns (uint256); /** * @notice module:core diff --git a/src/proposals/GovernorOZProposal.sol b/src/proposals/GovernorOZProposal.sol index 70af903..c91789c 100644 --- a/src/proposals/GovernorOZProposal.sol +++ b/src/proposals/GovernorOZProposal.sol @@ -85,10 +85,11 @@ abstract contract GovernorOZProposal is Proposal { ? quorumVotes : proposalThreshold; deal(address(governanceToken), proposerAddress, votingPower); + vm.roll(block.number - 1); // Delegate proposer's votes to itself vm.prank(proposerAddress); IVotes(governanceToken).delegate(proposerAddress); - vm.roll(block.number + 1); + vm.roll(block.number + 2); } bytes memory proposeCalldata = getCalldata(); @@ -96,7 +97,24 @@ abstract contract GovernorOZProposal is Proposal { // Register the proposal vm.prank(proposerAddress); bytes memory data = address(governor).functionCall(proposeCalldata); - uint256 proposalId = abi.decode(data, (uint256)); + + uint256 returnedProposalId = abi.decode(data, (uint256)); + + ( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas + ) = getProposalActions(); + + // Check that the proposal was registered correctly + uint256 proposalId = governor.hashProposal( + targets, + values, + calldatas, + keccak256(abi.encodePacked(description())) + ); + + require(returnedProposalId == proposalId, "Proposal id mismatch"); // Check proposal is in Pending state require( @@ -105,6 +123,7 @@ abstract contract GovernorOZProposal is Proposal { // Roll to Active state (voting period) vm.roll(block.number + governor.votingDelay() + 1); + require( governor.state(proposalId) == IGovernor.ProposalState.Active ); @@ -115,15 +134,13 @@ abstract contract GovernorOZProposal is Proposal { // Roll to allow proposal state transitions vm.roll(block.number + governor.votingPeriod()); + require( governor.state(proposalId) == IGovernor.ProposalState.Succeeded ); - ( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas - ) = getProposalActions(); + + vm.warp(block.timestamp + governor.proposalEta(proposalId) + 1); // Queue the proposal governor.queue(targets, values, calldatas, keccak256(abi.encodePacked(description()))); diff --git a/src/proposals/IProposal.sol b/src/proposals/IProposal.sol index dc0ae28..f6e1e44 100644 --- a/src/proposals/IProposal.sol +++ b/src/proposals/IProposal.sol @@ -67,6 +67,6 @@ interface IProposal { /// @notice set the Addresses contract function setAddresses(Addresses _addresses) external; - /// @notice set primary fork id + /// @notice set the primary fork id function setPrimaryForkId(uint256 _forkId) external; }