Skip to content

Commit abeb0fb

Browse files
Amxxfrangio
andauthored
Delay the Pending state until strictly after proposal.voteStart (#2892)
Co-authored-by: Francisco Giordano <[email protected]>
1 parent caba6b9 commit abeb0fb

File tree

5 files changed

+17
-9
lines changed

5 files changed

+17
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* `AccessControl`: mark `_setupRole(bytes32,address)` as deprecated in favor of `_grantRole(bytes32,address)`. ([#2568](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2568))
88
* `EIP712`: cache `address(this)` to immutable storage to avoid potential issues if a vanilla contract is used in a delegatecall context. ([#2852](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2852))
99
* Add internal `_setApprovalForAll` to `ERC721` and `ERC1155`. ([#2834](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2834))
10+
* `Governor`: shift vote start and end by one block to better match Compound's GovernorBravo and prevent voting at the Governor level if the voting snapshot is not ready. ([#2892](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/#2892))
1011

1112
## 4.3.2 (2021-09-14)
1213

contracts/governance/Governor.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor {
115115
return ProposalState.Executed;
116116
} else if (proposal.canceled) {
117117
return ProposalState.Canceled;
118-
} else if (proposal.voteStart.isPending()) {
118+
} else if (proposal.voteStart.getDeadline() >= block.number) {
119119
return ProposalState.Pending;
120-
} else if (proposal.voteEnd.isPending()) {
120+
} else if (proposal.voteEnd.getDeadline() >= block.number) {
121121
return ProposalState.Active;
122122
} else if (proposal.voteEnd.isExpired()) {
123123
return

contracts/governance/IGovernor.sol

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,28 +103,31 @@ abstract contract IGovernor is IERC165 {
103103

104104
/**
105105
* @notice module:core
106-
* @dev block number used to retrieve user's votes and quorum.
106+
* @dev Block number used to retrieve user's votes and quorum. As per Compound's Comp and OpenZeppelin's
107+
* ERC20Votes, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the
108+
* beginning of the following block.
107109
*/
108110
function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);
109111

110112
/**
111113
* @notice module:core
112-
* @dev timestamp at which votes close.
114+
* @dev Block number at which votes close. Votes close at the end of this block, so it is possible to cast a vote
115+
* during this block.
113116
*/
114117
function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);
115118

116119
/**
117120
* @notice module:user-config
118-
* @dev delay, in number of block, between the proposal is created and the vote starts. This can be increassed to
121+
* @dev Delay, in number of block, between the proposal is created and the vote starts. This can be increassed to
119122
* leave time for users to buy voting power, of delegate it, before the voting of a proposal starts.
120123
*/
121124
function votingDelay() public view virtual returns (uint256);
122125

123126
/**
124127
* @notice module:user-config
125-
* @dev delay, in number of blocks, between the vote start and vote ends.
128+
* @dev Delay, in number of blocks, between the vote start and vote ends.
126129
*
127-
* Note: the {votingDelay} can delay the start of the vote. This must be considered when setting the voting
130+
* NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting
128131
* duration compared to the voting delay.
129132
*/
130133
function votingPeriod() public view virtual returns (uint256);

test/governance/Governor.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,10 @@ contract('Governor', function (accounts) {
559559

560560
await time.advanceBlockTo(this.snapshot);
561561

562+
expect(await this.mock.state(this.id)).to.be.bignumber.equal(Enums.ProposalState.Pending);
563+
564+
await time.advanceBlock();
565+
562566
expect(await this.mock.state(this.id)).to.be.bignumber.equal(Enums.ProposalState.Active);
563567
});
564568
runGovernorWorkflow();

test/governance/GovernorWorkflow.behavior.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function runGovernorWorkflow () {
5858
tryGet(this.settings, 'steps.propose.error') === undefined &&
5959
tryGet(this.settings, 'steps.propose.noadvance') !== true
6060
) {
61-
await time.advanceBlockTo(this.snapshot);
61+
await time.advanceBlockTo(this.snapshot.addn(1));
6262
}
6363
}
6464

@@ -92,7 +92,7 @@ function runGovernorWorkflow () {
9292

9393
// fast forward
9494
if (tryGet(this.settings, 'steps.wait.enable') !== false) {
95-
await time.advanceBlockTo(this.deadline);
95+
await time.advanceBlockTo(this.deadline.addn(1));
9696
}
9797

9898
// queue

0 commit comments

Comments
 (0)