Files
openzeppelin-contracts/contracts/governance/extensions/GovernorVotesSuperQuorumFraction.sol
github-actions[bot] d183d9b07a Merge release-v5.3 branch (#5632)
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Co-authored-by: Francisco Giordano <fg@frang.io>
Co-authored-by: Joseph Delong <joseph@delong.me>
Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>
Co-authored-by: Renan Souza <renan.rodrigues.souza1@gmail.com>
Co-authored-by: Ernesto García <ernestognw@gmail.com>
Co-authored-by: Voronor <129545215+voronor@users.noreply.github.com>
Co-authored-by: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com>
Co-authored-by: Michalis Kargakis <kargakis@protonmail.com>
Co-authored-by: Bilog WEB3 <155262265+Bilogweb3@users.noreply.github.com>
Co-authored-by: Fallengirl <155266340+Fallengirl@users.noreply.github.com>
Co-authored-by: XxAlex74xX <30472093+XxAlex74xX@users.noreply.github.com>
Co-authored-by: PixelPilot <161360836+PixelPil0t1@users.noreply.github.com>
Co-authored-by: kilavvy <140459108+kilavvy@users.noreply.github.com>
Co-authored-by: Devkuni <155117116+detrina@users.noreply.github.com>
Co-authored-by: Danbo <140512416+dannbbb1@users.noreply.github.com>
Co-authored-by: Ann Wagner <chant_77_swirly@icloud.com>
Co-authored-by: comfsrt <155266597+comfsrt@users.noreply.github.com>
Co-authored-by: Bob <158583129+bouchmann@users.noreply.github.com>
Co-authored-by: JohnBonny <158583902+JohnBonny@users.noreply.github.com>
Co-authored-by: moonman <155266991+moooonman@users.noreply.github.com>
Co-authored-by: kazak <alright-epsilon8h@icloud.com>
Co-authored-by: Wei <ybxerlvqtx@rambler.ru>
Co-authored-by: Maxim Evtush <154841002+maximevtush@users.noreply.github.com>
Co-authored-by: Vitalyr <158586577+Vitaliyr888@users.noreply.github.com>
Co-authored-by: pendrue <158588659+pendrue@users.noreply.github.com>
Co-authored-by: Tronica <wudmytrotest404@gmail.com>
Co-authored-by: emmmm <155267286+eeemmmmmm@users.noreply.github.com>
Co-authored-by: bigbear <155267841+aso20455@users.noreply.github.com>
Co-authored-by: Tomás Andróil <tomasandroil@gmail.com>
Co-authored-by: GooseMatrix <155266802+GooseMatrix@users.noreply.github.com>
Co-authored-by: jasmy <3776356370@qq.com>
Co-authored-by: SITADRITA1 <mrlime2018@gmail.com>
Co-authored-by: Ocenka <testoviydiman1@gmail.com>
2025-04-09 20:47:07 +02:00

135 lines
5.5 KiB
Solidity

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (governance/extensions/GovernorVotesSuperQuorumFraction.sol)
pragma solidity ^0.8.20;
import {Governor} from "../Governor.sol";
import {GovernorSuperQuorum} from "./GovernorSuperQuorum.sol";
import {GovernorVotesQuorumFraction} from "./GovernorVotesQuorumFraction.sol";
import {Math} from "../../utils/math/Math.sol";
import {SafeCast} from "../../utils/math/SafeCast.sol";
import {Checkpoints} from "../../utils/structs/Checkpoints.sol";
/**
* @dev Extension of {GovernorVotesQuorumFraction} with a super quorum expressed as a
* fraction of the total supply. Proposals that meet the super quorum (and have a majority of for votes) advance to
* the `Succeeded` state before the proposal deadline.
*/
abstract contract GovernorVotesSuperQuorumFraction is GovernorVotesQuorumFraction, GovernorSuperQuorum {
using Checkpoints for Checkpoints.Trace208;
Checkpoints.Trace208 private _superQuorumNumeratorHistory;
event SuperQuorumNumeratorUpdated(uint256 oldSuperQuorumNumerator, uint256 newSuperQuorumNumerator);
/**
* @dev The super quorum set is not valid as it exceeds the quorum denominator.
*/
error GovernorInvalidSuperQuorumFraction(uint256 superQuorumNumerator, uint256 denominator);
/**
* @dev The super quorum set is not valid as it is smaller or equal to the quorum.
*/
error GovernorInvalidSuperQuorumTooSmall(uint256 superQuorumNumerator, uint256 quorumNumerator);
/**
* @dev The quorum set is not valid as it exceeds the super quorum.
*/
error GovernorInvalidQuorumTooLarge(uint256 quorumNumerator, uint256 superQuorumNumerator);
/**
* @dev Initialize super quorum as a fraction of the token's total supply.
*
* The super quorum is specified as a fraction of the token's total supply and has to
* be greater than the quorum.
*/
constructor(uint256 superQuorumNumeratorValue) {
_updateSuperQuorumNumerator(superQuorumNumeratorValue);
}
/**
* @dev Returns the current super quorum numerator.
*/
function superQuorumNumerator() public view virtual returns (uint256) {
return _superQuorumNumeratorHistory.latest();
}
/**
* @dev Returns the super quorum numerator at a specific `timepoint`.
*/
function superQuorumNumerator(uint256 timepoint) public view virtual returns (uint256) {
return _optimisticUpperLookupRecent(_superQuorumNumeratorHistory, timepoint);
}
/**
* @dev Returns the super quorum for a `timepoint`, in terms of number of votes: `supply * numerator / denominator`.
* See {GovernorSuperQuorum-superQuorum} for more details.
*/
function superQuorum(uint256 timepoint) public view virtual override returns (uint256) {
return Math.mulDiv(token().getPastTotalSupply(timepoint), superQuorumNumerator(timepoint), quorumDenominator());
}
/**
* @dev Changes the super quorum numerator.
*
* Emits a {SuperQuorumNumeratorUpdated} event.
*
* Requirements:
*
* - Must be called through a governance proposal.
* - New super quorum numerator must be smaller or equal to the denominator.
* - New super quorum numerator must be greater than or equal to the quorum numerator.
*/
function updateSuperQuorumNumerator(uint256 newSuperQuorumNumerator) public virtual onlyGovernance {
_updateSuperQuorumNumerator(newSuperQuorumNumerator);
}
/**
* @dev Changes the super quorum numerator.
*
* Emits a {SuperQuorumNumeratorUpdated} event.
*
* Requirements:
*
* - New super quorum numerator must be smaller or equal to the denominator.
* - New super quorum numerator must be greater than or equal to the quorum numerator.
*/
function _updateSuperQuorumNumerator(uint256 newSuperQuorumNumerator) internal virtual {
uint256 denominator = quorumDenominator();
if (newSuperQuorumNumerator > denominator) {
revert GovernorInvalidSuperQuorumFraction(newSuperQuorumNumerator, denominator);
}
uint256 quorumNumerator = quorumNumerator();
if (newSuperQuorumNumerator < quorumNumerator) {
revert GovernorInvalidSuperQuorumTooSmall(newSuperQuorumNumerator, quorumNumerator);
}
uint256 oldSuperQuorumNumerator = _superQuorumNumeratorHistory.latest();
_superQuorumNumeratorHistory.push(clock(), SafeCast.toUint208(newSuperQuorumNumerator));
emit SuperQuorumNumeratorUpdated(oldSuperQuorumNumerator, newSuperQuorumNumerator);
}
/**
* @dev Overrides {GovernorVotesQuorumFraction-_updateQuorumNumerator} to ensure the super
* quorum numerator is greater than or equal to the quorum numerator.
*/
function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual override {
// Ignoring check when the superQuorum was never set (construction sets quorum before superQuorum)
if (_superQuorumNumeratorHistory.length() > 0) {
uint256 superQuorumNumerator_ = superQuorumNumerator();
if (newQuorumNumerator > superQuorumNumerator_) {
revert GovernorInvalidQuorumTooLarge(newQuorumNumerator, superQuorumNumerator_);
}
}
super._updateQuorumNumerator(newQuorumNumerator);
}
/// @inheritdoc GovernorSuperQuorum
function state(
uint256 proposalId
) public view virtual override(Governor, GovernorSuperQuorum) returns (ProposalState) {
return super.state(proposalId);
}
}