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