commit
8c0684ad13
@ -0,0 +1,106 @@ |
||||
// SPDX-License-Identifier: MIT |
||||
|
||||
pragma solidity ^0.8.0; |
||||
|
||||
import "../Governor.sol"; |
||||
import "../../utils/math/Math.sol"; |
||||
|
||||
/** |
||||
* @dev A module that ensures there is a minimum voting period after quorum is reached. This prevents a large voter from |
||||
* swaying a vote and triggering quorum at the last minute, by ensuring there is always time for other voters to react |
||||
* and try to oppose the decision. |
||||
* |
||||
* If a vote causes quorum to be reached, the proposal's voting period may be extended so that it does not end before at |
||||
* least a given number of blocks have passed (the "vote extension" parameter). This parameter can be set by the |
||||
* governance executor (e.g. through a governance proposal). |
||||
* |
||||
* _Available since v4.5._ |
||||
*/ |
||||
abstract contract GovernorPreventLateQuorum is Governor { |
||||
using SafeCast for uint256; |
||||
using Timers for Timers.BlockNumber; |
||||
|
||||
uint64 private _voteExtension; |
||||
mapping(uint256 => Timers.BlockNumber) private _extendedDeadlines; |
||||
|
||||
/// @dev Emitted when a proposal deadline is pushed back due to reaching quorum late in its voting period. |
||||
event ProposalExtended(uint256 indexed proposalId, uint64 extendedDeadline); |
||||
|
||||
/// @dev Emitted when the {lateQuorumVoteExtension} parameter is changed. |
||||
event LateQuorumVoteExtensionSet(uint64 oldVoteExtension, uint64 newVoteExtension); |
||||
|
||||
/** |
||||
* @dev Initializes the vote extension parameter: the number of blocks that are required to pass since a proposal |
||||
* reaches quorum until its voting period ends. If necessary the voting period will be extended beyond the one set |
||||
* at proposal creation. |
||||
*/ |
||||
constructor(uint64 initialVoteExtension) { |
||||
_setLateQuorumVoteExtension(initialVoteExtension); |
||||
} |
||||
|
||||
/** |
||||
* @dev Returns the proposal deadline, which may have been extended beyond that set at proposal creation, if the |
||||
* proposal reached quorum late in the voting period. See {Governor-proposalDeadline}. |
||||
*/ |
||||
function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) { |
||||
return Math.max(super.proposalDeadline(proposalId), _extendedDeadlines[proposalId].getDeadline()); |
||||
} |
||||
|
||||
/** |
||||
* @dev Casts a vote and detects if it caused quorum to be reached, potentially extending the voting period. See |
||||
* {Governor-_castVote}. |
||||
* |
||||
* May emit a {ProposalExtended} event. |
||||
*/ |
||||
function _castVote( |
||||
uint256 proposalId, |
||||
address account, |
||||
uint8 support, |
||||
string memory reason |
||||
) internal virtual override returns (uint256) { |
||||
uint256 result = super._castVote(proposalId, account, support, reason); |
||||
|
||||
Timers.BlockNumber storage extendedDeadline = _extendedDeadlines[proposalId]; |
||||
|
||||
if (extendedDeadline.isUnset() && _quorumReached(proposalId)) { |
||||
uint64 extendedDeadlineValue = block.number.toUint64() + lateQuorumVoteExtension(); |
||||
|
||||
if (extendedDeadlineValue > proposalDeadline(proposalId)) { |
||||
emit ProposalExtended(proposalId, extendedDeadlineValue); |
||||
} |
||||
|
||||
extendedDeadline.setDeadline(extendedDeadlineValue); |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* @dev Returns the current value of the vote extension parameter: the number of blocks that are required to pass |
||||
* from the time a proposal reaches quorum until its voting period ends. |
||||
*/ |
||||
function lateQuorumVoteExtension() public view virtual returns (uint64) { |
||||
return _voteExtension; |
||||
} |
||||
|
||||
/** |
||||
* @dev Changes the {lateQuorumVoteExtension}. This operation can only be performed by the governance executor, |
||||
* generally through a governance proposal. |
||||
* |
||||
* Emits a {LateQuorumVoteExtensionSet} event. |
||||
*/ |
||||
function setLateQuorumVoteExtension(uint64 newVoteExtension) public virtual onlyGovernance { |
||||
_setLateQuorumVoteExtension(newVoteExtension); |
||||
} |
||||
|
||||
/** |
||||
* @dev Changes the {lateQuorumVoteExtension}. This is an internal function that can be exposed in a public function |
||||
* like {setLateQuorumVoteExtension} if another access control mechanism is needed. |
||||
* |
||||
* Emits a {LateQuorumVoteExtensionSet} event. |
||||
*/ |
||||
function _setLateQuorumVoteExtension(uint64 newVoteExtension) internal virtual { |
||||
emit LateQuorumVoteExtensionSet(_voteExtension, newVoteExtension); |
||||
_voteExtension = newVoteExtension; |
||||
} |
||||
} |
@ -0,0 +1,60 @@ |
||||
// SPDX-License-Identifier: MIT |
||||
|
||||
pragma solidity ^0.8.0; |
||||
|
||||
import "../governance/extensions/GovernorPreventLateQuorum.sol"; |
||||
import "../governance/extensions/GovernorSettings.sol"; |
||||
import "../governance/extensions/GovernorCountingSimple.sol"; |
||||
import "../governance/extensions/GovernorVotes.sol"; |
||||
|
||||
contract GovernorPreventLateQuorumMock is |
||||
GovernorSettings, |
||||
GovernorVotes, |
||||
GovernorCountingSimple, |
||||
GovernorPreventLateQuorum |
||||
{ |
||||
uint256 private _quorum; |
||||
|
||||
constructor( |
||||
string memory name_, |
||||
ERC20Votes token_, |
||||
uint256 votingDelay_, |
||||
uint256 votingPeriod_, |
||||
uint256 quorum_, |
||||
uint64 voteExtension_ |
||||
) |
||||
Governor(name_) |
||||
GovernorSettings(votingDelay_, votingPeriod_, 0) |
||||
GovernorVotes(token_) |
||||
GovernorPreventLateQuorum(voteExtension_) |
||||
{ |
||||
_quorum = quorum_; |
||||
} |
||||
|
||||
function quorum(uint256) public view virtual override returns (uint256) { |
||||
return _quorum; |
||||
} |
||||
|
||||
function proposalDeadline(uint256 proposalId) |
||||
public |
||||
view |
||||
virtual |
||||
override(Governor, GovernorPreventLateQuorum) |
||||
returns (uint256) |
||||
{ |
||||
return super.proposalDeadline(proposalId); |
||||
} |
||||
|
||||
function proposalThreshold() public view virtual override(Governor, GovernorSettings) returns (uint256) { |
||||
return super.proposalThreshold(); |
||||
} |
||||
|
||||
function _castVote( |
||||
uint256 proposalId, |
||||
address account, |
||||
uint8 support, |
||||
string memory reason |
||||
) internal virtual override(Governor, GovernorPreventLateQuorum) returns (uint256) { |
||||
return super._castVote(proposalId, account, support, reason); |
||||
} |
||||
} |
@ -0,0 +1 @@ |
||||
Contract presets are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com/) as a more powerful alternative. |
@ -0,0 +1 @@ |
||||
Contract presets are now deprecated in favor of [Contracts Wizard](https://wizard.openzeppelin.com/) as a more powerful alternative. |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue