Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"src/TurtleGovernor.sol": {
"content": "// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.2.0
pragma solidity =0.8.26;
import { GovernorVotesQuorumFractionUpgradeable } from
"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
import { GovernorTimelockControlUpgradeable } from
"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorTimelockControlUpgradeable.sol";
import { GovernorCountingSimpleUpgradeable } from
"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorCountingSimpleUpgradeable.sol";
import { GovernorSettingsUpgradeable } from
"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol";
import { GovernorStorageUpgradeable } from
"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorStorageUpgradeable.sol";
import { GovernorVotesUpgradeable } from
"@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol";
import { TimelockControllerUpgradeable } from
"@openzeppelin/contracts-upgradeable/governance/TimelockControllerUpgradeable.sol";
import { GovernorUpgradeable } from "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol";
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { IVotes } from "@openzeppelin/contracts/governance/utils/IVotes.sol";
/*
* @title Turtle Governor
* @dev Governor contract for Turtle DAO
*/
contract TurtleGovernor is
Initializable,
GovernorUpgradeable,
GovernorSettingsUpgradeable,
GovernorCountingSimpleUpgradeable,
GovernorStorageUpgradeable,
GovernorVotesUpgradeable,
GovernorVotesQuorumFractionUpgradeable,
GovernorTimelockControlUpgradeable,
OwnableUpgradeable,
UUPSUpgradeable
{
error InvalidAddress();
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
/*
* @dev Initialize the Turtle Governor contract
* @param _token Address of the voting token
* @param _timelock Address of the timelock contract
* @param _initialVotingDelay Initial voting delay
* @param _initialVotingPeriod Initial voting period
* @param _initialProposalThreshold Initial proposal threshold
* @param _quorumFraction Quorum fraction
*/
function initialize(
IVotes _token,
TimelockControllerUpgradeable _timelock,
uint48 _initialVotingDelay,
uint32 _initialVotingPeriod,
uint _initialProposalThreshold,
uint8 _quorumFraction
) public initializer {
// check addresses
if (address(_token) == address(0)) {
revert InvalidAddress();
}
if (address(_timelock) == address(0)) {
revert InvalidAddress();
}
__Governor_init("TurtleGovernor");
__GovernorSettings_init(_initialVotingDelay, _initialVotingPeriod, _initialProposalThreshold);
__GovernorCountingSimple_init();
__GovernorStorage_init();
__GovernorVotes_init(_token);
__GovernorVotesQuorumFraction_init(_quorumFraction);
__GovernorTimelockControl_init(_timelock);
__Ownable_init(address(_timelock));
__UUPSUpgradeable_init();
}
// Management functions only intented to be called by the DAO
/* solhint-disable no-empty-blocks */
/*
* @inheritdoc UUPSUpgradeable
*/
function _authorizeUpgrade(
address
) internal override onlyOwner { }
/* solhint-enable no-empty-blocks */
// The following functions are overrides required by Solidity.
/*
* @inheritdoc GovernorUpgradeable
*/
function votingDelay() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint) {
return super.votingDelay();
}
/*
* @inheritdoc GovernorUpgradeable
*/
function votingPeriod() public view override(GovernorUpgradeable, GovernorSettingsUpgradeable) returns (uint) {
return super.votingPeriod();
}
/*
* @inheritdoc GovernorUpgradeable
*/
function quorum(
uint blockNumber
) public view override(GovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable) returns (uint) {
return super.quorum(blockNumber);
}
/*
* @inheritdoc GovernorUpgradeable
*/
function state(
uint proposalId
) public view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (ProposalState) {
return super.state(proposalId);
}
/*
* @inheritdoc GovernorUpgradeable
*/
function proposalNeedsQueuing(
uint proposalId
) public view override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (bool) {
return super.proposalNeedsQueuing(proposalId);
}
/*
* @inheritdoc GovernorUpgradeable
*/
function proposalThreshold()
public
view
override(GovernorUpgradeable, GovernorSettingsUpgradeable)
returns (uint)
{
return super.proposalThreshold();
}
/*
* @inheritdoc GovernorUpgradeable
*/
function _propose(
address[] memory targets,
uint[] memory values,
bytes[] memory calldatas,
string memory description,
address proposer
) internal override(GovernorUpgradeable, GovernorStorageUpgradeable) returns (uint) {
return super._propose(targets, values, calldatas, description, proposer);
}
/*
* @inheritdoc GovernorUpgradeable
*/
function _queueOperations(
uint proposalId,
address[] memory targets,
uint[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint48) {
return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash);
}
/*
* @inheritdoc GovernorUpgradeable
*/
function _executeOperations(
uint proposalId,
address[] memory targets,
uint[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) {
super._executeOperations(proposalId, targets, values, calldatas, descriptionHash);
}
/*
* @inheritdoc GovernorUpgradeable
*/
function _cancel(
address[] memory targets,
uint[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal override(GovernorUpgradeable, GovernorTimelockControlUpgradeable) returns (uint) {
return super._cancel(targets, values, calldatas, descriptionHash);
}
/*
* @inheritdoc GovernorUpgradeable
*/
function _executor()
internal
view
override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
returns (address)
{
return super._executor();
}
}
"
},
"lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorVotesQuorumFraction.sol)
pragma solidity ^0.8.20;
import {GovernorVotesUpgradeable} from "./GovernorVotesUpgradeable.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {Checkpoints} from "@openzeppelin/contracts/utils/structs/Checkpoints.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token and a quorum expressed as a
* fraction of the total supply.
*/
abstract contract GovernorVotesQuorumFractionUpgradeable is Initializable, GovernorVotesUpgradeable {
using Checkpoints for Checkpoints.Trace208;
/// @custom:storage-location erc7201:openzeppelin.storage.GovernorVotesQuorumFraction
struct GovernorVotesQuorumFractionStorage {
Checkpoints.Trace208 _quorumNumeratorHistory;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.GovernorVotesQuorumFraction")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant GovernorVotesQuorumFractionStorageLocation = 0xe770710421fd2cad75ad828c61aa98f2d77d423a440b67872d0f65554148e000;
function _getGovernorVotesQuorumFractionStorage() private pure returns (GovernorVotesQuorumFractionStorage storage $) {
assembly {
$.slot := GovernorVotesQuorumFractionStorageLocation
}
}
event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);
/**
* @dev The quorum set is not a valid fraction.
*/
error GovernorInvalidQuorumFraction(uint256 quorumNumerator, uint256 quorumDenominator);
/**
* @dev Initialize quorum as a fraction of the token's total supply.
*
* The fraction is specified as `numerator / denominator`. By default the denominator is 100, so quorum is
* specified as a percent: a numerator of 10 corresponds to quorum being 10% of total supply. The denominator can be
* customized by overriding {quorumDenominator}.
*/
function __GovernorVotesQuorumFraction_init(uint256 quorumNumeratorValue) internal onlyInitializing {
__GovernorVotesQuorumFraction_init_unchained(quorumNumeratorValue);
}
function __GovernorVotesQuorumFraction_init_unchained(uint256 quorumNumeratorValue) internal onlyInitializing {
_updateQuorumNumerator(quorumNumeratorValue);
}
/**
* @dev Returns the current quorum numerator. See {quorumDenominator}.
*/
function quorumNumerator() public view virtual returns (uint256) {
GovernorVotesQuorumFractionStorage storage $ = _getGovernorVotesQuorumFractionStorage();
return $._quorumNumeratorHistory.latest();
}
/**
* @dev Returns the quorum numerator at a specific timepoint. See {quorumDenominator}.
*/
function quorumNumerator(uint256 timepoint) public view virtual returns (uint256) {
GovernorVotesQuorumFractionStorage storage $ = _getGovernorVotesQuorumFractionStorage();
uint256 length = $._quorumNumeratorHistory._checkpoints.length;
// Optimistic search, check the latest checkpoint
Checkpoints.Checkpoint208 storage latest = $._quorumNumeratorHistory._checkpoints[length - 1];
uint48 latestKey = latest._key;
uint208 latestValue = latest._value;
if (latestKey <= timepoint) {
return latestValue;
}
// Otherwise, do the binary search
return $._quorumNumeratorHistory.upperLookupRecent(SafeCast.toUint48(timepoint));
}
/**
* @dev Returns the quorum denominator. Defaults to 100, but may be overridden.
*/
function quorumDenominator() public view virtual returns (uint256) {
return 100;
}
/**
* @dev Returns the quorum for a timepoint, in terms of number of votes: `supply * numerator / denominator`.
*/
function quorum(uint256 timepoint) public view virtual override returns (uint256) {
return (token().getPastTotalSupply(timepoint) * quorumNumerator(timepoint)) / quorumDenominator();
}
/**
* @dev Changes the quorum numerator.
*
* Emits a {QuorumNumeratorUpdated} event.
*
* Requirements:
*
* - Must be called through a governance proposal.
* - New numerator must be smaller or equal to the denominator.
*/
function updateQuorumNumerator(uint256 newQuorumNumerator) external virtual onlyGovernance {
_updateQuorumNumerator(newQuorumNumerator);
}
/**
* @dev Changes the quorum numerator.
*
* Emits a {QuorumNumeratorUpdated} event.
*
* Requirements:
*
* - New numerator must be smaller or equal to the denominator.
*/
function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual {
GovernorVotesQuorumFractionStorage storage $ = _getGovernorVotesQuorumFractionStorage();
uint256 denominator = quorumDenominator();
if (newQuorumNumerator > denominator) {
revert GovernorInvalidQuorumFraction(newQuorumNumerator, denominator);
}
uint256 oldQuorumNumerator = quorumNumerator();
$._quorumNumeratorHistory.push(clock(), SafeCast.toUint208(newQuorumNumerator));
emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator);
}
}
"
},
"lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorTimelockControlUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (governance/extensions/GovernorTimelockControl.sol)
pragma solidity ^0.8.20;
import {IGovernor} from "@openzeppelin/contracts/governance/IGovernor.sol";
import {GovernorUpgradeable} from "../GovernorUpgradeable.sol";
import {TimelockControllerUpgradeable} from "../TimelockControllerUpgradeable.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} that binds the execution process to an instance of {TimelockController}. This adds a
* delay, enforced by the {TimelockController} to all successful proposal (in addition to the voting duration). The
* {Governor} needs the proposer (and ideally the executor and canceller) roles for the {Governor} to work properly.
*
* Using this model means the proposal will be operated by the {TimelockController} and not by the {Governor}. Thus,
* the assets and permissions must be attached to the {TimelockController}. Any asset sent to the {Governor} will be
* inaccessible from a proposal, unless executed via {Governor-relay}.
*
* WARNING: Setting up the TimelockController to have additional proposers or cancellers besides the governor is very
* risky, as it grants them the ability to: 1) execute operations as the timelock, and thus possibly performing
* operations or accessing funds that are expected to only be accessible through a vote, and 2) block governance
* proposals that have been approved by the voters, effectively executing a Denial of Service attack.
*/
abstract contract GovernorTimelockControlUpgradeable is Initializable, GovernorUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.GovernorTimelockControl
struct GovernorTimelockControlStorage {
TimelockControllerUpgradeable _timelock;
mapping(uint256 proposalId => bytes32) _timelockIds;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.GovernorTimelockControl")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant GovernorTimelockControlStorageLocation = 0x0d5829787b8befdbc6044ef7457d8a95c2a04bc99235349f1a212c063e59d400;
function _getGovernorTimelockControlStorage() private pure returns (GovernorTimelockControlStorage storage $) {
assembly {
$.slot := GovernorTimelockControlStorageLocation
}
}
/**
* @dev Emitted when the timelock controller used for proposal execution is modified.
*/
event TimelockChange(address oldTimelock, address newTimelock);
/**
* @dev Set the timelock.
*/
function __GovernorTimelockControl_init(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing {
__GovernorTimelockControl_init_unchained(timelockAddress);
}
function __GovernorTimelockControl_init_unchained(TimelockControllerUpgradeable timelockAddress) internal onlyInitializing {
_updateTimelock(timelockAddress);
}
/**
* @dev Overridden version of the {Governor-state} function that considers the status reported by the timelock.
*/
function state(uint256 proposalId) public view virtual override returns (ProposalState) {
GovernorTimelockControlStorage storage $ = _getGovernorTimelockControlStorage();
ProposalState currentState = super.state(proposalId);
if (currentState != ProposalState.Queued) {
return currentState;
}
bytes32 queueid = $._timelockIds[proposalId];
if ($._timelock.isOperationPending(queueid)) {
return ProposalState.Queued;
} else if ($._timelock.isOperationDone(queueid)) {
// This can happen if the proposal is executed directly on the timelock.
return ProposalState.Executed;
} else {
// This can happen if the proposal is canceled directly on the timelock.
return ProposalState.Canceled;
}
}
/**
* @dev Public accessor to check the address of the timelock
*/
function timelock() public view virtual returns (address) {
GovernorTimelockControlStorage storage $ = _getGovernorTimelockControlStorage();
return address($._timelock);
}
/**
* @dev See {IGovernor-proposalNeedsQueuing}.
*/
function proposalNeedsQueuing(uint256) public view virtual override returns (bool) {
return true;
}
/**
* @dev Function to queue a proposal to the timelock.
*/
function _queueOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override returns (uint48) {
GovernorTimelockControlStorage storage $ = _getGovernorTimelockControlStorage();
uint256 delay = $._timelock.getMinDelay();
bytes32 salt = _timelockSalt(descriptionHash);
$._timelockIds[proposalId] = $._timelock.hashOperationBatch(targets, values, calldatas, 0, salt);
$._timelock.scheduleBatch(targets, values, calldatas, 0, salt, delay);
return SafeCast.toUint48(block.timestamp + delay);
}
/**
* @dev Overridden version of the {Governor-_executeOperations} function that runs the already queued proposal
* through the timelock.
*/
function _executeOperations(
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override {
GovernorTimelockControlStorage storage $ = _getGovernorTimelockControlStorage();
// execute
$._timelock.executeBatch{value: msg.value}(targets, values, calldatas, 0, _timelockSalt(descriptionHash));
// cleanup for refund
delete $._timelockIds[proposalId];
}
/**
* @dev Overridden version of the {Governor-_cancel} function to cancel the timelocked proposal if it has already
* been queued.
*/
// This function can reenter through the external call to the timelock, but we assume the timelock is trusted and
// well behaved (according to TimelockController) and this will not happen.
// slither-disable-next-line reentrancy-no-eth
function _cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) internal virtual override returns (uint256) {
GovernorTimelockControlStorage storage $ = _getGovernorTimelockControlStorage();
uint256 proposalId = super._cancel(targets, values, calldatas, descriptionHash);
bytes32 timelockId = $._timelockIds[proposalId];
if (timelockId != 0) {
// cancel
$._timelock.cancel(timelockId);
// cleanup
delete $._timelockIds[proposalId];
}
return proposalId;
}
/**
* @dev Address through which the governor executes action. In this case, the timelock.
*/
function _executor() internal view virtual override returns (address) {
GovernorTimelockControlStorage storage $ = _getGovernorTimelockControlStorage();
return address($._timelock);
}
/**
* @dev Public endpoint to update the underlying timelock instance. Restricted to the timelock itself, so updates
* must be proposed, scheduled, and executed through governance proposals.
*
* CAUTION: It is not recommended to change the timelock while there are other queued governance proposals.
*/
function updateTimelock(TimelockControllerUpgradeable newTimelock) external virtual onlyGovernance {
_updateTimelock(newTimelock);
}
function _updateTimelock(TimelockControllerUpgradeable newTimelock) private {
GovernorTimelockControlStorage storage $ = _getGovernorTimelockControlStorage();
emit TimelockChange(address($._timelock), address(newTimelock));
$._timelock = newTimelock;
}
/**
* @dev Computes the {TimelockController} operation salt.
*
* It is computed with the governor address itself to avoid collisions across governor instances using the
* same timelock.
*/
function _timelockSalt(bytes32 descriptionHash) private view returns (bytes32) {
return bytes20(address(this)) ^ descriptionHash;
}
}
"
},
"lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorCountingSimpleUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (governance/extensions/GovernorCountingSimple.sol)
pragma solidity ^0.8.20;
import {GovernorUpgradeable} from "../GovernorUpgradeable.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for simple, 3 options, vote counting.
*/
abstract contract GovernorCountingSimpleUpgradeable is Initializable, GovernorUpgradeable {
/**
* @dev Supported vote types. Matches Governor Bravo ordering.
*/
enum VoteType {
Against,
For,
Abstain
}
struct ProposalVote {
uint256 againstVotes;
uint256 forVotes;
uint256 abstainVotes;
mapping(address voter => bool) hasVoted;
}
/// @custom:storage-location erc7201:openzeppelin.storage.GovernorCountingSimple
struct GovernorCountingSimpleStorage {
mapping(uint256 proposalId => ProposalVote) _proposalVotes;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.GovernorCountingSimple")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant GovernorCountingSimpleStorageLocation = 0xa1cefa0f43667ef127a258e673c94202a79b656e62899531c4376d87a7f39800;
function _getGovernorCountingSimpleStorage() private pure returns (GovernorCountingSimpleStorage storage $) {
assembly {
$.slot := GovernorCountingSimpleStorageLocation
}
}
function __GovernorCountingSimple_init() internal onlyInitializing {
}
function __GovernorCountingSimple_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IGovernor-COUNTING_MODE}.
*/
// solhint-disable-next-line func-name-mixedcase
function COUNTING_MODE() public pure virtual override returns (string memory) {
return "support=bravo&quorum=for,abstain";
}
/**
* @dev See {IGovernor-hasVoted}.
*/
function hasVoted(uint256 proposalId, address account) public view virtual override returns (bool) {
GovernorCountingSimpleStorage storage $ = _getGovernorCountingSimpleStorage();
return $._proposalVotes[proposalId].hasVoted[account];
}
/**
* @dev Accessor to the internal vote counts.
*/
function proposalVotes(
uint256 proposalId
) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) {
GovernorCountingSimpleStorage storage $ = _getGovernorCountingSimpleStorage();
ProposalVote storage proposalVote = $._proposalVotes[proposalId];
return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes);
}
/**
* @dev See {Governor-_quorumReached}.
*/
function _quorumReached(uint256 proposalId) internal view virtual override returns (bool) {
GovernorCountingSimpleStorage storage $ = _getGovernorCountingSimpleStorage();
ProposalVote storage proposalVote = $._proposalVotes[proposalId];
return quorum(proposalSnapshot(proposalId)) <= proposalVote.forVotes + proposalVote.abstainVotes;
}
/**
* @dev See {Governor-_voteSucceeded}. In this module, the forVotes must be strictly over the againstVotes.
*/
function _voteSucceeded(uint256 proposalId) internal view virtual override returns (bool) {
GovernorCountingSimpleStorage storage $ = _getGovernorCountingSimpleStorage();
ProposalVote storage proposalVote = $._proposalVotes[proposalId];
return proposalVote.forVotes > proposalVote.againstVotes;
}
/**
* @dev See {Governor-_countVote}. In this module, the support follows the `VoteType` enum (from Governor Bravo).
*/
function _countVote(
uint256 proposalId,
address account,
uint8 support,
uint256 totalWeight,
bytes memory // params
) internal virtual override returns (uint256) {
GovernorCountingSimpleStorage storage $ = _getGovernorCountingSimpleStorage();
ProposalVote storage proposalVote = $._proposalVotes[proposalId];
if (proposalVote.hasVoted[account]) {
revert GovernorAlreadyCastVote(account);
}
proposalVote.hasVoted[account] = true;
if (support == uint8(VoteType.Against)) {
proposalVote.againstVotes += totalWeight;
} else if (support == uint8(VoteType.For)) {
proposalVote.forVotes += totalWeight;
} else if (support == uint8(VoteType.Abstain)) {
proposalVote.abstainVotes += totalWeight;
} else {
revert GovernorInvalidVoteType();
}
return totalWeight;
}
}
"
},
"lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorSettingsUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorSettings.sol)
pragma solidity ^0.8.20;
import {GovernorUpgradeable} from "../GovernorUpgradeable.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for settings updatable through governance.
*/
abstract contract GovernorSettingsUpgradeable is Initializable, GovernorUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.GovernorSettings
struct GovernorSettingsStorage {
// amount of token
uint256 _proposalThreshold;
// timepoint: limited to uint48 in core (same as clock() type)
uint48 _votingDelay;
// duration: limited to uint32 in core
uint32 _votingPeriod;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.GovernorSettings")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant GovernorSettingsStorageLocation = 0x00d7616c8fe29c6c2fbe1d0c5bc8f2faa4c35b43746e70b24b4d532752affd00;
function _getGovernorSettingsStorage() private pure returns (GovernorSettingsStorage storage $) {
assembly {
$.slot := GovernorSettingsStorageLocation
}
}
event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay);
event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod);
event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold);
/**
* @dev Initialize the governance parameters.
*/
function __GovernorSettings_init(uint48 initialVotingDelay, uint32 initialVotingPeriod, uint256 initialProposalThreshold) internal onlyInitializing {
__GovernorSettings_init_unchained(initialVotingDelay, initialVotingPeriod, initialProposalThreshold);
}
function __GovernorSettings_init_unchained(uint48 initialVotingDelay, uint32 initialVotingPeriod, uint256 initialProposalThreshold) internal onlyInitializing {
_setVotingDelay(initialVotingDelay);
_setVotingPeriod(initialVotingPeriod);
_setProposalThreshold(initialProposalThreshold);
}
/**
* @dev See {IGovernor-votingDelay}.
*/
function votingDelay() public view virtual override returns (uint256) {
GovernorSettingsStorage storage $ = _getGovernorSettingsStorage();
return $._votingDelay;
}
/**
* @dev See {IGovernor-votingPeriod}.
*/
function votingPeriod() public view virtual override returns (uint256) {
GovernorSettingsStorage storage $ = _getGovernorSettingsStorage();
return $._votingPeriod;
}
/**
* @dev See {Governor-proposalThreshold}.
*/
function proposalThreshold() public view virtual override returns (uint256) {
GovernorSettingsStorage storage $ = _getGovernorSettingsStorage();
return $._proposalThreshold;
}
/**
* @dev Update the voting delay. This operation can only be performed through a governance proposal.
*
* Emits a {VotingDelaySet} event.
*/
function setVotingDelay(uint48 newVotingDelay) public virtual onlyGovernance {
_setVotingDelay(newVotingDelay);
}
/**
* @dev Update the voting period. This operation can only be performed through a governance proposal.
*
* Emits a {VotingPeriodSet} event.
*/
function setVotingPeriod(uint32 newVotingPeriod) public virtual onlyGovernance {
_setVotingPeriod(newVotingPeriod);
}
/**
* @dev Update the proposal threshold. This operation can only be performed through a governance proposal.
*
* Emits a {ProposalThresholdSet} event.
*/
function setProposalThreshold(uint256 newProposalThreshold) public virtual onlyGovernance {
_setProposalThreshold(newProposalThreshold);
}
/**
* @dev Internal setter for the voting delay.
*
* Emits a {VotingDelaySet} event.
*/
function _setVotingDelay(uint48 newVotingDelay) internal virtual {
GovernorSettingsStorage storage $ = _getGovernorSettingsStorage();
emit VotingDelaySet($._votingDelay, newVotingDelay);
$._votingDelay = newVotingDelay;
}
/**
* @dev Internal setter for the voting period.
*
* Emits a {VotingPeriodSet} event.
*/
function _setVotingPeriod(uint32 newVotingPeriod) internal virtual {
GovernorSettingsStorage storage $ = _getGovernorSettingsStorage();
if (newVotingPeriod == 0) {
revert GovernorInvalidVotingPeriod(0);
}
emit VotingPeriodSet($._votingPeriod, newVotingPeriod);
$._votingPeriod = newVotingPeriod;
}
/**
* @dev Internal setter for the proposal threshold.
*
* Emits a {ProposalThresholdSet} event.
*/
function _setProposalThreshold(uint256 newProposalThreshold) internal virtual {
GovernorSettingsStorage storage $ = _getGovernorSettingsStorage();
emit ProposalThresholdSet($._proposalThreshold, newProposalThreshold);
$._proposalThreshold = newProposalThreshold;
}
}
"
},
"lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorStorageUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (governance/extensions/GovernorStorage.sol)
pragma solidity ^0.8.20;
import {GovernorUpgradeable} from "../GovernorUpgradeable.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} that implements storage of proposal details. This modules also provides primitives for
* the enumerability of proposals.
*
* Use cases for this module include:
* - UIs that explore the proposal state without relying on event indexing.
* - Using only the proposalId as an argument in the {Governor-queue} and {Governor-execute} functions for L2 chains
* where storage is cheap compared to calldata.
*/
abstract contract GovernorStorageUpgradeable is Initializable, GovernorUpgradeable {
struct ProposalDetails {
address[] targets;
uint256[] values;
bytes[] calldatas;
bytes32 descriptionHash;
}
/// @custom:storage-location erc7201:openzeppelin.storage.GovernorStorage
struct GovernorStorageStorage {
uint256[] _proposalIds;
mapping(uint256 proposalId => ProposalDetails) _proposalDetails;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.GovernorStorage")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant GovernorStorageStorageLocation = 0x7fd223d3380145bd26132714391e777c488a0df7ac2dd4b66419d8549fb3a600;
function _getGovernorStorageStorage() private pure returns (GovernorStorageStorage storage $) {
assembly {
$.slot := GovernorStorageStorageLocation
}
}
function __GovernorStorage_init() internal onlyInitializing {
}
function __GovernorStorage_init_unchained() internal onlyInitializing {
}
/**
* @dev Hook into the proposing mechanism
*/
function _propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description,
address proposer
) internal virtual override returns (uint256) {
GovernorStorageStorage storage $ = _getGovernorStorageStorage();
uint256 proposalId = super._propose(targets, values, calldatas, description, proposer);
// store
$._proposalIds.push(proposalId);
$._proposalDetails[proposalId] = ProposalDetails({
targets: targets,
values: values,
calldatas: calldatas,
descriptionHash: keccak256(bytes(description))
});
return proposalId;
}
/**
* @dev Version of {IGovernorTimelock-queue} with only `proposalId` as an argument.
*/
function queue(uint256 proposalId) public virtual {
GovernorStorageStorage storage $ = _getGovernorStorageStorage();
// here, using storage is more efficient than memory
ProposalDetails storage details = $._proposalDetails[proposalId];
queue(details.targets, details.values, details.calldatas, details.descriptionHash);
}
/**
* @dev Version of {IGovernor-execute} with only `proposalId` as an argument.
*/
function execute(uint256 proposalId) public payable virtual {
GovernorStorageStorage storage $ = _getGovernorStorageStorage();
// here, using storage is more efficient than memory
ProposalDetails storage details = $._proposalDetails[proposalId];
execute(details.targets, details.values, details.calldatas, details.descriptionHash);
}
/**
* @dev ProposalId version of {IGovernor-cancel}.
*/
function cancel(uint256 proposalId) public virtual {
GovernorStorageStorage storage $ = _getGovernorStorageStorage();
// here, using storage is more efficient than memory
ProposalDetails storage details = $._proposalDetails[proposalId];
cancel(details.targets, details.values, details.calldatas, details.descriptionHash);
}
/**
* @dev Returns the number of stored proposals.
*/
function proposalCount() public view virtual returns (uint256) {
GovernorStorageStorage storage $ = _getGovernorStorageStorage();
return $._proposalIds.length;
}
/**
* @dev Returns the details of a proposalId. Reverts if `proposalId` is not a known proposal.
*/
function proposalDetails(
uint256 proposalId
)
public
view
virtual
returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
{
GovernorStorageStorage storage $ = _getGovernorStorageStorage();
// here, using memory is more efficient than storage
ProposalDetails memory details = $._proposalDetails[proposalId];
if (details.descriptionHash == 0) {
revert GovernorNonexistentProposal(proposalId);
}
return (details.targets, details.values, details.calldatas, details.descriptionHash);
}
/**
* @dev Returns the details (including the proposalId) of a proposal given its sequential index.
*/
function proposalDetailsAt(
uint256 index
)
public
view
virtual
returns (
uint256 proposalId,
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
)
{
GovernorStorageStorage storage $ = _getGovernorStorageStorage();
proposalId = $._proposalIds[index];
(targets, values, calldatas, descriptionHash) = proposalDetails(proposalId);
}
}
"
},
"lib/openzeppelin-contracts-upgradeable/contracts/governance/extensions/GovernorVotesUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (governance/extensions/GovernorVotes.sol)
pragma solidity ^0.8.20;
import {GovernorUpgradeable} from "../GovernorUpgradeable.sol";
import {IVotes} from "@openzeppelin/contracts/governance/utils/IVotes.sol";
import {IERC5805} from "@openzeppelin/contracts/interfaces/IERC5805.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes}
* token.
*/
abstract contract GovernorVotesUpgradeable is Initializable, GovernorUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.GovernorVotes
struct GovernorVotesStorage {
IERC5805 _token;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.GovernorVotes")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant GovernorVotesStorageLocation = 0x3ba4977254e415696610a40ebf2258dbfa0ec6a2ff64e84bfe715ff16977cc00;
function _getGovernorVotesStorage() private pure returns (GovernorVotesStorage storage $) {
assembly {
$.slot := GovernorVotesStorageLocation
}
}
function __GovernorVotes_init(IVotes tokenAddress) internal onlyInitializing {
__GovernorVotes_init_unchained(tokenAddress);
}
function __GovernorVotes_init_unchained(IVotes tokenAddress) internal onlyInitializing {
GovernorVotesStorage storage $ = _getGovernorVotesStorage();
$._token = IERC5805(address(tokenAddress));
}
/**
* @dev The token that voting power is sourced from.
*/
function token() public view virtual returns (IERC5805) {
GovernorVotesStorage storage $ = _getGovernorVotesStorage();
return $._token;
}
/**
* @dev Clock (as specified in ERC-6372) is set to match the token's clock. Fallback to block numbers if the token
* does not implement ERC-6372.
*/
function clock() public view virtual override returns (uint48) {
try token().clock() returns (uint48 timepoint) {
return timepoint;
} catch {
return Time.blockNumber();
}
}
/**
* @dev Machine-readable description of the clock as specified in ERC-6372.
*/
// solhint-disable-next-line func-name-mixedcase
function CLOCK_MODE() public view virtual override returns (string memory) {
try token().CLOCK_MODE() returns (string memory clockmode) {
return clockmode;
} catch {
return "mode=blocknumber&from=default";
}
}
/**
* Read the voting weight from the token's built in snapshot mechanism (see {Governor-_getVotes}).
*/
function _getVotes(
address account,
uint256 timepoint,
bytes memory /*params*/
) internal view virtual override returns (uint256) {
return token().getPastVotes(account, timepoint);
}
}
"
},
"lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (governance/TimelockController.sol)
pragma solidity ^0.8.20;
import {AccessControlUpgradeable} from "../access/AccessControlUpgradeable.sol";
import {ERC721HolderUpgradeable} from "../token/ERC721/utils/ERC721HolderUpgradeable.sol";
import {ERC1155HolderUpgradeable} from "../token/ERC1155/utils/ERC1155HolderUpgradeable.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which acts as a timelocked controller. When set as the
* owner of an `Ownable` smart contract, it enforces a timelock on all
* `onlyOwner` maintenance operations. This gives time for users of the
* controlled contract to exit before a potentially dangerous maintenance
* operation is applied.
*
* By default, this contract is self administered, meaning administration tasks
* have to go through the timelock process. The proposer (resp executor) role
* is in charge of proposing (resp executing) operations. A common use case is
* to position this {TimelockController} as the owner of a smart contract, with
* a multisig or a DAO as the sole proposer.
*/
contract TimelockControllerUpgradeable is Initializable, AccessControlUpgradeable, ERC721HolderUpgradeable, ERC1155HolderUpgradeable {
bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE");
uint256 internal constant _DONE_TIMESTAMP = uint256(1);
/// @custom:storage-location erc7201:openzeppelin.storage.TimelockController
struct TimelockControllerStorage {
mapping(bytes32 id => uint256) _timestamps;
uint256 _minDelay;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.TimelockController")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant TimelockControllerStorageLocation = 0x9a37c2aa9d186a0969ff8a8267bf4e07e864c2f2768f5040949e28a624fb3600;
function _getTimelockControllerStorage() private pure returns (TimelockControllerStorage storage $) {
assembly {
$.slot := TimelockControllerStorageLocation
}
}
enum OperationState {
Unset,
Waiting,
Ready,
Done
}
/**
* @dev Mismatch between the parameters length for an operation call.
*/
error TimelockInvalidOperationLength(uint256 targets, uint256 payloads, uint256 values);
/**
* @dev The schedule operation doesn't meet the minimum delay.
*/
error TimelockInsufficientDelay(uint256 delay, uint256 minDelay);
/**
* @dev The current state of an operation is not as required.
* The `expectedStates` is a bitmap with the bits enabled for each OperationState enum position
* counting from right to left.
*
* See {_encodeStateBitmap}.
*/
error TimelockUnexpectedOperationState(bytes32 operationId, bytes32 expectedStates);
/**
* @dev The predecessor to an operation not yet done.
*/
error TimelockUnexecutedPredecessor(bytes32 predecessorId);
/**
* @dev The caller account is not authorized.
*/
error TimelockUnauthorizedCaller(address caller);
/**
* @dev Emitted when a call is scheduled as part of operation `id`.
*/
event CallScheduled(
bytes32 indexed id,
uint256 indexed index,
address target,
uint256 value,
bytes data,
bytes32 predecessor,
uint256 delay
);
/**
* @dev Emitted when a call is performed as part of operation `id`.
*/
event CallExecuted(bytes32 indexed id, uint256 indexed index, address target, uint256 value, bytes data);
/**
* @dev Emitted when new proposal is scheduled with non-zero salt.
*/
event CallSalt(bytes32 indexed id, bytes32 salt);
/**
* @dev Emitted when operation `id` is cancelled.
*/
event Cancelled(bytes32 indexed id);
/**
* @dev Emitted when the minimum delay for future operations is modified.
*/
event MinDelayChange(uint256 oldDuration, uint256 newDuration);
function initialize(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) public virtual initializer {
__TimelockController_init(minDelay, proposers, executors, admin);
}
/**
* @dev Initializes the contract with the following parameters:
*
* - `minDelay`: initial minimum delay in seconds for operations
* - `proposers`: accounts to be granted proposer and canceller roles
* - `executors`: accounts to be granted executor role
* - `admin`: optional account to be granted admin role; disable with zero address
*
* IMPORTANT: The optional admin can aid with initial configuration of roles after deployment
* without being subject to delay, but this role should be subsequently renounced in favor of
* administration through timelocked proposals. Previous versions of this contract would assign
* this admin to the deployer automatically and should be renounced as well.
*/
function __TimelockController_init(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) internal onlyInitializing {
__TimelockController_init_unchained(minDelay, proposers, executors, admin);
}
function __TimelockController_init_unchained(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) internal onlyInitializing {
TimelockControllerStorage storage $ = _getTimelockControllerStorage();
// self administration
_grantRole(DEFAULT_ADMIN_ROLE, address(this));
// optional admin
if (admin != address(0)) {
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
// register proposers and cancellers
for (uint256 i = 0; i < proposers.length; ++i) {
_grantRole(PROPOSER_ROLE, proposers[i]);
_grantRole(CANCELLER_ROLE, proposers[i]);
}
// register executors
for (uint256 i = 0; i < executors.length; ++i) {
_grantRole(EXECUTOR_ROLE, executors[i]);
}
$._minDelay = minDelay;
emit MinDelayChange(0, minDelay);
}
/**
* @dev Modifier to make a function callable only by a certain role. In
* addition to checking the sender's role, `address(0)` 's role is also
* considered. Granting a role to `address(0)` is equivalent to enabling
* this role for everyone.
*/
modifier onlyRoleOrOpenRole(bytes32 role) {
if (!hasRole(role, address(0))) {
_checkRole(role, _msgSender());
}
_;
}
/**
* @dev Contract might receive/hold ETH as part of the maintenance process.
*/
receive() external payable {}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(
bytes4 interfaceId
) public view virtual override(AccessControlUpgradeable, ERC1155HolderUpgradeable) returns (bool) {
return super.supportsInterface(interfaceId);
}
/**
* @dev Returns whether an id corresponds to a registered operation. This
* includes both Waiting, Ready, and Done operations.
*/
function isOperation(bytes32 id) public view returns (bool) {
return getOperationState(id) != OperationState.Unset;
}
/**
* @dev Returns whether an operation is pending or not. Note that a "pending" operation may also be "ready".
*/
function isOperationPending(bytes32 id) public view returns (bool) {
OperationState state = getOperationState(id);
return state == OperationState.Waiting || state == OperationState.Ready;
}
/**
* @dev Returns whether an operation is ready for execution. Note that a "ready" operation is also "pending".
*/
function isOperationReady(bytes32 id) public view returns (bool) {
return getOperationState(id) == OperationState.Ready;
}
/**
* @dev Returns whether an operation is done or not.
*/
function isOperationDone(bytes32 id) public view returns (bool) {
return getOperationState(id) == OperationState.Done;
}
/**
* @dev Returns the timestamp at which an operation becomes ready (0 for
* unset operations, 1 for done operations).
*/
function getTimestamp(bytes32 id) public view virtual returns (uint256) {
TimelockControllerStorage storage $ = _getTimelockControllerStorage();
return $._timestamps[id];
}
/**
* @dev Returns operation state.
*/
function getOperationState(bytes32 id) public view virtual returns (OperationState) {
uint256 timestamp = getTimestamp(id);
if (timestamp == 0) {
return OperationState.Unset;
} else if (timestamp == _DONE_TIMESTAMP) {
return OperationState.Done;
} else if (timestamp > block.timestamp) {
return OperationState.Waiting;
} else {
return OperationState.Ready;
}
}
/**
* @dev Returns the minimum delay in seconds for an operation to become valid.
*
* This value can be changed by executing an operation that calls `updateDelay`.
*/
function getMinDelay() public view virtual returns (uint256) {
TimelockControllerStorage storage $ = _getTimelockControllerStorage();
return $._minDelay;
}
/**
* @dev Returns the identifier of an operation containing a single
* transaction.
*/
function hashOperation(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt
) public pure virtual returns (bytes32) {
return keccak256(abi.encode(target, value, data, predecessor, salt));
}
/**
* @dev Returns the identifier of an operation containing a batch of
* transactions.
*/
function hashOperationBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata payloads,
bytes32 predecessor,
bytes32 salt
) public pure virtual returns (bytes32) {
return keccak256(abi.encode(targets, values, payloads, predecessor, salt));
}
/**
* @dev Schedule an operation containing a single transaction.
*
* Emits {CallSalt} if salt is nonzero, and {CallScheduled}.
*
* Requirements:
*
* - the caller must have the 'proposer' role.
*/
function schedule(
address target,
uint256 value,
bytes calldata data,
bytes32 predecessor,
bytes32 salt,
uint256 delay
) public virtual onlyRole(PROPOSER_ROLE) {
bytes32 id = hashOperation(target, value, data, predecessor, salt);
_schedule(id, delay);
emit CallScheduled(id, 0, target, value, data, predecessor, delay);
if (salt != bytes32(0)) {
emit CallSalt(id, salt);
}
}
/**
* @dev Schedule an operation containing a batch of transactions.
*
* Emits {CallSalt} if salt is nonzero, and one {CallScheduled} event per transaction in the batch.
*
* Requirements:
*
* - the caller must have the 'proposer' role.
*/
function scheduleBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata payloads,
bytes32 predecessor,
bytes32 salt,
uint256 delay
) public virtual onlyRole(PROPOSER_ROLE) {
if (targets.length != values.length || targets.length != payloads.length) {
revert TimelockInvalidOperationLength(targets.length, payloads.length, values.length);
}
bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);
_schedule(id, delay);
for (uint256 i = 0; i < targets.length; ++i) {
emit CallScheduled(id, i, targets[i], values[i], payloads[i], predecessor, delay);
}
if (salt != bytes32(0)) {
emit CallSalt(id, salt);
}
}
/**
* @dev Schedule an operation that is to become valid after a given delay.
*/
function _schedule(bytes32 id, uint256 delay) private {
TimelockControllerStorage storage $ = _getTimelockControllerStorage();
if (isOperation(id)) {
revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Unset));
}
uint256 minDelay = getMinDelay();
if (delay < minDelay) {
revert TimelockInsufficientDelay(delay, minDelay);
}
$._timestamps[id] = block.timestamp + delay;
}
/**
* @dev Cancel an operation.
*
* Requirements:
*
* - the caller must have the 'canceller' role.
*/
function cancel(bytes32 id) public virtual onlyRole(CANCELLER_ROLE) {
TimelockControllerStorage storage $ = _getTimelockControllerStorage();
if (!isOperationPending(id)) {
revert TimelockUnexpectedOperationState(
id,
_encodeStateBitmap(OperationState.Waiting) | _encodeStateBitmap(OperationState.Ready)
);
}
delete $._timestamps[id];
emit Cancelled(id);
}
/**
* @dev Execute an (ready) operation containing a single transaction.
*
* Emits a {CallExecuted} event.
*
* Requirements:
*
* - the caller must have the 'executor' role.
*/
// This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,
// thus any modifications to the operation during reentrancy should be caught.
// slither-disable-next-line reentrancy-eth
function execute(
address target,
uint256 value,
bytes calldata payload,
bytes32 predecessor,
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
bytes32 id = hashOperation(target, value, payload, predecessor, salt);
_beforeCall(id, predecessor);
_execute(target, value, payload);
emit CallExecuted(id, 0, target, value, payload);
_afterCall(id);
}
/**
* @dev Execute an (ready) operation containing a batch of transactions.
*
* Emits one {CallExecuted} event per transaction in the batch.
*
* Requirements:
*
* - the caller must have the 'executor' role.
*/
// This function can reenter, but it doesn't pose a risk because _afterCall checks that the proposal is pending,
// thus any modifications to the operation during reentrancy should be caught.
// slither-disable-next-line reentrancy-eth
function executeBatch(
address[] calldata targets,
uint256[] calldata values,
bytes[] calldata payloads,
bytes32 predecessor,
bytes32 salt
) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) {
if (targets.length != values.length || targets.length != payloads.length) {
revert TimelockInvalidOperationLength(targets.length, payloads.length, values.length);
}
bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt);
_beforeCall(id, predecessor);
for (uint256 i = 0; i < targets.length; ++i) {
address target = targets[i];
uint256 value = values[i];
bytes calldata payload = payloads[i];
_execute(target, value, payload);
emit CallExecuted(id, i, target, value, payload);
}
_afterCall(id);
}
/**
* @dev Execute an operation's call.
*/
function _execute(address target, uint256 value, bytes calldata data) internal virtual {
(bool success, bytes memory returndata) = target.call{value: value}(data);
Address.verifyCallResult(success, returndata);
}
/**
* @dev Checks before execution of an operation's calls.
*/
function _beforeCall(bytes32 id, bytes32 predecessor) private view {
if (!isOperationReady(id)) {
revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Ready));
}
if (predecessor != bytes32(0) && !isOperationDone(predecessor)) {
revert TimelockUnexecutedPredecessor(predecessor);
}
}
/**
* @dev Checks after execution of an operation's calls.
*/
function _afterCall(bytes32 id) private {
TimelockControllerStorage storage $ = _getTimelockControllerStorage();
if (!isOperationReady(id)) {
revert TimelockUnexpectedOperationState(id, _encodeStateBitmap(OperationState.Ready));
}
$._timestamps[id] = _DONE_TIMESTAMP;
}
/**
* @dev Changes the minimum timelock duration for future operations.
*
* Emits a {MinDelayChange} event.
*
* Requirements:
*
* - the caller must be the timelock itself. This can only be achieved by scheduling and later executing
* an operation where the timelock is the target and the data is the ABI-encoded call to this function.
*/
function updateDelay(uint256 newDelay) external virtual {
TimelockControllerStorage storage $ = _getTimelockControllerStorage();
address sender = _msgSender();
if (sender != address(this)) {
revert TimelockUnauthorizedCaller(sender);
}
emit MinDelayChange($._minDelay, newDelay);
$._minDelay = newDelay;
}
/**
* @dev Encodes a `OperationState` into a `bytes32` representation where each bit enabled corresponds to
* the underlying position in the `OperationState` enum. For example:
*
* 0x000...1000
* ^^^^^^----- ...
* ^---- Done
* ^--- Ready
* ^-- Waiting
* ^- Unset
*/
function _encodeStateBitmap(OperationState operationState) internal pure returns (bytes32) {
return bytes32(1 << uint8(operationState));
}
}
"
},
"lib/openzeppelin-contracts-upgradeable/contracts/governance/GovernorUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0-rc.0) (governance/Governor.sol)
pragma solidity ^0.8.20;
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import {EIP712Upgradeable} from "../utils/cryptography/EIP712Upgradeable.sol";
import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {ERC165Upgradeable} from "../utils/introspection/ERC165Upgradeable.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {DoubleEndedQueue} from "@openzeppelin/contracts/utils/structs/DoubleEndedQueue.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {NoncesUpgradeable} from "../utils/NoncesUpgradeable.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {IGovernor} from "@openzeppelin/contracts/governance/IGovernor.sol";
import {IERC6372} from "@openzeppelin/contracts/interfaces/IERC6372.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Core of the governance system, designed to be extended through various modules.
*
* This contract is abstract and requires several functions to be implemented in various modules:
*
* - A counting module must implement {quorum}, {_quorumReached}, {_voteSucceeded} and {_countVote}
* - A voting module must implement {_getVotes}
* - Additionally, {votingPeriod} must also be implemented
*/
abstract contract GovernorUpgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, EIP712Upgradeable, NoncesUpgradeable, IGovernor, IERC721Receiver, IERC1155Receiver {
using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque;
bytes32 public constant BALLOT_TYPEHASH =
keccak256("Ballot(uint256 proposalId,uint8 support,address voter,uint256 nonce)");
bytes32 public constant EXTENDED_BALLOT_TYPEHASH =
keccak256(
"ExtendedBallot(uint256 proposalId,uint8 support,address voter,uint256 nonce,string reason,bytes params)"
);
struct ProposalCore {
address proposer;
uint48 voteStart;
uint32 voteDuration;
bool executed;
bool canceled;
uint48 etaSeconds;
}
bytes32 private constant ALL_PROPOSAL_STATES_BITMAP = bytes32((2 ** (uint8(type(ProposalState).max) + 1)) - 1);
/// @custom:storage-location erc7201:openzeppelin.storage.Governor
struct GovernorStorage {
string _name;
mapping(uint256 proposalId => ProposalCore) _proposals;
// This queue keeps track of the governor operating on itself. Calls to functions protected by the {onlyGovernance}
// modifier needs to be whitelisted in this queue. Whitelisting is set in {execute}, consumed by the
// {onlyGovernance} modifier and eventually reset after {_executeOperations} completes. This ensures that the
// execution of {onlyGovernance} protected calls can only be achieved through successful proposals.
DoubleEndedQueue.Bytes32Deque _governanceCall;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Governor")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant GovernorStorageLocation = 0x7c712897014dbe49c045ef1299aa2d5f9e67e48eea4403efa21f1e0f3ac0cb00;
function _getGovernorStorage() private pure returns (GovernorStorage storage $) {
assembly {
$.slot := GovernorStorageLocation
}
}
/**
* @dev Restricts a function so it can only be executed through governance proposals. For example, governance
* parameter setters in {GovernorSettings} are protected using this modifier.
*
* The governance executing address may be different from the Governor's own address, for example it could be a
* timelock. This can be customized by modules by overriding {_executor}. The executor is only able to invoke these
* functions during the execution of the governor's {execute} function, and not under any other circumstances. Thus,
* for example, additional timelock proposers are not able to change governance parameters without going through the
* governance protocol (since v4.6).
*/
modifier onlyGovernance() {
_checkGovernance();
_;
}
/**
* @dev Sets the value for {name} and {version}
*/
function __Governor_init(string memory
Submitted on: 2025-10-23 16:10:13
Comments
Log in to comment.
No comments yet.