123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v4.9.0) (governance/extensions/GovernorPreventLateQuorum.sol)
- pragma solidity ^0.8.19;
- import {Governor} from "../Governor.sol";
- import {Math} from "../../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 specified time has passed (the "vote extension" parameter). This parameter can be set through a governance
- * proposal.
- */
- abstract contract GovernorPreventLateQuorum is Governor {
- uint48 private _voteExtension;
- mapping(uint256 => uint48) 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 time in either number of blocks or seconds (depending on the governor
- * clock mode) that is required to pass since the moment a proposal reaches quorum until its voting period ends. If
- * necessary the voting period will be extended beyond the one set during proposal creation.
- */
- constructor(uint48 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]);
- }
- /**
- * @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,
- bytes memory params
- ) internal virtual override returns (uint256) {
- uint256 result = super._castVote(proposalId, account, support, reason, params);
- if (_extendedDeadlines[proposalId] == 0 && _quorumReached(proposalId)) {
- uint48 extendedDeadline = clock() + lateQuorumVoteExtension();
- if (extendedDeadline > proposalDeadline(proposalId)) {
- emit ProposalExtended(proposalId, extendedDeadline);
- }
- _extendedDeadlines[proposalId] = extendedDeadline;
- }
- 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 (uint48) {
- 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(uint48 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(uint48 newVoteExtension) internal virtual {
- emit LateQuorumVoteExtensionSet(_voteExtension, newVoteExtension);
- _voteExtension = newVoteExtension;
- }
- }
|