Source Code
Overview
S Balance
More Info
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
23620070 | 4 days ago | 0 S |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
EcoNovaGovernor
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT // Compatible with OpenZeppelin Contracts ^5.0.0 pragma solidity ^0.8.22; import {Governor} from "@openzeppelin/contracts/governance/Governor.sol"; import {GovernorCountingSimple} from "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol"; import {GovernorSettings} from "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol"; import {GovernorTimelockControl} from "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol"; import {GovernorVotes} from "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol"; import {GovernorVotesQuorumFraction} from "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol"; import {IVotes} from "@openzeppelin/contracts/governance/utils/IVotes.sol"; import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol"; contract EcoNovaGovernor is Governor, GovernorSettings, GovernorCountingSimple, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl { constructor( IVotes _token, TimelockController _timelock, uint256 _quorumPercentage, uint32 _votingPeriod, uint48 _votingDelay ) Governor("EcoNovaGovernor") GovernorSettings(_votingDelay, _votingPeriod, 0) GovernorVotes(_token) GovernorVotesQuorumFraction(_quorumPercentage) GovernorTimelockControl(_timelock) {} // The following functions are overrides required by Solidity. function votingDelay() public view override(Governor, GovernorSettings) returns (uint256) { return super.votingDelay(); } function votingPeriod() public view override(Governor, GovernorSettings) returns (uint256) { return super.votingPeriod(); } function quorum( uint256 blockNumber ) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) { return super.quorum(blockNumber); } function state( uint256 proposalId ) public view override(Governor, GovernorTimelockControl) returns (ProposalState) { return super.state(proposalId); } function proposalNeedsQueuing( uint256 proposalId ) public view override(Governor, GovernorTimelockControl) returns (bool) { return super.proposalNeedsQueuing(proposalId); } function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { return super.proposalThreshold(); } function _queueOperations( uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal override(Governor, GovernorTimelockControl) returns (uint48) { return super._queueOperations(proposalId, targets, values, calldatas, descriptionHash); } function _executeOperations( uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal override(Governor, GovernorTimelockControl) { super._executeOperations(proposalId, targets, values, calldatas, descriptionHash); } function _cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal override(Governor, GovernorTimelockControl) returns (uint256) { return super._cancel(targets, values, calldatas, descriptionHash); } function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) { return super._executor(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) pragma solidity ^0.8.20; import {IAccessControl} from "./IAccessControl.sol"; import {Context} from "../utils/Context.sol"; import {ERC165} from "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address account => bool) hasRole; bytes32 adminRole; } mapping(bytes32 role => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with an {AccessControlUnauthorizedAccount} error including the required role. */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual returns (bool) { return _roles[role].hasRole[account]; } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` * is missing `role`. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert AccessControlUnauthorizedAccount(account, role); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address callerConfirmation) public virtual { if (callerConfirmation != _msgSender()) { revert AccessControlBadConfirmation(); } _revokeRole(role, callerConfirmation); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual returns (bool) { if (!hasRole(role, account)) { _roles[role].hasRole[account] = true; emit RoleGranted(role, account, _msgSender()); return true; } else { return false; } } /** * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { if (hasRole(role, account)) { _roles[role].hasRole[account] = false; emit RoleRevoked(role, account, _msgSender()); return true; } else { return false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC-165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role). * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (governance/extensions/GovernorCountingSimple.sol) pragma solidity ^0.8.20; import {Governor} from "../Governor.sol"; /** * @dev Extension of {Governor} for simple, 3 options, vote counting. */ abstract contract GovernorCountingSimple is Governor { /** * @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; } mapping(uint256 proposalId => ProposalVote) private _proposalVotes; /** * @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) { 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) { 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) { 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) { 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) { 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorSettings.sol) pragma solidity ^0.8.20; import {Governor} from "../Governor.sol"; /** * @dev Extension of {Governor} for settings updatable through governance. */ abstract contract GovernorSettings is Governor { // amount of token uint256 private _proposalThreshold; // timepoint: limited to uint48 in core (same as clock() type) uint48 private _votingDelay; // duration: limited to uint32 in core uint32 private _votingPeriod; event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay); event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod); event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold); /** * @dev Initialize the governance parameters. */ constructor(uint48 initialVotingDelay, uint32 initialVotingPeriod, uint256 initialProposalThreshold) { _setVotingDelay(initialVotingDelay); _setVotingPeriod(initialVotingPeriod); _setProposalThreshold(initialProposalThreshold); } /** * @dev See {IGovernor-votingDelay}. */ function votingDelay() public view virtual override returns (uint256) { return _votingDelay; } /** * @dev See {IGovernor-votingPeriod}. */ function votingPeriod() public view virtual override returns (uint256) { return _votingPeriod; } /** * @dev See {Governor-proposalThreshold}. */ function proposalThreshold() public view virtual override returns (uint256) { 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 { emit VotingDelaySet(_votingDelay, newVotingDelay); _votingDelay = newVotingDelay; } /** * @dev Internal setter for the voting period. * * Emits a {VotingPeriodSet} event. */ function _setVotingPeriod(uint32 newVotingPeriod) internal virtual { 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 { emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold); _proposalThreshold = newProposalThreshold; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (governance/extensions/GovernorTimelockControl.sol) pragma solidity ^0.8.20; import {IGovernor, Governor} from "../Governor.sol"; import {TimelockController} from "../TimelockController.sol"; import {IERC165} from "../../interfaces/IERC165.sol"; import {SafeCast} from "../../utils/math/SafeCast.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 GovernorTimelockControl is Governor { TimelockController private _timelock; mapping(uint256 proposalId => bytes32) private _timelockIds; /** * @dev Emitted when the timelock controller used for proposal execution is modified. */ event TimelockChange(address oldTimelock, address newTimelock); /** * @dev Set the timelock. */ constructor(TimelockController timelockAddress) { _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) { 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) { 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) { 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 { // 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) { 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) { 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(TimelockController newTimelock) external virtual onlyGovernance { _updateTimelock(newTimelock); } function _updateTimelock(TimelockController newTimelock) private { 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (governance/extensions/GovernorVotes.sol) pragma solidity ^0.8.20; import {Governor} from "../Governor.sol"; import {IVotes} from "../utils/IVotes.sol"; import {IERC5805} from "../../interfaces/IERC5805.sol"; import {SafeCast} from "../../utils/math/SafeCast.sol"; import {Time} from "../../utils/types/Time.sol"; /** * @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} * token. */ abstract contract GovernorVotes is Governor { IERC5805 private immutable _token; constructor(IVotes tokenAddress) { _token = IERC5805(address(tokenAddress)); } /** * @dev The token that voting power is sourced from. */ function token() public view virtual returns (IERC5805) { 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorVotesQuorumFraction.sol) pragma solidity ^0.8.20; import {GovernorVotes} from "./GovernorVotes.sol"; import {SafeCast} from "../../utils/math/SafeCast.sol"; import {Checkpoints} from "../../utils/structs/Checkpoints.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 GovernorVotesQuorumFraction is GovernorVotes { using Checkpoints for Checkpoints.Trace208; Checkpoints.Trace208 private _quorumNumeratorHistory; 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}. */ constructor(uint256 quorumNumeratorValue) { _updateQuorumNumerator(quorumNumeratorValue); } /** * @dev Returns the current quorum numerator. See {quorumDenominator}. */ function quorumNumerator() public view virtual returns (uint256) { return _quorumNumeratorHistory.latest(); } /** * @dev Returns the quorum numerator at a specific timepoint. See {quorumDenominator}. */ function quorumNumerator(uint256 timepoint) public view virtual returns (uint256) { 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 { uint256 denominator = quorumDenominator(); if (newQuorumNumerator > denominator) { revert GovernorInvalidQuorumFraction(newQuorumNumerator, denominator); } uint256 oldQuorumNumerator = quorumNumerator(); _quorumNumeratorHistory.push(clock(), SafeCast.toUint208(newQuorumNumerator)); emit QuorumNumeratorUpdated(oldQuorumNumerator, newQuorumNumerator); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (governance/Governor.sol) pragma solidity ^0.8.20; import {IERC721Receiver} from "../token/ERC721/IERC721Receiver.sol"; import {IERC1155Receiver} from "../token/ERC1155/IERC1155Receiver.sol"; import {EIP712} from "../utils/cryptography/EIP712.sol"; import {SignatureChecker} from "../utils/cryptography/SignatureChecker.sol"; import {IERC165, ERC165} from "../utils/introspection/ERC165.sol"; import {SafeCast} from "../utils/math/SafeCast.sol"; import {DoubleEndedQueue} from "../utils/structs/DoubleEndedQueue.sol"; import {Address} from "../utils/Address.sol"; import {Context} from "../utils/Context.sol"; import {Nonces} from "../utils/Nonces.sol"; import {Strings} from "../utils/Strings.sol"; import {IGovernor, IERC6372} from "./IGovernor.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 Governor is Context, ERC165, EIP712, Nonces, 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); string private _name; mapping(uint256 proposalId => ProposalCore) private _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 private _governanceCall; /** * @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} */ constructor(string memory name_) EIP712(name_, version()) { _name = name_; } /** * @dev Function to receive ETH that will be handled by the governor (disabled if executor is a third party contract) */ receive() external payable virtual { if (_executor() != address(this)) { revert GovernorDisabledDeposit(); } } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IGovernor).interfaceId || interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IGovernor-name}. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev See {IGovernor-version}. */ function version() public view virtual returns (string memory) { return "1"; } /** * @dev See {IGovernor-hashProposal}. * * The proposal id is produced by hashing the ABI encoded `targets` array, the `values` array, the `calldatas` array * and the descriptionHash (bytes32 which itself is the keccak256 hash of the description string). This proposal id * can be produced from the proposal data which is part of the {ProposalCreated} event. It can even be computed in * advance, before the proposal is submitted. * * Note that the chainId and the governor address are not part of the proposal id computation. Consequently, the * same proposal (with same operation and same description) will have the same id if submitted on multiple governors * across multiple networks. This also means that in order to execute the same operation twice (on the same * governor) the proposer will have to change the description in order to avoid proposal id conflicts. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public pure virtual returns (uint256) { return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); } /** * @dev See {IGovernor-state}. */ function state(uint256 proposalId) public view virtual returns (ProposalState) { // We read the struct fields into the stack at once so Solidity emits a single SLOAD ProposalCore storage proposal = _proposals[proposalId]; bool proposalExecuted = proposal.executed; bool proposalCanceled = proposal.canceled; if (proposalExecuted) { return ProposalState.Executed; } if (proposalCanceled) { return ProposalState.Canceled; } uint256 snapshot = proposalSnapshot(proposalId); if (snapshot == 0) { revert GovernorNonexistentProposal(proposalId); } uint256 currentTimepoint = clock(); if (snapshot >= currentTimepoint) { return ProposalState.Pending; } uint256 deadline = proposalDeadline(proposalId); if (deadline >= currentTimepoint) { return ProposalState.Active; } else if (!_quorumReached(proposalId) || !_voteSucceeded(proposalId)) { return ProposalState.Defeated; } else if (proposalEta(proposalId) == 0) { return ProposalState.Succeeded; } else { return ProposalState.Queued; } } /** * @dev See {IGovernor-proposalThreshold}. */ function proposalThreshold() public view virtual returns (uint256) { return 0; } /** * @dev See {IGovernor-proposalSnapshot}. */ function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256) { return _proposals[proposalId].voteStart; } /** * @dev See {IGovernor-proposalDeadline}. */ function proposalDeadline(uint256 proposalId) public view virtual returns (uint256) { return _proposals[proposalId].voteStart + _proposals[proposalId].voteDuration; } /** * @dev See {IGovernor-proposalProposer}. */ function proposalProposer(uint256 proposalId) public view virtual returns (address) { return _proposals[proposalId].proposer; } /** * @dev See {IGovernor-proposalEta}. */ function proposalEta(uint256 proposalId) public view virtual returns (uint256) { return _proposals[proposalId].etaSeconds; } /** * @dev See {IGovernor-proposalNeedsQueuing}. */ function proposalNeedsQueuing(uint256) public view virtual returns (bool) { return false; } /** * @dev Reverts if the `msg.sender` is not the executor. In case the executor is not this contract * itself, the function reverts if `msg.data` is not whitelisted as a result of an {execute} * operation. See {onlyGovernance}. */ function _checkGovernance() internal virtual { if (_executor() != _msgSender()) { revert GovernorOnlyExecutor(_msgSender()); } if (_executor() != address(this)) { bytes32 msgDataHash = keccak256(_msgData()); // loop until popping the expected operation - throw if deque is empty (operation not authorized) while (_governanceCall.popFront() != msgDataHash) {} } } /** * @dev Amount of votes already cast passes the threshold limit. */ function _quorumReached(uint256 proposalId) internal view virtual returns (bool); /** * @dev Is the proposal successful or not. */ function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); /** * @dev Get the voting weight of `account` at a specific `timepoint`, for a vote as described by `params`. */ function _getVotes(address account, uint256 timepoint, bytes memory params) internal view virtual returns (uint256); /** * @dev Register a vote for `proposalId` by `account` with a given `support`, voting `weight` and voting `params`. * * Note: Support is generic and can represent various things depending on the voting system used. */ function _countVote( uint256 proposalId, address account, uint8 support, uint256 totalWeight, bytes memory params ) internal virtual returns (uint256); /** * @dev Hook that should be called every time the tally for a proposal is updated. * * Note: This function must run successfully. Reverts will result in the bricking of governance */ function _tallyUpdated(uint256 proposalId) internal virtual {} /** * @dev Default additional encoded parameters used by castVote methods that don't include them * * Note: Should be overridden by specific implementations to use an appropriate value, the * meaning of the additional params, in the context of that implementation */ function _defaultParams() internal view virtual returns (bytes memory) { return ""; } /** * @dev See {IGovernor-propose}. This function has opt-in frontrunning protection, described in {_isValidDescriptionForProposer}. */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) public virtual returns (uint256) { address proposer = _msgSender(); // check description restriction if (!_isValidDescriptionForProposer(proposer, description)) { revert GovernorRestrictedProposer(proposer); } // check proposal threshold uint256 votesThreshold = proposalThreshold(); if (votesThreshold > 0) { uint256 proposerVotes = getVotes(proposer, clock() - 1); if (proposerVotes < votesThreshold) { revert GovernorInsufficientProposerVotes(proposer, proposerVotes, votesThreshold); } } return _propose(targets, values, calldatas, description, proposer); } /** * @dev Internal propose mechanism. Can be overridden to add more logic on proposal creation. * * Emits a {IGovernor-ProposalCreated} event. */ function _propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description, address proposer ) internal virtual returns (uint256 proposalId) { proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); if (targets.length != values.length || targets.length != calldatas.length || targets.length == 0) { revert GovernorInvalidProposalLength(targets.length, calldatas.length, values.length); } if (_proposals[proposalId].voteStart != 0) { revert GovernorUnexpectedProposalState(proposalId, state(proposalId), bytes32(0)); } uint256 snapshot = clock() + votingDelay(); uint256 duration = votingPeriod(); ProposalCore storage proposal = _proposals[proposalId]; proposal.proposer = proposer; proposal.voteStart = SafeCast.toUint48(snapshot); proposal.voteDuration = SafeCast.toUint32(duration); emit ProposalCreated( proposalId, proposer, targets, values, new string[](targets.length), calldatas, snapshot, snapshot + duration, description ); // Using a named return variable to avoid stack too deep errors } /** * @dev See {IGovernor-queue}. */ function queue( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); _validateStateBitmap(proposalId, _encodeStateBitmap(ProposalState.Succeeded)); uint48 etaSeconds = _queueOperations(proposalId, targets, values, calldatas, descriptionHash); if (etaSeconds != 0) { _proposals[proposalId].etaSeconds = etaSeconds; emit ProposalQueued(proposalId, etaSeconds); } else { revert GovernorQueueNotImplemented(); } return proposalId; } /** * @dev Internal queuing mechanism. Can be overridden (without a super call) to modify the way queuing is * performed (for example adding a vault/timelock). * * This is empty by default, and must be overridden to implement queuing. * * This function returns a timestamp that describes the expected ETA for execution. If the returned value is 0 * (which is the default value), the core will consider queueing did not succeed, and the public {queue} function * will revert. * * NOTE: Calling this function directly will NOT check the current state of the proposal, or emit the * `ProposalQueued` event. Queuing a proposal should be done using {queue}. */ function _queueOperations( uint256 /*proposalId*/, address[] memory /*targets*/, uint256[] memory /*values*/, bytes[] memory /*calldatas*/, bytes32 /*descriptionHash*/ ) internal virtual returns (uint48) { return 0; } /** * @dev See {IGovernor-execute}. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public payable virtual returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); _validateStateBitmap( proposalId, _encodeStateBitmap(ProposalState.Succeeded) | _encodeStateBitmap(ProposalState.Queued) ); // mark as executed before calls to avoid reentrancy _proposals[proposalId].executed = true; // before execute: register governance call in queue. if (_executor() != address(this)) { for (uint256 i = 0; i < targets.length; ++i) { if (targets[i] == address(this)) { _governanceCall.pushBack(keccak256(calldatas[i])); } } } _executeOperations(proposalId, targets, values, calldatas, descriptionHash); // after execute: cleanup governance call queue. if (_executor() != address(this) && !_governanceCall.empty()) { _governanceCall.clear(); } emit ProposalExecuted(proposalId); return proposalId; } /** * @dev Internal execution mechanism. Can be overridden (without a super call) to modify the way execution is * performed (for example adding a vault/timelock). * * NOTE: Calling this function directly will NOT check the current state of the proposal, set the executed flag to * true or emit the `ProposalExecuted` event. Executing a proposal should be done using {execute} or {_execute}. */ function _executeOperations( uint256 /* proposalId */, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { for (uint256 i = 0; i < targets.length; ++i) { (bool success, bytes memory returndata) = targets[i].call{value: values[i]}(calldatas[i]); Address.verifyCallResult(success, returndata); } } /** * @dev See {IGovernor-cancel}. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) public virtual returns (uint256) { // The proposalId will be recomputed in the `_cancel` call further down. However we need the value before we // do the internal call, because we need to check the proposal state BEFORE the internal `_cancel` call // changes it. The `hashProposal` duplication has a cost that is limited, and that we accept. uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); // public cancel restrictions (on top of existing _cancel restrictions). _validateStateBitmap(proposalId, _encodeStateBitmap(ProposalState.Pending)); if (_msgSender() != proposalProposer(proposalId)) { revert GovernorOnlyProposer(_msgSender()); } return _cancel(targets, values, calldatas, descriptionHash); } /** * @dev Internal cancel mechanism with minimal restrictions. A proposal can be cancelled in any state other than * Canceled, Expired, or Executed. Once cancelled a proposal can't be re-submitted. * * Emits a {IGovernor-ProposalCanceled} event. */ function _cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal virtual returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); _validateStateBitmap( proposalId, ALL_PROPOSAL_STATES_BITMAP ^ _encodeStateBitmap(ProposalState.Canceled) ^ _encodeStateBitmap(ProposalState.Expired) ^ _encodeStateBitmap(ProposalState.Executed) ); _proposals[proposalId].canceled = true; emit ProposalCanceled(proposalId); return proposalId; } /** * @dev See {IGovernor-getVotes}. */ function getVotes(address account, uint256 timepoint) public view virtual returns (uint256) { return _getVotes(account, timepoint, _defaultParams()); } /** * @dev See {IGovernor-getVotesWithParams}. */ function getVotesWithParams( address account, uint256 timepoint, bytes memory params ) public view virtual returns (uint256) { return _getVotes(account, timepoint, params); } /** * @dev See {IGovernor-castVote}. */ function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReason}. */ function castVoteWithReason( uint256 proposalId, uint8 support, string calldata reason ) public virtual returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason); } /** * @dev See {IGovernor-castVoteWithReasonAndParams}. */ function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string calldata reason, bytes memory params ) public virtual returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason, params); } /** * @dev See {IGovernor-castVoteBySig}. */ function castVoteBySig( uint256 proposalId, uint8 support, address voter, bytes memory signature ) public virtual returns (uint256) { bool valid = SignatureChecker.isValidSignatureNow( voter, _hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support, voter, _useNonce(voter)))), signature ); if (!valid) { revert GovernorInvalidSignature(voter); } return _castVote(proposalId, voter, support, ""); } /** * @dev See {IGovernor-castVoteWithReasonAndParamsBySig}. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, address voter, string calldata reason, bytes memory params, bytes memory signature ) public virtual returns (uint256) { bool valid = SignatureChecker.isValidSignatureNow( voter, _hashTypedDataV4( keccak256( abi.encode( EXTENDED_BALLOT_TYPEHASH, proposalId, support, voter, _useNonce(voter), keccak256(bytes(reason)), keccak256(params) ) ) ), signature ); if (!valid) { revert GovernorInvalidSignature(voter); } return _castVote(proposalId, voter, support, reason, params); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. Uses the _defaultParams(). * * Emits a {IGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint8 support, string memory reason ) internal virtual returns (uint256) { return _castVote(proposalId, account, support, reason, _defaultParams()); } /** * @dev Internal vote casting mechanism: Check that the vote is pending, that it has not been cast yet, retrieve * voting weight using {IGovernor-getVotes} and call the {_countVote} internal function. * * Emits a {IGovernor-VoteCast} event. */ function _castVote( uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params ) internal virtual returns (uint256) { _validateStateBitmap(proposalId, _encodeStateBitmap(ProposalState.Active)); uint256 totalWeight = _getVotes(account, proposalSnapshot(proposalId), params); uint256 votedWeight = _countVote(proposalId, account, support, totalWeight, params); if (params.length == 0) { emit VoteCast(account, proposalId, support, votedWeight, reason); } else { emit VoteCastWithParams(account, proposalId, support, votedWeight, reason, params); } _tallyUpdated(proposalId); return votedWeight; } /** * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor * is some contract other than the governor itself, like when using a timelock, this function can be invoked * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance { (bool success, bytes memory returndata) = target.call{value: value}(data); Address.verifyCallResult(success, returndata); } /** * @dev Address through which the governor executes action. Will be overloaded by module that execute actions * through another contract such as a timelock. */ function _executor() internal view virtual returns (address) { return address(this); } /** * @dev See {IERC721Receiver-onERC721Received}. * Receiving tokens is disabled if the governance executor is other than the governor itself (eg. when using with a timelock). */ function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4) { if (_executor() != address(this)) { revert GovernorDisabledDeposit(); } return this.onERC721Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155Received}. * Receiving tokens is disabled if the governance executor is other than the governor itself (eg. when using with a timelock). */ function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual returns (bytes4) { if (_executor() != address(this)) { revert GovernorDisabledDeposit(); } return this.onERC1155Received.selector; } /** * @dev See {IERC1155Receiver-onERC1155BatchReceived}. * Receiving tokens is disabled if the governance executor is other than the governor itself (eg. when using with a timelock). */ function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual returns (bytes4) { if (_executor() != address(this)) { revert GovernorDisabledDeposit(); } return this.onERC1155BatchReceived.selector; } /** * @dev Encodes a `ProposalState` into a `bytes32` representation where each bit enabled corresponds to * the underlying position in the `ProposalState` enum. For example: * * 0x000...10000 * ^^^^^^------ ... * ^----- Succeeded * ^---- Defeated * ^--- Canceled * ^-- Active * ^- Pending */ function _encodeStateBitmap(ProposalState proposalState) internal pure returns (bytes32) { return bytes32(1 << uint8(proposalState)); } /** * @dev Check that the current state of a proposal matches the requirements described by the `allowedStates` bitmap. * This bitmap should be built using `_encodeStateBitmap`. * * If requirements are not met, reverts with a {GovernorUnexpectedProposalState} error. */ function _validateStateBitmap(uint256 proposalId, bytes32 allowedStates) internal view returns (ProposalState) { ProposalState currentState = state(proposalId); if (_encodeStateBitmap(currentState) & allowedStates == bytes32(0)) { revert GovernorUnexpectedProposalState(proposalId, currentState, allowedStates); } return currentState; } /* * @dev Check if the proposer is authorized to submit a proposal with the given description. * * If the proposal description ends with `#proposer=0x???`, where `0x???` is an address written as a hex string * (case insensitive), then the submission of this proposal will only be authorized to said address. * * This is used for frontrunning protection. By adding this pattern at the end of their proposal, one can ensure * that no other address can submit the same proposal. An attacker would have to either remove or change that part, * which would result in a different proposal id. * * If the description does not match this pattern, it is unrestricted and anyone can submit it. This includes: * - If the `0x???` part is not a valid hex string. * - If the `0x???` part is a valid hex string, but does not contain exactly 40 hex digits. * - If it ends with the expected suffix followed by newlines or other whitespace. * - If it ends with some other similar suffix, e.g. `#other=abc`. * - If it does not end with any such suffix. */ function _isValidDescriptionForProposer( address proposer, string memory description ) internal view virtual returns (bool) { unchecked { uint256 length = bytes(description).length; // Length is too short to contain a valid proposer suffix if (length < 52) { return true; } // Extract what would be the `#proposer=` marker beginning the suffix bytes10 marker = bytes10(_unsafeReadBytesOffset(bytes(description), length - 52)); // If the marker is not found, there is no proposer suffix to check if (marker != bytes10("#proposer=")) { return true; } // Check that the last 42 characters (after the marker) are a properly formatted address. (bool success, address recovered) = Strings.tryParseAddress(description, length - 42, length); return !success || recovered == proposer; } } /** * @inheritdoc IERC6372 */ function clock() public view virtual returns (uint48); /** * @inheritdoc IERC6372 */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual returns (string memory); /** * @inheritdoc IGovernor */ function votingDelay() public view virtual returns (uint256); /** * @inheritdoc IGovernor */ function votingPeriod() public view virtual returns (uint256); /** * @inheritdoc IGovernor */ function quorum(uint256 timepoint) public view virtual returns (uint256); /** * @dev Reads a bytes32 from a bytes array without bounds checking. * * NOTE: making this function internal would mean it could be used with memory unsafe offset, and marking the * assembly block as such would prevent some optimizations. */ function _unsafeReadBytesOffset(bytes memory buffer, uint256 offset) private pure returns (bytes32 value) { // This is not memory safe in the general case, but all calls to this private function are within bounds. assembly ("memory-safe") { value := mload(add(buffer, add(0x20, offset))) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (governance/IGovernor.sol) pragma solidity ^0.8.20; import {IERC165} from "../interfaces/IERC165.sol"; import {IERC6372} from "../interfaces/IERC6372.sol"; /** * @dev Interface of the {Governor} core. * * NOTE: Event parameters lack the `indexed` keyword for compatibility with GovernorBravo events. * Making event parameters `indexed` affects how events are decoded, potentially breaking existing indexers. */ interface IGovernor is IERC165, IERC6372 { enum ProposalState { Pending, Active, Canceled, Defeated, Succeeded, Queued, Expired, Executed } /** * @dev Empty proposal or a mismatch between the parameters length for a proposal call. */ error GovernorInvalidProposalLength(uint256 targets, uint256 calldatas, uint256 values); /** * @dev The vote was already cast. */ error GovernorAlreadyCastVote(address voter); /** * @dev Token deposits are disabled in this contract. */ error GovernorDisabledDeposit(); /** * @dev The `account` is not a proposer. */ error GovernorOnlyProposer(address account); /** * @dev The `account` is not the governance executor. */ error GovernorOnlyExecutor(address account); /** * @dev The `proposalId` doesn't exist. */ error GovernorNonexistentProposal(uint256 proposalId); /** * @dev The current state of a proposal is not the required for performing an operation. * The `expectedStates` is a bitmap with the bits enabled for each ProposalState enum position * counting from right to left. * * NOTE: If `expectedState` is `bytes32(0)`, the proposal is expected to not be in any state (i.e. not exist). * This is the case when a proposal that is expected to be unset is already initiated (the proposal is duplicated). * * See {Governor-_encodeStateBitmap}. */ error GovernorUnexpectedProposalState(uint256 proposalId, ProposalState current, bytes32 expectedStates); /** * @dev The voting period set is not a valid period. */ error GovernorInvalidVotingPeriod(uint256 votingPeriod); /** * @dev The `proposer` does not have the required votes to create a proposal. */ error GovernorInsufficientProposerVotes(address proposer, uint256 votes, uint256 threshold); /** * @dev The `proposer` is not allowed to create a proposal. */ error GovernorRestrictedProposer(address proposer); /** * @dev The vote type used is not valid for the corresponding counting module. */ error GovernorInvalidVoteType(); /** * @dev The provided params buffer is not supported by the counting module. */ error GovernorInvalidVoteParams(); /** * @dev Queue operation is not implemented for this governor. Execute should be called directly. */ error GovernorQueueNotImplemented(); /** * @dev The proposal hasn't been queued yet. */ error GovernorNotQueuedProposal(uint256 proposalId); /** * @dev The proposal has already been queued. */ error GovernorAlreadyQueuedProposal(uint256 proposalId); /** * @dev The provided signature is not valid for the expected `voter`. * If the `voter` is a contract, the signature is not valid using {IERC1271-isValidSignature}. */ error GovernorInvalidSignature(address voter); /** * @dev Emitted when a proposal is created. */ event ProposalCreated( uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 voteStart, uint256 voteEnd, string description ); /** * @dev Emitted when a proposal is queued. */ event ProposalQueued(uint256 proposalId, uint256 etaSeconds); /** * @dev Emitted when a proposal is executed. */ event ProposalExecuted(uint256 proposalId); /** * @dev Emitted when a proposal is canceled. */ event ProposalCanceled(uint256 proposalId); /** * @dev Emitted when a vote is cast without params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. */ event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); /** * @dev Emitted when a vote is cast with params. * * Note: `support` values should be seen as buckets. Their interpretation depends on the voting module used. * `params` are additional encoded parameters. Their interpretation also depends on the voting module used. */ event VoteCastWithParams( address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params ); /** * @notice module:core * @dev Name of the governor instance (used in building the EIP-712 domain separator). */ function name() external view returns (string memory); /** * @notice module:core * @dev Version of the governor instance (used in building the EIP-712 domain separator). Default: "1" */ function version() external view returns (string memory); /** * @notice module:voting * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of * key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`. * * There are 2 standard keys: `support` and `quorum`. * * - `support=bravo` refers to the vote options 0 = Against, 1 = For, 2 = Abstain, as in `GovernorBravo`. * - `quorum=bravo` means that only For votes are counted towards quorum. * - `quorum=for,abstain` means that both For and Abstain votes are counted towards quorum. * * If a counting module makes use of encoded `params`, it should include this under a `params` key with a unique * name that describes the behavior. For example: * * - `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain. * - `params=erc721` might refer to a scheme where specific NFTs are delegated to vote. * * NOTE: The string can be decoded by the standard * https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams[`URLSearchParams`] * JavaScript class. */ // solhint-disable-next-line func-name-mixedcase function COUNTING_MODE() external view returns (string memory); /** * @notice module:core * @dev Hashing function used to (re)build the proposal id from the proposal details.. */ function hashProposal( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external pure returns (uint256); /** * @notice module:core * @dev Current state of a proposal, following Compound's convention */ function state(uint256 proposalId) external view returns (ProposalState); /** * @notice module:core * @dev The number of votes required in order for a voter to become a proposer. */ function proposalThreshold() external view returns (uint256); /** * @notice module:core * @dev Timepoint used to retrieve user's votes and quorum. If using block number (as per Compound's Comp), the * snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the * following block. */ function proposalSnapshot(uint256 proposalId) external view returns (uint256); /** * @notice module:core * @dev Timepoint at which votes close. If using block number, votes close at the end of this block, so it is * possible to cast a vote during this block. */ function proposalDeadline(uint256 proposalId) external view returns (uint256); /** * @notice module:core * @dev The account that created a proposal. */ function proposalProposer(uint256 proposalId) external view returns (address); /** * @notice module:core * @dev The time when a queued proposal becomes executable ("ETA"). Unlike {proposalSnapshot} and * {proposalDeadline}, this doesn't use the governor clock, and instead relies on the executor's clock which may be * different. In most cases this will be a timestamp. */ function proposalEta(uint256 proposalId) external view returns (uint256); /** * @notice module:core * @dev Whether a proposal needs to be queued before execution. */ function proposalNeedsQueuing(uint256 proposalId) external view returns (bool); /** * @notice module:user-config * @dev Delay, between the proposal is created and the vote starts. The unit this duration is expressed in depends * on the clock (see ERC-6372) this contract uses. * * This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a * proposal starts. * * NOTE: While this interface returns a uint256, timepoints are stored as uint48 following the ERC-6372 clock type. * Consequently this value must fit in a uint48 (when added to the current clock). See {IERC6372-clock}. */ function votingDelay() external view returns (uint256); /** * @notice module:user-config * @dev Delay between the vote start and vote end. The unit this duration is expressed in depends on the clock * (see ERC-6372) this contract uses. * * NOTE: The {votingDelay} can delay the start of the vote. This must be considered when setting the voting * duration compared to the voting delay. * * NOTE: This value is stored when the proposal is submitted so that possible changes to the value do not affect * proposals that have already been submitted. The type used to save it is a uint32. Consequently, while this * interface returns a uint256, the value it returns should fit in a uint32. */ function votingPeriod() external view returns (uint256); /** * @notice module:user-config * @dev Minimum number of cast voted required for a proposal to be successful. * * NOTE: The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows to scale the * quorum depending on values such as the totalSupply of a token at this timepoint (see {ERC20Votes}). */ function quorum(uint256 timepoint) external view returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `timepoint`. * * Note: this can be implemented in a number of ways, for example by reading the delegated balance from one (or * multiple), {ERC20Votes} tokens. */ function getVotes(address account, uint256 timepoint) external view returns (uint256); /** * @notice module:reputation * @dev Voting power of an `account` at a specific `timepoint` given additional encoded parameters. */ function getVotesWithParams( address account, uint256 timepoint, bytes memory params ) external view returns (uint256); /** * @notice module:voting * @dev Returns whether `account` has cast a vote on `proposalId`. */ function hasVoted(uint256 proposalId, address account) external view returns (bool); /** * @dev Create a new proposal. Vote start after a delay specified by {IGovernor-votingDelay} and lasts for a * duration specified by {IGovernor-votingPeriod}. * * Emits a {ProposalCreated} event. * * NOTE: The state of the Governor and `targets` may change between the proposal creation and its execution. * This may be the result of third party actions on the targeted contracts, or other governor proposals. * For example, the balance of this contract could be updated or its access control permissions may be modified, * possibly compromising the proposal's ability to execute successfully (e.g. the governor doesn't have enough * value to cover a proposal with multiple transfers). */ function propose( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description ) external returns (uint256 proposalId); /** * @dev Queue a proposal. Some governors require this step to be performed before execution can happen. If queuing * is not necessary, this function may revert. * Queuing a proposal requires the quorum to be reached, the vote to be successful, and the deadline to be reached. * * Emits a {ProposalQueued} event. */ function queue( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external returns (uint256 proposalId); /** * @dev Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the * deadline to be reached. Depending on the governor it might also be required that the proposal was queued and * that some delay passed. * * Emits a {ProposalExecuted} event. * * NOTE: Some modules can modify the requirements for execution, for example by adding an additional timelock. */ function execute( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external payable returns (uint256 proposalId); /** * @dev Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e. * before the vote starts. * * Emits a {ProposalCanceled} event. */ function cancel( address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) external returns (uint256 proposalId); /** * @dev Cast a vote * * Emits a {VoteCast} event. */ function castVote(uint256 proposalId, uint8 support) external returns (uint256 balance); /** * @dev Cast a vote with a reason * * Emits a {VoteCast} event. */ function castVoteWithReason( uint256 proposalId, uint8 support, string calldata reason ) external returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParams( uint256 proposalId, uint8 support, string calldata reason, bytes memory params ) external returns (uint256 balance); /** * @dev Cast a vote using the voter's signature, including ERC-1271 signature support. * * Emits a {VoteCast} event. */ function castVoteBySig( uint256 proposalId, uint8 support, address voter, bytes memory signature ) external returns (uint256 balance); /** * @dev Cast a vote with a reason and additional encoded parameters using the voter's signature, * including ERC-1271 signature support. * * Emits a {VoteCast} or {VoteCastWithParams} event depending on the length of params. */ function castVoteWithReasonAndParamsBySig( uint256 proposalId, uint8 support, address voter, string calldata reason, bytes memory params, bytes memory signature ) external returns (uint256 balance); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (governance/TimelockController.sol) pragma solidity ^0.8.20; import {AccessControl} from "../access/AccessControl.sol"; import {ERC721Holder} from "../token/ERC721/utils/ERC721Holder.sol"; import {ERC1155Holder} from "../token/ERC1155/utils/ERC1155Holder.sol"; import {Address} from "../utils/Address.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 TimelockController is AccessControl, ERC721Holder, ERC1155Holder { 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); mapping(bytes32 id => uint256) private _timestamps; uint256 private _minDelay; 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); /** * @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. */ constructor(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) { // 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(AccessControl, ERC1155Holder) 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) { 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) { 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 { 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) { 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 { 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 { 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)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/IVotes.sol) pragma solidity ^0.8.20; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. */ interface IVotes { /** * @dev The signature used has expired. */ error VotesExpiredSignature(uint256 expiry); /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of voting units. */ event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. */ function getPastVotes(address account, uint256 timepoint) external view returns (uint256); /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 timepoint) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1271.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-1271 standard signature validation method for * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. */ interface IERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param hash Hash of the data to be signed * @param signature Signature byte array associated with _data */ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.20; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5805.sol) pragma solidity ^0.8.20; import {IVotes} from "../governance/utils/IVotes.sol"; import {IERC6372} from "./IERC6372.sol"; interface IERC5805 is IERC6372, IVotes {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol) pragma solidity ^0.8.20; interface IERC6372 { /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() external view returns (uint48); /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Interface that must be implemented by smart contracts in order to receive * ERC-1155 token transfers. */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC-1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC-1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC1155/utils/ERC1155Holder.sol) pragma solidity ^0.8.20; import {IERC165, ERC165} from "../../../utils/introspection/ERC165.sol"; import {IERC1155Receiver} from "../IERC1155Receiver.sol"; /** * @dev Simple implementation of `IERC1155Receiver` that will allow a contract to hold ERC-1155 tokens. * * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be * stuck. */ abstract contract ERC1155Holder is ERC165, IERC1155Receiver { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId); } function onERC1155Received( address, address, uint256, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] memory, uint256[] memory, bytes memory ) public virtual override returns (bytes4) { return this.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @title ERC-721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC-721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.20; import {IERC721Receiver} from "../IERC721Receiver.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or * {IERC721-setApprovalForAll}. */ abstract contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (utils/Address.sol) pragma solidity ^0.8.20; import {Errors} from "./Errors.sol"; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } (bool success, bytes memory returndata) = recipient.call{value: amount}(""); if (!success) { _revert(returndata); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {Errors.FailedCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case * of an unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {Errors.FailedCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.20; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS } /** * @dev The signature derives the `address(0)`. */ error ECDSAInvalidSignature(); /** * @dev The signature has an invalid length. */ error ECDSAInvalidSignatureLength(uint256 length); /** * @dev The signature has an S value that is in the upper half order. */ error ECDSAInvalidSignatureS(bytes32 s); /** * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not * return address(0) without also returning an error description. Errors are documented using an enum (error type) * and a bytes32 providing additional information about the error. * * If no error is returned, then the address can be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] */ function tryRecover( bytes32 hash, bytes memory signature ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly ("memory-safe") { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures] */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { unchecked { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); // We do not check for an overflow here since the shift operation results in 0 or 1. uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); _throwError(error, errorArg); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS, s); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature, bytes32(0)); } return (signer, RecoverError.NoError, bytes32(0)); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s); _throwError(error, errorArg); return recovered; } /** * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. */ function _throwError(RecoverError error, bytes32 errorArg) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert ECDSAInvalidSignature(); } else if (error == RecoverError.InvalidSignatureLength) { revert ECDSAInvalidSignatureLength(uint256(errorArg)); } else if (error == RecoverError.InvalidSignatureS) { revert ECDSAInvalidSignatureS(errorArg); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.20; import {MessageHashUtils} from "./MessageHashUtils.sol"; import {ShortStrings, ShortString} from "../ShortStrings.sol"; import {IERC5267} from "../../interfaces/IERC5267.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP-712] is a standard for hashing and signing of typed structured data. * * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP-712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * @custom:oz-upgrades-unsafe-allow state-variable-immutable */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP-712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {IERC-5267}. */ function eip712Domain() public view virtual returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _EIP712Name(), _EIP712Version(), block.chainid, address(this), bytes32(0), new uint256[](0) ); } /** * @dev The name parameter for the EIP712 domain. * * NOTE: By default this function reads _name which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Name() internal view returns (string memory) { return _name.toStringWithFallback(_nameFallback); } /** * @dev The version parameter for the EIP712 domain. * * NOTE: By default this function reads _version which is an immutable value. * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). */ // solhint-disable-next-line func-name-mixedcase function _EIP712Version() internal view returns (string memory) { return _version.toStringWithFallback(_versionFallback); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/MessageHashUtils.sol) pragma solidity ^0.8.20; import {Strings} from "../Strings.sol"; /** * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. * * The library provides methods for generating a hash of a message that conforms to the * https://eips.ethereum.org/EIPS/eip-191[ERC-191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] * specifications. */ library MessageHashUtils { /** * @dev Returns the keccak256 digest of an ERC-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing a bytes32 `messageHash` with * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with * keccak256, although any bytes32 value can be safely used because the final digest will * be re-hashed. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { assembly ("memory-safe") { mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) } } /** * @dev Returns the keccak256 digest of an ERC-191 signed data with version * `0x45` (`personal_sign` messages). * * The digest is calculated by prefixing an arbitrary `message` with * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. * * See {ECDSA-recover}. */ function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) { return keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); } /** * @dev Returns the keccak256 digest of an ERC-191 signed data with version * `0x00` (data with intended validator). * * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended * `validator` address. Then hashing the result. * * See {ECDSA-recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked(hex"19_00", validator, data)); } /** * @dev Returns the keccak256 digest of an EIP-712 typed data (ERC-191 version `0x01`). * * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with * `\x19\x01` and hashing the result. It corresponds to the hash signed by the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. * * See {ECDSA-recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { assembly ("memory-safe") { let ptr := mload(0x40) mstore(ptr, hex"19_01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) digest := keccak256(ptr, 0x42) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/SignatureChecker.sol) pragma solidity ^0.8.20; import {ECDSA} from "./ECDSA.sol"; import {IERC1271} from "../../interfaces/IERC1271.sol"; /** * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA * signatures from externally owned accounts (EOAs) as well as ERC-1271 signatures from smart contract wallets like * Argent and Safe Wallet (previously Gnosis Safe). */ library SignatureChecker { /** * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the * signature is validated against that smart contract using ERC-1271, otherwise it's validated using `ECDSA.recover`. * * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus * change through time. It could return true at block N and false at block N+1 (or the opposite). */ function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) { if (signer.code.length == 0) { (address recovered, ECDSA.RecoverError err, ) = ECDSA.tryRecover(hash, signature); return err == ECDSA.RecoverError.NoError && recovered == signer; } else { return isValidERC1271SignatureNow(signer, hash, signature); } } /** * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated * against the signer smart contract using ERC-1271. * * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus * change through time. It could return true at block N and false at block N+1 (or the opposite). */ function isValidERC1271SignatureNow( address signer, bytes32 hash, bytes memory signature ) internal view returns (bool) { (bool success, bytes memory result) = signer.staticcall( abi.encodeCall(IERC1271.isValidSignature, (hash, signature)) ); return (success && result.length >= 32 && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol) pragma solidity ^0.8.20; import {Panic} from "../Panic.sol"; import {SafeCast} from "./SafeCast.sol"; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an success flag (no overflow). */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow). */ function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow). */ function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a success flag (no division by zero). */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero). */ function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * SafeCast.toUint(condition)); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. Panic.panic(Panic.DIVISION_BY_ZERO); } // The following calculation ensures accurate ceiling division without overflow. // Since a is non-zero, (a - 1) / b will not overflow. // The largest possible result occurs when (a - 1) / b is type(uint256).max, // but the largest value we can obtain is type(uint256).max - 1, which happens // when a = type(uint256).max and b = 1. unchecked { return SafeCast.toUint(a > 0) * ((a - 1) / b + 1); } } /** * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2²⁵⁶ + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0. if (denominator <= prod1) { Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW)); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv ≡ 1 mod 2⁴. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2⁸ inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶ inverse *= 2 - denominator * inverse; // inverse mod 2³² inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴ inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸ inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶ // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @dev Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0); } /** * @dev Calculate the modular multiplicative inverse of a number in Z/nZ. * * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0. * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible. * * If the input value is not inversible, 0 is returned. * * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}. */ function invMod(uint256 a, uint256 n) internal pure returns (uint256) { unchecked { if (n == 0) return 0; // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version) // Used to compute integers x and y such that: ax + ny = gcd(a, n). // When the gcd is 1, then the inverse of a modulo n exists and it's x. // ax + ny = 1 // ax = 1 + (-y)n // ax ≡ 1 (mod n) # x is the inverse of a modulo n // If the remainder is 0 the gcd is n right away. uint256 remainder = a % n; uint256 gcd = n; // Therefore the initial coefficients are: // ax + ny = gcd(a, n) = n // 0a + 1n = n int256 x = 0; int256 y = 1; while (remainder != 0) { uint256 quotient = gcd / remainder; (gcd, remainder) = ( // The old remainder is the next gcd to try. remainder, // Compute the next remainder. // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd // where gcd is at most n (capped to type(uint256).max) gcd - remainder * quotient ); (x, y) = ( // Increment the coefficient of a. y, // Decrement the coefficient of n. // Can overflow, but the result is casted to uint256 so that the // next value of y is "wrapped around" to a value between 0 and n - 1. x - y * int256(quotient) ); } if (gcd != 1) return 0; // No inverse exists. return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative. } } /** * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`. * * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that * `a**(p-2)` is the modular multiplicative inverse of a in Fp. * * NOTE: this function does NOT check that `p` is a prime greater than `2`. */ function invModPrime(uint256 a, uint256 p) internal view returns (uint256) { unchecked { return Math.modExp(a, p - 2, p); } } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m) * * Requirements: * - modulus can't be zero * - underlying staticcall to precompile must succeed * * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make * sure the chain you're using it on supports the precompiled contract for modular exponentiation * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, * the underlying function will succeed given the lack of a revert, but the result may be incorrectly * interpreted as 0. */ function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) { (bool success, uint256 result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m). * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying * to operate modulo 0 or if the underlying precompile reverted. * * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack * of a revert, but the result may be incorrectly interpreted as 0. */ function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) { if (m == 0) return (false, 0); assembly ("memory-safe") { let ptr := mload(0x40) // | Offset | Content | Content (Hex) | // |-----------|------------|--------------------------------------------------------------------| // | 0x00:0x1f | size of b | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x20:0x3f | size of e | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x40:0x5f | size of m | 0x0000000000000000000000000000000000000000000000000000000000000020 | // | 0x60:0x7f | value of b | 0x<.............................................................b> | // | 0x80:0x9f | value of e | 0x<.............................................................e> | // | 0xa0:0xbf | value of m | 0x<.............................................................m> | mstore(ptr, 0x20) mstore(add(ptr, 0x20), 0x20) mstore(add(ptr, 0x40), 0x20) mstore(add(ptr, 0x60), b) mstore(add(ptr, 0x80), e) mstore(add(ptr, 0xa0), m) // Given the result < m, it's guaranteed to fit in 32 bytes, // so we can use the memory scratch space located at offset 0. success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20) result := mload(0x00) } } /** * @dev Variant of {modExp} that supports inputs of arbitrary length. */ function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) { (bool success, bytes memory result) = tryModExp(b, e, m); if (!success) { Panic.panic(Panic.DIVISION_BY_ZERO); } return result; } /** * @dev Variant of {tryModExp} that supports inputs of arbitrary length. */ function tryModExp( bytes memory b, bytes memory e, bytes memory m ) internal view returns (bool success, bytes memory result) { if (_zeroBytes(m)) return (false, new bytes(0)); uint256 mLen = m.length; // Encode call args in result and move the free memory pointer result = abi.encodePacked(b.length, e.length, mLen, b, e, m); assembly ("memory-safe") { let dataPtr := add(result, 0x20) // Write result on top of args to avoid allocating extra memory. success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen) // Overwrite the length. // result.length > returndatasize() is guaranteed because returndatasize() == m.length mstore(result, mLen) // Set the memory pointer after the returned data. mstore(0x40, add(dataPtr, mLen)) } } /** * @dev Returns whether the provided byte array is zero. */ function _zeroBytes(bytes memory byteArray) private pure returns (bool) { for (uint256 i = 0; i < byteArray.length; ++i) { if (byteArray[i] != 0) { return false; } } return true; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * This method is based on Newton's method for computing square roots; the algorithm is restricted to only * using integer operations. */ function sqrt(uint256 a) internal pure returns (uint256) { unchecked { // Take care of easy edge cases when a == 0 or a == 1 if (a <= 1) { return a; } // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between // the current value as `ε_n = | x_n - sqrt(a) |`. // // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is // bigger than any uint256. // // By noticing that // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)` // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar // to the msb function. uint256 aa = a; uint256 xn = 1; if (aa >= (1 << 128)) { aa >>= 128; xn <<= 64; } if (aa >= (1 << 64)) { aa >>= 64; xn <<= 32; } if (aa >= (1 << 32)) { aa >>= 32; xn <<= 16; } if (aa >= (1 << 16)) { aa >>= 16; xn <<= 8; } if (aa >= (1 << 8)) { aa >>= 8; xn <<= 4; } if (aa >= (1 << 4)) { aa >>= 4; xn <<= 2; } if (aa >= (1 << 2)) { xn <<= 1; } // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1). // // We can refine our estimation by noticing that the middle of that interval minimizes the error. // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2). // This is going to be our x_0 (and ε_0) xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2) // From here, Newton's method give us: // x_{n+1} = (x_n + a / x_n) / 2 // // One should note that: // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a // = ((x_n² + a) / (2 * x_n))² - a // = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a // = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²) // = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²) // = (x_n² - a)² / (2 * x_n)² // = ((x_n² - a) / (2 * x_n))² // ≥ 0 // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n // // This gives us the proof of quadratic convergence of the sequence: // ε_{n+1} = | x_{n+1} - sqrt(a) | // = | (x_n + a / x_n) / 2 - sqrt(a) | // = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) | // = | (x_n - sqrt(a))² / (2 * x_n) | // = | ε_n² / (2 * x_n) | // = ε_n² / | (2 * x_n) | // // For the first iteration, we have a special case where x_0 is known: // ε_1 = ε_0² / | (2 * x_0) | // ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2))) // ≤ 2**(2*e-4) / (3 * 2**(e-1)) // ≤ 2**(e-3) / 3 // ≤ 2**(e-3-log2(3)) // ≤ 2**(e-4.5) // // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n: // ε_{n+1} = ε_n² / | (2 * x_n) | // ≤ (2**(e-k))² / (2 * 2**(e-1)) // ≤ 2**(2*e-2*k) / 2**e // ≤ 2**(e-2*k) xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5) -- special case, see above xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9) -- general case with k = 4.5 xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18) -- general case with k = 9 xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36) -- general case with k = 18 xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72) -- general case with k = 36 xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144) -- general case with k = 72 // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either // sqrt(a) or sqrt(a) + 1. return xn - SafeCast.toUint(xn > a / xn); } } /** * @dev Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 exp; unchecked { exp = 128 * SafeCast.toUint(value > (1 << 128) - 1); value >>= exp; result += exp; exp = 64 * SafeCast.toUint(value > (1 << 64) - 1); value >>= exp; result += exp; exp = 32 * SafeCast.toUint(value > (1 << 32) - 1); value >>= exp; result += exp; exp = 16 * SafeCast.toUint(value > (1 << 16) - 1); value >>= exp; result += exp; exp = 8 * SafeCast.toUint(value > (1 << 8) - 1); value >>= exp; result += exp; exp = 4 * SafeCast.toUint(value > (1 << 4) - 1); value >>= exp; result += exp; exp = 2 * SafeCast.toUint(value > (1 << 2) - 1); value >>= exp; result += exp; result += SafeCast.toUint(value > 1); } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; uint256 isGt; unchecked { isGt = SafeCast.toUint(value > (1 << 128) - 1); value >>= isGt * 128; result += isGt * 16; isGt = SafeCast.toUint(value > (1 << 64) - 1); value >>= isGt * 64; result += isGt * 8; isGt = SafeCast.toUint(value > (1 << 32) - 1); value >>= isGt * 32; result += isGt * 4; isGt = SafeCast.toUint(value > (1 << 16) - 1); value >>= isGt * 16; result += isGt * 2; result += SafeCast.toUint(value > (1 << 8) - 1); } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; import {SafeCast} from "./SafeCast.sol"; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant. * * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone. * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute * one branch when needed, making this function more expensive. */ function ternary(bool condition, int256 a, int256 b) internal pure returns (int256) { unchecked { // branchless ternary works because: // b ^ (a ^ b) == a // b ^ 0 == b return b ^ ((a ^ b) * int256(SafeCast.toUint(condition))); } } /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return ternary(a > b, a, b); } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return ternary(a < b, a, b); } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // Formula from the "Bit Twiddling Hacks" by Sean Eron Anderson. // Since `n` is a signed integer, the generated bytecode will use the SAR opcode to perform the right shift, // taking advantage of the most significant (or "sign" bit) in two's complement representation. // This opcode adds new most significant bits set to the value of the previous most significant bit. As a result, // the mask will either be `bytes32(0)` (if n is positive) or `~bytes32(0)` (if n is negative). int256 mask = n >> 255; // A `bytes32(0)` mask leaves the input unchanged, while a `~bytes32(0)` mask complements it. return uint256((n + mask) ^ mask); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol) pragma solidity ^0.8.20; /** * @dev Provides tracking nonces for addresses. Nonces will only increment. */ abstract contract Nonces { /** * @dev The nonce used for an `account` is not the expected current nonce. */ error InvalidAccountNonce(address account, uint256 currentNonce); mapping(address account => uint256) private _nonces; /** * @dev Returns the next unused nonce for an address. */ function nonces(address owner) public view virtual returns (uint256) { return _nonces[owner]; } /** * @dev Consumes a nonce. * * Returns the current value and increments nonce. */ function _useNonce(address owner) internal virtual returns (uint256) { // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be // decremented or reset. This guarantees that the nonce never overflows. unchecked { // It is important to do x++ and not ++x here. return _nonces[owner]++; } } /** * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`. */ function _useCheckedNonce(address owner, uint256 nonce) internal virtual { uint256 current = _useNonce(owner); if (nonce != current) { revert InvalidAccountNonce(owner, current); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol) pragma solidity ^0.8.20; /** * @dev Helper library for emitting standardized panic codes. * * ```solidity * contract Example { * using Panic for uint256; * * // Use any of the declared internal constants * function foo() { Panic.GENERIC.panic(); } * * // Alternatively * function foo() { Panic.panic(Panic.GENERIC); } * } * ``` * * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil]. * * _Available since v5.1._ */ // slither-disable-next-line unused-state library Panic { /// @dev generic / unspecified error uint256 internal constant GENERIC = 0x00; /// @dev used by the assert() builtin uint256 internal constant ASSERT = 0x01; /// @dev arithmetic underflow or overflow uint256 internal constant UNDER_OVERFLOW = 0x11; /// @dev division or modulo by zero uint256 internal constant DIVISION_BY_ZERO = 0x12; /// @dev enum conversion error uint256 internal constant ENUM_CONVERSION_ERROR = 0x21; /// @dev invalid encoding in storage uint256 internal constant STORAGE_ENCODING_ERROR = 0x22; /// @dev empty array pop uint256 internal constant EMPTY_ARRAY_POP = 0x31; /// @dev array out of bounds access uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32; /// @dev resource error (too large allocation or too large array) uint256 internal constant RESOURCE_ERROR = 0x41; /// @dev calling invalid internal function uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51; /// @dev Reverts with a panic code. Recommended to use with /// the internal constants with predefined codes. function panic(uint256 code) internal pure { assembly ("memory-safe") { mstore(0x00, 0x4e487b71) mstore(0x20, code) revert(0x1c, 0x24) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ShortStrings.sol) pragma solidity ^0.8.20; import {StorageSlot} from "./StorageSlot.sol"; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); assembly ("memory-safe") { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using * {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.20; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC-1967 implementation slot: * ```solidity * contract ERC1967 { * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot. * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(newImplementation.code.length > 0); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * TIP: Consider using this library along with {SlotDerivation}. */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct Int256Slot { int256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `Int256Slot` with member `value` located at `slot`. */ function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns a `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { assembly ("memory-safe") { r.slot := store.slot } } /** * @dev Returns a `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { assembly ("memory-safe") { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { assembly ("memory-safe") { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (utils/Strings.sol) pragma solidity ^0.8.20; import {Math} from "./math/Math.sol"; import {SafeCast} from "./math/SafeCast.sol"; import {SignedMath} from "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { using SafeCast for *; bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @dev The string being parsed contains characters that are not in scope of the given base. */ error StringsInvalidChar(); /** * @dev The string being parsed is not a properly formatted address. */ error StringsInvalidAddressFormat(); /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; assembly ("memory-safe") { ptr := add(buffer, add(32, length)) } while (true) { ptr--; assembly ("memory-safe") { mstore8(ptr, byte(mod(value, 10), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal * representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH); } /** * @dev Converts an `address` with fixed length of 20 bytes to its checksummed ASCII `string` hexadecimal * representation, according to EIP-55. */ function toChecksumHexString(address addr) internal pure returns (string memory) { bytes memory buffer = bytes(toHexString(addr)); // hash the hex part of buffer (skip length + 2 bytes, length 40) uint256 hashValue; assembly ("memory-safe") { hashValue := shr(96, keccak256(add(buffer, 0x22), 40)) } for (uint256 i = 41; i > 1; --i) { // possible values for buffer[i] are 48 (0) to 57 (9) and 97 (a) to 102 (f) if (hashValue & 0xf > 7 && uint8(buffer[i]) > 96) { // case shift by xoring with 0x20 buffer[i] ^= 0x20; } hashValue >>= 4; } return string(buffer); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } /** * @dev Parse a decimal string and returns the value as a `uint256`. * * Requirements: * - The string must be formatted as `[0-9]*` * - The result must fit into an `uint256` type */ function parseUint(string memory input) internal pure returns (uint256) { return parseUint(input, 0, bytes(input).length); } /** * @dev Variant of {parseUint} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `[0-9]*` * - The result must fit into an `uint256` type */ function parseUint(string memory input, uint256 begin, uint256 end) internal pure returns (uint256) { (bool success, uint256 value) = tryParseUint(input, begin, end); if (!success) revert StringsInvalidChar(); return value; } /** * @dev Variant of {parseUint-string} that returns false if the parsing fails because of an invalid character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseUint(string memory input) internal pure returns (bool success, uint256 value) { return _tryParseUintUncheckedBounds(input, 0, bytes(input).length); } /** * @dev Variant of {parseUint-string-uint256-uint256} that returns false if the parsing fails because of an invalid * character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseUint( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, uint256 value) { if (end > bytes(input).length || begin > end) return (false, 0); return _tryParseUintUncheckedBounds(input, begin, end); } /** * @dev Implementation of {tryParseUint} that does not check bounds. Caller should make sure that * `begin <= end <= input.length`. Other inputs would result in undefined behavior. */ function _tryParseUintUncheckedBounds( string memory input, uint256 begin, uint256 end ) private pure returns (bool success, uint256 value) { bytes memory buffer = bytes(input); uint256 result = 0; for (uint256 i = begin; i < end; ++i) { uint8 chr = _tryParseChr(bytes1(_unsafeReadBytesOffset(buffer, i))); if (chr > 9) return (false, 0); result *= 10; result += chr; } return (true, result); } /** * @dev Parse a decimal string and returns the value as a `int256`. * * Requirements: * - The string must be formatted as `[-+]?[0-9]*` * - The result must fit in an `int256` type. */ function parseInt(string memory input) internal pure returns (int256) { return parseInt(input, 0, bytes(input).length); } /** * @dev Variant of {parseInt-string} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `[-+]?[0-9]*` * - The result must fit in an `int256` type. */ function parseInt(string memory input, uint256 begin, uint256 end) internal pure returns (int256) { (bool success, int256 value) = tryParseInt(input, begin, end); if (!success) revert StringsInvalidChar(); return value; } /** * @dev Variant of {parseInt-string} that returns false if the parsing fails because of an invalid character or if * the result does not fit in a `int256`. * * NOTE: This function will revert if the absolute value of the result does not fit in a `uint256`. */ function tryParseInt(string memory input) internal pure returns (bool success, int256 value) { return _tryParseIntUncheckedBounds(input, 0, bytes(input).length); } uint256 private constant ABS_MIN_INT256 = 2 ** 255; /** * @dev Variant of {parseInt-string-uint256-uint256} that returns false if the parsing fails because of an invalid * character or if the result does not fit in a `int256`. * * NOTE: This function will revert if the absolute value of the result does not fit in a `uint256`. */ function tryParseInt( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, int256 value) { if (end > bytes(input).length || begin > end) return (false, 0); return _tryParseIntUncheckedBounds(input, begin, end); } /** * @dev Implementation of {tryParseInt} that does not check bounds. Caller should make sure that * `begin <= end <= input.length`. Other inputs would result in undefined behavior. */ function _tryParseIntUncheckedBounds( string memory input, uint256 begin, uint256 end ) private pure returns (bool success, int256 value) { bytes memory buffer = bytes(input); // Check presence of a negative sign. bytes1 sign = begin == end ? bytes1(0) : bytes1(_unsafeReadBytesOffset(buffer, begin)); // don't do out-of-bound (possibly unsafe) read if sub-string is empty bool positiveSign = sign == bytes1("+"); bool negativeSign = sign == bytes1("-"); uint256 offset = (positiveSign || negativeSign).toUint(); (bool absSuccess, uint256 absValue) = tryParseUint(input, begin + offset, end); if (absSuccess && absValue < ABS_MIN_INT256) { return (true, negativeSign ? -int256(absValue) : int256(absValue)); } else if (absSuccess && negativeSign && absValue == ABS_MIN_INT256) { return (true, type(int256).min); } else return (false, 0); } /** * @dev Parse a hexadecimal string (with or without "0x" prefix), and returns the value as a `uint256`. * * Requirements: * - The string must be formatted as `(0x)?[0-9a-fA-F]*` * - The result must fit in an `uint256` type. */ function parseHexUint(string memory input) internal pure returns (uint256) { return parseHexUint(input, 0, bytes(input).length); } /** * @dev Variant of {parseHexUint} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `(0x)?[0-9a-fA-F]*` * - The result must fit in an `uint256` type. */ function parseHexUint(string memory input, uint256 begin, uint256 end) internal pure returns (uint256) { (bool success, uint256 value) = tryParseHexUint(input, begin, end); if (!success) revert StringsInvalidChar(); return value; } /** * @dev Variant of {parseHexUint-string} that returns false if the parsing fails because of an invalid character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseHexUint(string memory input) internal pure returns (bool success, uint256 value) { return _tryParseHexUintUncheckedBounds(input, 0, bytes(input).length); } /** * @dev Variant of {parseHexUint-string-uint256-uint256} that returns false if the parsing fails because of an * invalid character. * * NOTE: This function will revert if the result does not fit in a `uint256`. */ function tryParseHexUint( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, uint256 value) { if (end > bytes(input).length || begin > end) return (false, 0); return _tryParseHexUintUncheckedBounds(input, begin, end); } /** * @dev Implementation of {tryParseHexUint} that does not check bounds. Caller should make sure that * `begin <= end <= input.length`. Other inputs would result in undefined behavior. */ function _tryParseHexUintUncheckedBounds( string memory input, uint256 begin, uint256 end ) private pure returns (bool success, uint256 value) { bytes memory buffer = bytes(input); // skip 0x prefix if present bool hasPrefix = (end > begin + 1) && bytes2(_unsafeReadBytesOffset(buffer, begin)) == bytes2("0x"); // don't do out-of-bound (possibly unsafe) read if sub-string is empty uint256 offset = hasPrefix.toUint() * 2; uint256 result = 0; for (uint256 i = begin + offset; i < end; ++i) { uint8 chr = _tryParseChr(bytes1(_unsafeReadBytesOffset(buffer, i))); if (chr > 15) return (false, 0); result *= 16; unchecked { // Multiplying by 16 is equivalent to a shift of 4 bits (with additional overflow check). // This guaratees that adding a value < 16 will not cause an overflow, hence the unchecked. result += chr; } } return (true, result); } /** * @dev Parse a hexadecimal string (with or without "0x" prefix), and returns the value as an `address`. * * Requirements: * - The string must be formatted as `(0x)?[0-9a-fA-F]{40}` */ function parseAddress(string memory input) internal pure returns (address) { return parseAddress(input, 0, bytes(input).length); } /** * @dev Variant of {parseAddress} that parses a substring of `input` located between position `begin` (included) and * `end` (excluded). * * Requirements: * - The substring must be formatted as `(0x)?[0-9a-fA-F]{40}` */ function parseAddress(string memory input, uint256 begin, uint256 end) internal pure returns (address) { (bool success, address value) = tryParseAddress(input, begin, end); if (!success) revert StringsInvalidAddressFormat(); return value; } /** * @dev Variant of {parseAddress-string} that returns false if the parsing fails because the input is not a properly * formatted address. See {parseAddress} requirements. */ function tryParseAddress(string memory input) internal pure returns (bool success, address value) { return tryParseAddress(input, 0, bytes(input).length); } /** * @dev Variant of {parseAddress-string-uint256-uint256} that returns false if the parsing fails because input is not a properly * formatted address. See {parseAddress} requirements. */ function tryParseAddress( string memory input, uint256 begin, uint256 end ) internal pure returns (bool success, address value) { if (end > bytes(input).length || begin > end) return (false, address(0)); bool hasPrefix = (end > begin + 1) && bytes2(_unsafeReadBytesOffset(bytes(input), begin)) == bytes2("0x"); // don't do out-of-bound (possibly unsafe) read if sub-string is empty uint256 expectedLength = 40 + hasPrefix.toUint() * 2; // check that input is the correct length if (end - begin == expectedLength) { // length guarantees that this does not overflow, and value is at most type(uint160).max (bool s, uint256 v) = _tryParseHexUintUncheckedBounds(input, begin, end); return (s, address(uint160(v))); } else { return (false, address(0)); } } function _tryParseChr(bytes1 chr) private pure returns (uint8) { uint8 value = uint8(chr); // Try to parse `chr`: // - Case 1: [0-9] // - Case 2: [a-f] // - Case 3: [A-F] // - otherwise not supported unchecked { if (value > 47 && value < 58) value -= 48; else if (value > 96 && value < 103) value -= 87; else if (value > 64 && value < 71) value -= 55; else return type(uint8).max; } return value; } /** * @dev Reads a bytes32 from a bytes array without bounds checking. * * NOTE: making this function internal would mean it could be used with memory unsafe offset, and marking the * assembly block as such would prevent some optimizations. */ function _unsafeReadBytesOffset(bytes memory buffer, uint256 offset) private pure returns (bytes32 value) { // This is not memory safe in the general case, but all calls to this private function are within bounds. assembly ("memory-safe") { value := mload(add(buffer, add(0x20, offset))) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/structs/Checkpoints.sol) // This file was procedurally generated from scripts/generate/templates/Checkpoints.js. pragma solidity ^0.8.20; import {Math} from "../math/Math.sol"; /** * @dev This library defines the `Trace*` struct, for checkpointing values as they change at different points in * time, and later looking up past values by block number. See {Votes} as an example. * * To create a history of checkpoints define a variable type `Checkpoints.Trace*` in your contract, and store a new * checkpoint for the current transaction block using the {push} function. */ library Checkpoints { /** * @dev A value was attempted to be inserted on a past checkpoint. */ error CheckpointUnorderedInsertion(); struct Trace224 { Checkpoint224[] _checkpoints; } struct Checkpoint224 { uint32 _key; uint224 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint. * * Returns previous value and new value. * * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint32).max` key set will disable the * library. */ function push( Trace224 storage self, uint32 key, uint224 value ) internal returns (uint224 oldValue, uint224 newValue) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if * there is none. */ function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. */ function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high * keys). */ function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace224 storage self) internal view returns (uint224) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint224 storage ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace224 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Returns checkpoint at given position. */ function at(Trace224 storage self, uint32 pos) internal view returns (Checkpoint224 memory) { return self._checkpoints[pos]; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert( Checkpoint224[] storage self, uint32 key, uint224 value ) private returns (uint224 oldValue, uint224 newValue) { uint256 pos = self.length; if (pos > 0) { Checkpoint224 storage last = _unsafeAccess(self, pos - 1); uint32 lastKey = last._key; uint224 lastValue = last._value; // Checkpoint keys must be non-decreasing. if (lastKey > key) { revert CheckpointUnorderedInsertion(); } // Update or push new checkpoint if (lastKey == key) { last._value = value; } else { self.push(Checkpoint224({_key: key, _value: value})); } return (lastValue, value); } else { self.push(Checkpoint224({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the first (oldest) checkpoint with key strictly bigger than the search key, or `high` * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive * `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key greater or equal than the search key, or `high` * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive * `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint224[] storage self, uint32 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint224[] storage self, uint256 pos ) private pure returns (Checkpoint224 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace208 { Checkpoint208[] _checkpoints; } struct Checkpoint208 { uint48 _key; uint208 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace208 so that it is stored as the checkpoint. * * Returns previous value and new value. * * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint48).max` key set will disable the * library. */ function push( Trace208 storage self, uint48 key, uint208 value ) internal returns (uint208 oldValue, uint208 newValue) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if * there is none. */ function lowerLookup(Trace208 storage self, uint48 key) internal view returns (uint208) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. */ function upperLookup(Trace208 storage self, uint48 key) internal view returns (uint208) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high * keys). */ function upperLookupRecent(Trace208 storage self, uint48 key) internal view returns (uint208) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace208 storage self) internal view returns (uint208) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace208 storage self) internal view returns (bool exists, uint48 _key, uint208 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint208 storage ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace208 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Returns checkpoint at given position. */ function at(Trace208 storage self, uint32 pos) internal view returns (Checkpoint208 memory) { return self._checkpoints[pos]; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert( Checkpoint208[] storage self, uint48 key, uint208 value ) private returns (uint208 oldValue, uint208 newValue) { uint256 pos = self.length; if (pos > 0) { Checkpoint208 storage last = _unsafeAccess(self, pos - 1); uint48 lastKey = last._key; uint208 lastValue = last._value; // Checkpoint keys must be non-decreasing. if (lastKey > key) { revert CheckpointUnorderedInsertion(); } // Update or push new checkpoint if (lastKey == key) { last._value = value; } else { self.push(Checkpoint208({_key: key, _value: value})); } return (lastValue, value); } else { self.push(Checkpoint208({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the first (oldest) checkpoint with key strictly bigger than the search key, or `high` * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive * `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint208[] storage self, uint48 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key greater or equal than the search key, or `high` * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive * `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint208[] storage self, uint48 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint208[] storage self, uint256 pos ) private pure returns (Checkpoint208 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } struct Trace160 { Checkpoint160[] _checkpoints; } struct Checkpoint160 { uint96 _key; uint160 _value; } /** * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint. * * Returns previous value and new value. * * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint96).max` key set will disable the * library. */ function push( Trace160 storage self, uint96 key, uint160 value ) internal returns (uint160 oldValue, uint160 newValue) { return _insert(self._checkpoints, key, value); } /** * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if * there is none. */ function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len); return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. */ function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero * if there is none. * * NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high * keys). */ function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) { uint256 len = self._checkpoints.length; uint256 low = 0; uint256 high = len; if (len > 5) { uint256 mid = len - Math.sqrt(len); if (key < _unsafeAccess(self._checkpoints, mid)._key) { high = mid; } else { low = mid + 1; } } uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high); return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints. */ function latest(Trace160 storage self) internal view returns (uint160) { uint256 pos = self._checkpoints.length; return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value; } /** * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value * in the most recent checkpoint. */ function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) { uint256 pos = self._checkpoints.length; if (pos == 0) { return (false, 0, 0); } else { Checkpoint160 storage ckpt = _unsafeAccess(self._checkpoints, pos - 1); return (true, ckpt._key, ckpt._value); } } /** * @dev Returns the number of checkpoint. */ function length(Trace160 storage self) internal view returns (uint256) { return self._checkpoints.length; } /** * @dev Returns checkpoint at given position. */ function at(Trace160 storage self, uint32 pos) internal view returns (Checkpoint160 memory) { return self._checkpoints[pos]; } /** * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint, * or by updating the last one. */ function _insert( Checkpoint160[] storage self, uint96 key, uint160 value ) private returns (uint160 oldValue, uint160 newValue) { uint256 pos = self.length; if (pos > 0) { Checkpoint160 storage last = _unsafeAccess(self, pos - 1); uint96 lastKey = last._key; uint160 lastValue = last._value; // Checkpoint keys must be non-decreasing. if (lastKey > key) { revert CheckpointUnorderedInsertion(); } // Update or push new checkpoint if (lastKey == key) { last._value = value; } else { self.push(Checkpoint160({_key: key, _value: value})); } return (lastValue, value); } else { self.push(Checkpoint160({_key: key, _value: value})); return (0, value); } } /** * @dev Return the index of the first (oldest) checkpoint with key strictly bigger than the search key, or `high` * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive * `high`. * * WARNING: `high` should not be greater than the array's length. */ function _upperBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key > key) { high = mid; } else { low = mid + 1; } } return high; } /** * @dev Return the index of the first (oldest) checkpoint with key greater or equal than the search key, or `high` * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive * `high`. * * WARNING: `high` should not be greater than the array's length. */ function _lowerBinaryLookup( Checkpoint160[] storage self, uint96 key, uint256 low, uint256 high ) private view returns (uint256) { while (low < high) { uint256 mid = Math.average(low, high); if (_unsafeAccess(self, mid)._key < key) { low = mid + 1; } else { high = mid; } } return high; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess( Checkpoint160[] storage self, uint256 pos ) private pure returns (Checkpoint160 storage result) { assembly { mstore(0, self.slot) result.slot := add(keccak256(0, 0x20), pos) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/structs/DoubleEndedQueue.sol) pragma solidity ^0.8.20; import {Panic} from "../Panic.sol"; /** * @dev A sequence of items with the ability to efficiently push and pop items (i.e. insert and remove) on both ends of * the sequence (called front and back). Among other access patterns, it can be used to implement efficient LIFO and * FIFO queues. Storage use is optimized, and all operations are O(1) constant time. This includes {clear}, given that * the existing queue contents are left in storage. * * The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be * used in storage, and not in memory. * ```solidity * DoubleEndedQueue.Bytes32Deque queue; * ``` */ library DoubleEndedQueue { /** * @dev Indices are 128 bits so begin and end are packed in a single storage slot for efficient access. * * Struct members have an underscore prefix indicating that they are "private" and should not be read or written to * directly. Use the functions provided below instead. Modifying the struct manually may violate assumptions and * lead to unexpected behavior. * * The first item is at data[begin] and the last item is at data[end - 1]. This range can wrap around. */ struct Bytes32Deque { uint128 _begin; uint128 _end; mapping(uint128 index => bytes32) _data; } /** * @dev Inserts an item at the end of the queue. * * Reverts with {Panic-RESOURCE_ERROR} if the queue is full. */ function pushBack(Bytes32Deque storage deque, bytes32 value) internal { unchecked { uint128 backIndex = deque._end; if (backIndex + 1 == deque._begin) Panic.panic(Panic.RESOURCE_ERROR); deque._data[backIndex] = value; deque._end = backIndex + 1; } } /** * @dev Removes the item at the end of the queue and returns it. * * Reverts with {Panic-EMPTY_ARRAY_POP} if the queue is empty. */ function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) { unchecked { uint128 backIndex = deque._end; if (backIndex == deque._begin) Panic.panic(Panic.EMPTY_ARRAY_POP); --backIndex; value = deque._data[backIndex]; delete deque._data[backIndex]; deque._end = backIndex; } } /** * @dev Inserts an item at the beginning of the queue. * * Reverts with {Panic-RESOURCE_ERROR} if the queue is full. */ function pushFront(Bytes32Deque storage deque, bytes32 value) internal { unchecked { uint128 frontIndex = deque._begin - 1; if (frontIndex == deque._end) Panic.panic(Panic.RESOURCE_ERROR); deque._data[frontIndex] = value; deque._begin = frontIndex; } } /** * @dev Removes the item at the beginning of the queue and returns it. * * Reverts with {Panic-EMPTY_ARRAY_POP} if the queue is empty. */ function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) { unchecked { uint128 frontIndex = deque._begin; if (frontIndex == deque._end) Panic.panic(Panic.EMPTY_ARRAY_POP); value = deque._data[frontIndex]; delete deque._data[frontIndex]; deque._begin = frontIndex + 1; } } /** * @dev Returns the item at the beginning of the queue. * * Reverts with {Panic-ARRAY_OUT_OF_BOUNDS} if the queue is empty. */ function front(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS); return deque._data[deque._begin]; } /** * @dev Returns the item at the end of the queue. * * Reverts with {Panic-ARRAY_OUT_OF_BOUNDS} if the queue is empty. */ function back(Bytes32Deque storage deque) internal view returns (bytes32 value) { if (empty(deque)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS); unchecked { return deque._data[deque._end - 1]; } } /** * @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at * `length(deque) - 1`. * * Reverts with {Panic-ARRAY_OUT_OF_BOUNDS} if the index is out of bounds. */ function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) { if (index >= length(deque)) Panic.panic(Panic.ARRAY_OUT_OF_BOUNDS); // By construction, length is a uint128, so the check above ensures that index can be safely downcast to uint128 unchecked { return deque._data[deque._begin + uint128(index)]; } } /** * @dev Resets the queue back to being empty. * * NOTE: The current items are left behind in storage. This does not affect the functioning of the queue, but misses * out on potential gas refunds. */ function clear(Bytes32Deque storage deque) internal { deque._begin = 0; deque._end = 0; } /** * @dev Returns the number of items in the queue. */ function length(Bytes32Deque storage deque) internal view returns (uint256) { unchecked { return uint256(deque._end - deque._begin); } } /** * @dev Returns true if the queue is empty. */ function empty(Bytes32Deque storage deque) internal view returns (bool) { return deque._end == deque._begin; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/types/Time.sol) pragma solidity ^0.8.20; import {Math} from "../math/Math.sol"; import {SafeCast} from "../math/SafeCast.sol"; /** * @dev This library provides helpers for manipulating time-related objects. * * It uses the following types: * - `uint48` for timepoints * - `uint32` for durations * * While the library doesn't provide specific types for timepoints and duration, it does provide: * - a `Delay` type to represent duration that can be programmed to change value automatically at a given point * - additional helper functions */ library Time { using Time for *; /** * @dev Get the block timestamp as a Timepoint. */ function timestamp() internal view returns (uint48) { return SafeCast.toUint48(block.timestamp); } /** * @dev Get the block number as a Timepoint. */ function blockNumber() internal view returns (uint48) { return SafeCast.toUint48(block.number); } // ==================================================== Delay ===================================================== /** * @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the * future. The "effect" timepoint describes when the transitions happens from the "old" value to the "new" value. * This allows updating the delay applied to some operation while keeping some guarantees. * * In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for * some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set * the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should * still apply for some time. * * * The `Delay` type is 112 bits long, and packs the following: * * ``` * | [uint48]: effect date (timepoint) * | | [uint32]: value before (duration) * ↓ ↓ ↓ [uint32]: value after (duration) * 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC * ``` * * NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently * supported. */ type Delay is uint112; /** * @dev Wrap a duration into a Delay to add the one-step "update in the future" feature */ function toDelay(uint32 duration) internal pure returns (Delay) { return Delay.wrap(duration); } /** * @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled * change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered. */ function _getFullAt( Delay self, uint48 timepoint ) private pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) { (valueBefore, valueAfter, effect) = self.unpack(); return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect); } /** * @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the * effect timepoint is 0, then the pending value should not be considered. */ function getFull(Delay self) internal view returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) { return _getFullAt(self, timestamp()); } /** * @dev Get the current value. */ function get(Delay self) internal view returns (uint32) { (uint32 delay, , ) = self.getFull(); return delay; } /** * @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to * enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the * new delay becomes effective. */ function withUpdate( Delay self, uint32 newValue, uint32 minSetback ) internal view returns (Delay updatedDelay, uint48 effect) { uint32 value = self.get(); uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0)); effect = timestamp() + setback; return (pack(value, newValue, effect), effect); } /** * @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint). */ function unpack(Delay self) internal pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) { uint112 raw = Delay.unwrap(self); valueAfter = uint32(raw); valueBefore = uint32(raw >> 32); effect = uint48(raw >> 64); return (valueBefore, valueAfter, effect); } /** * @dev pack the components into a Delay object. */ function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect) internal pure returns (Delay) { return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter)); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract ABI
API[{"inputs":[{"internalType":"contract IVotes","name":"_token","type":"address"},{"internalType":"contract TimelockController","name":"_timelock","type":"address"},{"internalType":"uint256","name":"_quorumPercentage","type":"uint256"},{"internalType":"uint32","name":"_votingPeriod","type":"uint32"},{"internalType":"uint48","name":"_votingDelay","type":"uint48"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CheckpointUnorderedInsertion","type":"error"},{"inputs":[],"name":"FailedCall","type":"error"},{"inputs":[{"internalType":"address","name":"voter","type":"address"}],"name":"GovernorAlreadyCastVote","type":"error"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"GovernorAlreadyQueuedProposal","type":"error"},{"inputs":[],"name":"GovernorDisabledDeposit","type":"error"},{"inputs":[{"internalType":"address","name":"proposer","type":"address"},{"internalType":"uint256","name":"votes","type":"uint256"},{"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"GovernorInsufficientProposerVotes","type":"error"},{"inputs":[{"internalType":"uint256","name":"targets","type":"uint256"},{"internalType":"uint256","name":"calldatas","type":"uint256"},{"internalType":"uint256","name":"values","type":"uint256"}],"name":"GovernorInvalidProposalLength","type":"error"},{"inputs":[{"internalType":"uint256","name":"quorumNumerator","type":"uint256"},{"internalType":"uint256","name":"quorumDenominator","type":"uint256"}],"name":"GovernorInvalidQuorumFraction","type":"error"},{"inputs":[{"internalType":"address","name":"voter","type":"address"}],"name":"GovernorInvalidSignature","type":"error"},{"inputs":[],"name":"GovernorInvalidVoteParams","type":"error"},{"inputs":[],"name":"GovernorInvalidVoteType","type":"error"},{"inputs":[{"internalType":"uint256","name":"votingPeriod","type":"uint256"}],"name":"GovernorInvalidVotingPeriod","type":"error"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"GovernorNonexistentProposal","type":"error"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"GovernorNotQueuedProposal","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"GovernorOnlyExecutor","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"GovernorOnlyProposer","type":"error"},{"inputs":[],"name":"GovernorQueueNotImplemented","type":"error"},{"inputs":[{"internalType":"address","name":"proposer","type":"address"}],"name":"GovernorRestrictedProposer","type":"error"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"enum IGovernor.ProposalState","name":"current","type":"uint8"},{"internalType":"bytes32","name":"expectedStates","type":"bytes32"}],"name":"GovernorUnexpectedProposalState","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"currentNonce","type":"uint256"}],"name":"InvalidAccountNonce","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"address","name":"proposer","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"string[]","name":"signatures","type":"string[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"voteStart","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"voteEnd","type":"uint256"},{"indexed":false,"internalType":"string","name":"description","type":"string"}],"name":"ProposalCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"ProposalExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"etaSeconds","type":"uint256"}],"name":"ProposalQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldProposalThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newProposalThreshold","type":"uint256"}],"name":"ProposalThresholdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldQuorumNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newQuorumNumerator","type":"uint256"}],"name":"QuorumNumeratorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldTimelock","type":"address"},{"indexed":false,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"VoteCast","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"support","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"},{"indexed":false,"internalType":"bytes","name":"params","type":"bytes"}],"name":"VoteCastWithParams","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingDelay","type":"uint256"}],"name":"VotingDelaySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldVotingPeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVotingPeriod","type":"uint256"}],"name":"VotingPeriodSet","type":"event"},{"inputs":[],"name":"BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLOCK_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COUNTING_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"EXTENDED_BALLOT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"cancel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"}],"name":"castVote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"address","name":"voter","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"castVoteBySig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"castVoteWithReason","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"castVoteWithReasonAndParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"uint8","name":"support","type":"uint8"},{"internalType":"address","name":"voter","type":"address"},{"internalType":"string","name":"reason","type":"string"},{"internalType":"bytes","name":"params","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"castVoteWithReasonAndParamsBySig","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"clock","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"execute","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"getVotesWithParams","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"hasVoted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"hashProposal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalEta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalNeedsQueuing","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalProposer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalSnapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"proposalVotes","outputs":[{"internalType":"uint256","name":"againstVotes","type":"uint256"},{"internalType":"uint256","name":"forVotes","type":"uint256"},{"internalType":"uint256","name":"abstainVotes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"string","name":"description","type":"string"}],"name":"propose","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes[]","name":"calldatas","type":"bytes[]"},{"internalType":"bytes32","name":"descriptionHash","type":"bytes32"}],"name":"queue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"quorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"quorumNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorumNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"relay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newProposalThreshold","type":"uint256"}],"name":"setProposalThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"newVotingDelay","type":"uint48"}],"name":"setVotingDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"newVotingPeriod","type":"uint32"}],"name":"setVotingPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"}],"name":"state","outputs":[{"internalType":"enum IGovernor.ProposalState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC5805","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newQuorumNumerator","type":"uint256"}],"name":"updateQuorumNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract TimelockController","name":"newTimelock","type":"address"}],"name":"updateTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
61018060405234801561001157600080fd5b50604051614e0d380380614e0d8339810160408190526100309161074d565b838386838560006040518060400160405280600f81526020016e22b1b7a737bb30a3b7bb32b93737b960891b8152508061006e61017660201b60201c565b610079826000610191565b61012052610088816001610191565b61014052815160208084019190912060e052815190820120610100524660a05261011560e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c052600361012a828261085b565b506101369050836101c4565b61013f8261022a565b610148816102d0565b5050506001600160a01b03166101605261016181610311565b5061016b816103a7565b5050505050506109c7565b6040805180820190915260018152603160f81b602082015290565b60006020835110156101ad576101a683610410565b90506101be565b816101b8848261085b565b5060ff90505b92915050565b6008546040805165ffffffffffff928316815291831660208301527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a16008805465ffffffffffff191665ffffffffffff92909216919091179055565b8063ffffffff166000036102595760405163f1cfbf0560e01b8152600060048201526024015b60405180910390fd5b6008546040805163ffffffff66010000000000009093048316815291831660208301527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a16008805463ffffffff90921666010000000000000263ffffffff60301b19909216919091179055565b60075460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600755565b60648082111561033e5760405163243e544560e01b81526004810183905260248101829052604401610250565b600061034861044e565b9050610367610355610468565b61035e856104e3565b600a919061051b565b505060408051828152602081018590527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b4633997910160405180910390a1505050565b600b54604080516001600160a01b03928316815291831660208301527f08f74ea46ef7894f65eabfb5e6e695de773a000b47c529ab559178069b226401910160405180910390a1600b80546001600160a01b0319166001600160a01b0392909216919091179055565b600080829050601f8151111561043b578260405163305a27a960e01b81526004016102509190610919565b805161044682610967565b179392505050565b600061045a600a610536565b6001600160d01b0316905090565b60006104746101605190565b6001600160a01b03166391ddadf46040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156104cd575060408051601f3d908101601f191682019092526104ca9181019061098b565b60015b6104de576104d9610581565b905090565b919050565b60006001600160d01b03821115610517576040516306dfcc6560e41b815260d0600482015260248101839052604401610250565b5090565b60008061052985858561058c565b915091505b935093915050565b805460009080156105775761055e836105506001846109a6565b600091825260209091200190565b54660100000000000090046001600160d01b031661057a565b60005b9392505050565b60006104d9436106ec565b82546000908190801561068e5760006105aa876105506001856109a6565b805490915065ffffffffffff80821691660100000000000090046001600160d01b03169088168211156105f057604051632520601d60e01b815260040160405180910390fd5b8765ffffffffffff168265ffffffffffff160361062c57825465ffffffffffff1666010000000000006001600160d01b03891602178355610680565b6040805180820190915265ffffffffffff808a1682526001600160d01b03808a1660208085019182528d54600181018f5560008f815291909120945191519092166601000000000000029216919091179101555b945085935061052e92505050565b50506040805180820190915265ffffffffffff80851682526001600160d01b0380851660208085019182528854600181018a5560008a815291822095519251909316660100000000000002919093161792019190915590508161052e565b600065ffffffffffff821115610517576040516306dfcc6560e41b81526030600482015260248101839052604401610250565b6001600160a01b038116811461073457600080fd5b50565b805165ffffffffffff811681146104de57600080fd5b600080600080600060a0868803121561076557600080fd5b85516107708161071f565b60208701519095506107818161071f565b60408701516060880151919550935063ffffffff811681146107a257600080fd5b91506107b060808701610737565b90509295509295909350565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806107e657607f821691505b60208210810361080657634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561085657806000526020600020601f840160051c810160208510156108335750805b601f840160051c820191505b81811015610853576000815560010161083f565b50505b505050565b81516001600160401b03811115610874576108746107bc565b6108888161088284546107d2565b8461080c565b6020601f8211600181146108bc57600083156108a45750848201515b600019600385901b1c1916600184901b178455610853565b600084815260208120601f198516915b828110156108ec57878501518255602094850194600190920191016108cc565b508482101561090a5786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b602081526000825180602084015260005b81811015610947576020818601810151604086840101520161092a565b506000604082850101526040601f19601f83011684010191505092915050565b805160208083015191908110156108065760001960209190910360031b1b16919050565b60006020828403121561099d57600080fd5b61057a82610737565b818103818111156101be57634e487b7160e01b600052601160045260246000fd5b60805160a05160c05160e051610100516101205161014051610160516143c5610a48600039600081816109de01528181610e480152818161139f01528181611fa101526121fb01526000611f6c01526000611f3f0152600061283e01526000612816015260006127710152600061279b015260006127c501526143c56000f3fe6080604052600436106102975760003560e01c80637ecebe001161015a578063c01f9e37116100c1578063e540d01d1161007a578063e540d01d1461092f578063eb9019d41461094f578063ece40cc11461096f578063f23a6e611461098f578063f8ce560a146109af578063fc0c546a146109cf57600080fd5b8063c01f9e3714610844578063c28bc2fa14610864578063c59057e414610877578063d33219b414610897578063dd4e2ba5146108b5578063deaaa7cc146108fb57600080fd5b8063a7713a7011610113578063a7713a7014610782578063a890c91014610797578063a9a95294146107b7578063ab58fb8e146107d7578063b58131b01461080f578063bc197c811461082457600080fd5b80637ecebe00146106a457806384b0196e146106da5780638ff262e31461070257806391ddadf41461072257806397c3d3341461074e5780639a802a6d1461076257600080fd5b806343859632116101fe5780635b8d0e0d116101b75780635b8d0e0d146105e45780635f398a141461060457806360c4247f1461062457806379051887146106445780637b3c71d3146106645780637d5e81e21461068457600080fd5b806343859632146104c6578063452115d6146105105780634bf5d7e914610530578063544ffc9c1461054557806354fd4d501461059a57806356781388146105c457600080fd5b8063160cbed711610250578063160cbed7146103fd5780632656227d1461041d5780632d63f693146104305780632fe3e261146104505780633932abb1146104845780633e4f49e61461049957600080fd5b806301ffc9a7146102d357806302a251a31461030857806306f3f9e61461033457806306fdde0314610354578063143489d014610376578063150b7a02146103c457600080fd5b366102ce57306102a5610a02565b6001600160a01b0316146102cc57604051637485328f60e11b815260040160405180910390fd5b005b600080fd5b3480156102df57600080fd5b506102f36102ee3660046132f5565b610a1b565b60405190151581526020015b60405180910390f35b34801561031457600080fd5b50600854600160301b900463ffffffff165b6040519081526020016102ff565b34801561034057600080fd5b506102cc61034f36600461331f565b610a6d565b34801561036057600080fd5b50610369610a81565b6040516102ff9190613388565b34801561038257600080fd5b506103ac61039136600461331f565b6000908152600460205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016102ff565b3480156103d057600080fd5b506103e46103df36600461347b565b610b13565b6040516001600160e01b031990911681526020016102ff565b34801561040957600080fd5b50610326610418366004613650565b610b56565b61032661042b366004613650565b610c25565b34801561043c57600080fd5b5061032661044b36600461331f565b610d91565b34801561045c57600080fd5b506103267f3e83946653575f9a39005e1545185629e92736b7528ab20ca3816f315424a81181565b34801561049057600080fd5b50610326610db2565b3480156104a557600080fd5b506104b96104b436600461331f565b610dc5565b6040516102ff9190613721565b3480156104d257600080fd5b506102f36104e136600461372f565b60008281526009602090815260408083206001600160a01b038516845260030190915290205460ff1692915050565b34801561051c57600080fd5b5061032661052b366004613650565b610dd0565b34801561053c57600080fd5b50610369610e44565b34801561055157600080fd5b5061057f61056036600461331f565b6000908152600960205260409020805460018201546002909201549092565b604080519384526020840192909252908201526060016102ff565b3480156105a657600080fd5b506040805180820190915260018152603160f81b6020820152610369565b3480156105d057600080fd5b506103266105df366004613770565b610f06565b3480156105f057600080fd5b506103266105ff3660046137e4565b610f2f565b34801561061057600080fd5b5061032661061f3660046138a8565b61108e565b34801561063057600080fd5b5061032661063f36600461331f565b6110e3565b34801561065057600080fd5b506102cc61065f366004613943565b611171565b34801561067057600080fd5b5061032661067f366004613960565b611182565b34801561069057600080fd5b5061032661069f3660046139b9565b6111ca565b3480156106b057600080fd5b506103266106bf366004613a7d565b6001600160a01b031660009081526002602052604090205490565b3480156106e657600080fd5b506106ef611283565b6040516102ff9796959493929190613ad6565b34801561070e57600080fd5b5061032661071d366004613b46565b6112c9565b34801561072e57600080fd5b5061073761139b565b60405165ffffffffffff90911681526020016102ff565b34801561075a57600080fd5b506064610326565b34801561076e57600080fd5b5061032661077d366004613b97565b611423565b34801561078e57600080fd5b5061032661143a565b3480156107a357600080fd5b506102cc6107b2366004613a7d565b611454565b3480156107c357600080fd5b506102f36107d236600461331f565b611465565b3480156107e357600080fd5b506103266107f236600461331f565b60009081526004602052604090206001015465ffffffffffff1690565b34801561081b57600080fd5b5061032661146e565b34801561083057600080fd5b506103e461083f366004613bef565b611479565b34801561085057600080fd5b5061032661085f36600461331f565b6114bd565b6102cc610872366004613c8d565b611500565b34801561088357600080fd5b50610326610892366004613650565b611580565b3480156108a357600080fd5b50600b546001600160a01b03166103ac565b3480156108c157600080fd5b506040805180820190915260208082527f737570706f72743d627261766f2671756f72756d3d666f722c6162737461696e90820152610369565b34801561090757600080fd5b506103267ff2aad550cf55f045cb27e9c559f9889fdfb6e6cdaa032301d6ea397784ae51d781565b34801561093b57600080fd5b506102cc61094a366004613cd0565b6115ba565b34801561095b57600080fd5b5061032661096a366004613cf6565b6115cb565b34801561097b57600080fd5b506102cc61098a36600461331f565b6115ec565b34801561099b57600080fd5b506103e46109aa366004613d22565b6115fd565b3480156109bb57600080fd5b506103266109ca36600461331f565b611641565b3480156109db57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006103ac565b6000610a16600b546001600160a01b031690565b905090565b60006001600160e01b031982166332a2ad4360e11b1480610a4c57506001600160e01b03198216630271189760e51b145b80610a6757506301ffc9a760e01b6001600160e01b03198316145b92915050565b610a7561164c565b610a7e816116c6565b50565b606060038054610a9090613d7e565b80601f0160208091040260200160405190810160405280929190818152602001828054610abc90613d7e565b8015610b095780601f10610ade57610100808354040283529160200191610b09565b820191906000526020600020905b815481529060010190602001808311610aec57829003601f168201915b5050505050905090565b600030610b1e610a02565b6001600160a01b031614610b4557604051637485328f60e11b815260040160405180910390fd5b50630a85bd0160e11b949350505050565b600080610b6586868686611580565b9050610b7a81610b75600461175c565b61177f565b506000610b8a82888888886117be565b905065ffffffffffff811615610c0257600082815260046020908152604091829020600101805465ffffffffffff191665ffffffffffff85169081179091558251858152918201527f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892910160405180910390a1610c1b565b604051634844252360e11b815260040160405180910390fd5b5095945050505050565b600080610c3486868686611580565b9050610c5481610c44600561175c565b610c4e600461175c565b1761177f565b506000818152600460205260409020805460ff60f01b1916600160f01b17905530610c7d610a02565b6001600160a01b031614610d075760005b8651811015610d0557306001600160a01b0316878281518110610cb357610cb3613db8565b60200260200101516001600160a01b031603610cfd57610cfd858281518110610cde57610cde613db8565b60200260200101518051906020012060056117cd90919063ffffffff16565b600101610c8e565b505b610d14818787878761182f565b30610d1d610a02565b6001600160a01b031614158015610d4957506005546001600160801b03808216600160801b9092041614155b15610d545760006005555b6040518181527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f906020015b60405180910390a195945050505050565b600090815260046020526040902054600160a01b900465ffffffffffff1690565b6000610a1660085465ffffffffffff1690565b6000610a6782611843565b600080610ddf86868686611580565b9050610def81610b75600061175c565b506000818152600460205260409020546001600160a01b03163314610e2e5760405163233d98e360e01b81523360048201526024015b60405180910390fd5b610e3a86868686611982565b9695505050505050565b60607f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634bf5d7e96040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015610ec557506040513d6000823e601f3d908101601f19168201604052610ec29190810190613dce565b60015b610f01575060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b919050565b600080339050610f2784828560405180602001604052806000815250611999565b949350505050565b6000806110128761100c7f3e83946653575f9a39005e1545185629e92736b7528ab20ca3816f315424a8118c8c8c610f848e6001600160a01b0316600090815260026020526040902080546001810190915590565b8d8d604051610f94929190613e3b565b60405180910390208c80519060200120604051602001610ff19796959493929190968752602087019590955260ff9390931660408601526001600160a01b03919091166060850152608084015260a083015260c082015260e00190565b604051602081830303815290604052805190602001206119bc565b856119e9565b90508061103d576040516394ab6c0760e01b81526001600160a01b0388166004820152602401610e25565b61108189888a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b9250611a5d915050565b9998505050505050505050565b6000803390506110d887828888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250611a5d915050565b979650505050505050565b600a805460009182906110f7600184613e61565b8154811061110757611107613db8565b6000918252602090912001805490915065ffffffffffff811690600160301b90046001600160d01b031685821161114a576001600160d01b031695945050505050565b61115e61115687611b3f565b600a90611b76565b6001600160d01b03169695505050505050565b61117961164c565b610a7e81611c2b565b600080339050610e3a86828787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061199992505050565b6000336111d78184611c91565b6111ff5760405163d9b3955760e01b81526001600160a01b0382166004820152602401610e25565b600061120961146e565b9050801561127657600061123883600161122161139b565b61122b9190613e74565b65ffffffffffff166115cb565b90508181101561127457604051636121770b60e11b81526001600160a01b03841660048201526024810182905260448101839052606401610e25565b505b6110d88787878786611d18565b600060608060008060006060611297611f38565b61129f611f65565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b6000806113558461100c7ff2aad550cf55f045cb27e9c559f9889fdfb6e6cdaa032301d6ea397784ae51d789898961131e8b6001600160a01b0316600090815260026020526040902080546001810190915590565b60408051602081019690965285019390935260ff90911660608401526001600160a01b0316608083015260a082015260c001610ff1565b905080611380576040516394ab6c0760e01b81526001600160a01b0385166004820152602401610e25565b610e3a86858760405180602001604052806000815250611999565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166391ddadf46040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611417575060408051601f3d908101601f1916820190925261141491810190613e92565b60015b610f0157610a16611f92565b6000611430848484611f9d565b90505b9392505050565b6000611446600a612033565b6001600160d01b0316905090565b61145c61164c565b610a7e8161206c565b60006001610a67565b6000610a1660075490565b600030611484610a02565b6001600160a01b0316146114ab57604051637485328f60e11b815260040160405180910390fd5b5063bc197c8160e01b95945050505050565b6000818152600460205260408120546114f290600160d01b810463ffffffff1690600160a01b900465ffffffffffff16613eaf565b65ffffffffffff1692915050565b61150861164c565b600080856001600160a01b0316858585604051611526929190613e3b565b60006040518083038185875af1925050503d8060008114611563576040519150601f19603f3d011682016040523d82523d6000602084013e611568565b606091505b509150915061157782826120d5565b50505050505050565b6000848484846040516020016115999493929190613f64565b60408051601f19818403018152919052805160209091012095945050505050565b6115c261164c565b610a7e816120f1565b600061143383836115e760408051602081019091526000815290565b611f9d565b6115f461164c565b610a7e8161218f565b600030611608610a02565b6001600160a01b03161461162f57604051637485328f60e11b815260040160405180910390fd5b5063f23a6e6160e01b95945050505050565b6000610a67826121d0565b33611655610a02565b6001600160a01b03161461167e576040516347096e4760e01b8152336004820152602401610e25565b30611687610a02565b6001600160a01b0316146116c457600080366040516116a7929190613e3b565b604051809103902090505b806116bd600561227a565b036116b257505b565b6064808211156116f35760405163243e544560e01b81526004810183905260248101829052604401610e25565b60006116fd61143a565b905061171c61170a61139b565b611713856122e9565b600a919061231d565b505060408051828152602081018590527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b4633997910160405180910390a1505050565b6000816007811115611770576117706136e9565b600160ff919091161b92915050565b60008061178b84610dc5565b90506000836117998361175c565b1603611433578381846040516331b75e4d60e01b8152600401610e2593929190613faf565b6000610e3a8686868686612338565b81546001600160801b03600160801b8204811691811660018301909116036117f9576117f960416124e3565b6001600160801b03808216600090815260018086016020526040909120939093558354919092018216600160801b029116179055565b61183c85858585856124f5565b5050505050565b60008061184f8361258b565b90506005816007811115611865576118656136e9565b146118705792915050565b6000838152600c60205260409081902054600b549151632c258a9f60e11b81526004810182905290916001600160a01b03169063584b153e90602401602060405180830381865afa1580156118c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ed9190613fd1565b156118fc575060059392505050565b600b54604051632ab0f52960e01b8152600481018390526001600160a01b0390911690632ab0f52990602401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613fd1565b15611978575060079392505050565b5060029392505050565b6000611990858585856126c5565b95945050505050565b6000611990858585856119b760408051602081019091526000815290565b611a5d565b6000610a676119c9612764565b8360405161190160f01b8152600281019290925260228201526042902090565b6000836001600160a01b03163b600003611a4b57600080611a0a858561288f565b5090925090506000816003811115611a2457611a246136e9565b148015611a425750856001600160a01b0316826001600160a01b0316145b92505050611433565b611a568484846128dc565b9050611433565b6000611a6d86610b75600161175c565b506000611a8386611a7d89610d91565b85611f9d565b90506000611a9488888885886129b7565b90508351600003611aeb57866001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda489888489604051611ade9493929190613ff3565b60405180910390a26110d8565b866001600160a01b03167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb87128988848989604051611b2c95949392919061401b565b60405180910390a2979650505050505050565b600065ffffffffffff821115611b72576040516306dfcc6560e41b81526030600482015260248101839052604401610e25565b5090565b815460009081816005811115611bd5576000611b9184612aba565b611b9b9085613e61565b60008881526020902090915081015465ffffffffffff9081169087161015611bc557809150611bd3565b611bd0816001614055565b92505b505b6000611be387878585612c13565b90508015611c1e57611c0887611bfa600184613e61565b600091825260209091200190565b54600160301b90046001600160d01b03166110d8565b6000979650505050505050565b6008546040805165ffffffffffff928316815291831660208301527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a16008805465ffffffffffff191665ffffffffffff92909216919091179055565b80516000906034811015611ca9576001915050610a67565b60131981840101516001600160b01b03198116692370726f706f7365723d60b01b14611cda57600192505050610a67565b600080611ceb86602a860386612c75565b915091508115806110d85750866001600160a01b0316816001600160a01b03161494505050505092915050565b6000611d2d8686868680519060200120611580565b905084518651141580611d4257508351865114155b80611d4c57508551155b15611d8157855184518651604051630447b05d60e41b8152600481019390935260248301919091526044820152606401610e25565b600081815260046020526040902054600160a01b900465ffffffffffff1615611dcc5780611dae82610dc5565b6040516331b75e4d60e01b8152610e25929190600090600401613faf565b6000611dd6610db2565b611dde61139b565b65ffffffffffff16611df09190614055565b90506000611e0b60085463ffffffff600160301b9091041690565b600084815260046020526040902080546001600160a01b0319166001600160a01b038716178155909150611e3e83611b3f565b815465ffffffffffff91909116600160a01b0265ffffffffffff60a01b19909116178155611e6b82612d24565b815463ffffffff91909116600160d01b0263ffffffff60d01b1990911617815588517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e090859087908c908c906001600160401b03811115611ece57611ece6133b0565b604051908082528060200260200182016040528015611f0157816020015b6060815260200190600190039081611eec5790505b508c89611f0e8a82614055565b8e604051611f2499989796959493929190614068565b60405180910390a150505095945050505050565b6060610a167f00000000000000000000000000000000000000000000000000000000000000006000612d55565b6060610a167f00000000000000000000000000000000000000000000000000000000000000006001612d55565b6000610a1643611b3f565b60007f0000000000000000000000000000000000000000000000000000000000000000604051630748d63560e31b81526001600160a01b038681166004830152602482018690529190911690633a46b1a890604401602060405180830381865afa15801561200f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114309190614145565b805460009080156120635761204d83611bfa600184613e61565b54600160301b90046001600160d01b0316611433565b60009392505050565b600b54604080516001600160a01b03928316815291831660208301527f08f74ea46ef7894f65eabfb5e6e695de773a000b47c529ab559178069b226401910160405180910390a1600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6060826120ea576120e582612e00565b610a67565b5080610a67565b8063ffffffff1660000361211b5760405163f1cfbf0560e01b815260006004820152602401610e25565b6008546040805163ffffffff600160301b9093048316815291831660208301527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a16008805463ffffffff909216600160301b0269ffffffff00000000000019909216919091179055565b60075460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600755565b600060646121dd836110e3565b604051632394e7a360e21b8152600481018590526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638e539e8c90602401602060405180830381865afa158015612242573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122669190614145565b612270919061415e565b610a67919061418b565b80546000906001600160801b0380821691600160801b90041681036122a3576122a360316124e3565b6001600160801b038181166000908152600185810160205260408220805492905585546fffffffffffffffffffffffffffffffff19169301909116919091179092555090565b60006001600160d01b03821115611b72576040516306dfcc6560e41b815260d0600482015260248101839052604401610e25565b60008061232b858585612e29565b915091505b935093915050565b600080600b60009054906101000a90046001600160a01b03166001600160a01b031663f27a0c926040518163ffffffff1660e01b8152600401602060405180830381865afa15801561238e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b29190614145565b905060003060601b6bffffffffffffffffffffffff19168418600b5460405163b1c5f42760e01b81529192506001600160a01b03169063b1c5f42790612405908a908a908a9060009088906004016141ad565b602060405180830381865afa158015612422573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124469190614145565b6000898152600c602052604080822092909255600b5491516308f2a0bb60e41b81526001600160a01b0390921691638f2a0bb091612491918b918b918b919088908a906004016141fb565b600060405180830381600087803b1580156124ab57600080fd5b505af11580156124bf573d6000803e3d6000fd5b505050506124d782426124d29190614055565b611b3f565b98975050505050505050565b634e487b71600052806020526024601cfd5b600b546001600160a01b031663e38335e53486868660003060601b6bffffffffffffffffffffffff191688186040518763ffffffff1660e01b81526004016125419594939291906141ad565b6000604051808303818588803b15801561255a57600080fd5b505af115801561256e573d6000803e3d6000fd5b50505060009687525050600c602052505060408320929092555050565b6000818152600460205260408120805460ff600160f01b8204811691600160f81b90041681156125c057506007949350505050565b80156125d157506002949350505050565b60006125dc86610d91565b90508060000361260257604051636ad0607560e01b815260048101879052602401610e25565b600061260c61139b565b65ffffffffffff16905080821061262a575060009695505050505050565b6000612635886114bd565b905081811061264c57506001979650505050505050565b61265588612f7d565b158061267557506000888152600960205260409020805460019091015411155b1561268857506003979650505050505050565b60008881526004602052604090206001015465ffffffffffff166000036126b757506004979650505050505050565b506005979650505050505050565b6000806126d486868686612fb4565b6000818152600c60205260409020549091508015610c1b57600b5460405163c4d252f560e01b8152600481018390526001600160a01b039091169063c4d252f590602401600060405180830381600087803b15801561273257600080fd5b505af1158015612746573d6000803e3d6000fd5b5050506000838152600c602052604081205550509050949350505050565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156127bd57507f000000000000000000000000000000000000000000000000000000000000000046145b156127e757507f000000000000000000000000000000000000000000000000000000000000000090565b610a16604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080600083516041036128c95760208401516040850151606086015160001a6128bb88828585613065565b9550955095505050506128d5565b50508151600091506002905b9250925092565b6000806000856001600160a01b031685856040516024016128fe929190614253565b60408051601f198184030181529181526020820180516001600160e01b0316630b135d3f60e11b17905251612933919061426c565b600060405180830381855afa9150503d806000811461296e576040519150601f19603f3d011682016040523d82523d6000602084013e612973565b606091505b509150915081801561298757506020815110155b8015610e3a57508051630b135d3f60e11b906129ac9083016020908101908401614145565b149695505050505050565b60008581526009602090815260408083206001600160a01b03881684526003810190925282205460ff1615612a0a576040516371c6af4960e01b81526001600160a01b0387166004820152602401610e25565b6001600160a01b03861660009081526003820160205260409020805460ff1916600117905560ff8516612a565783816000016000828254612a4b9190614055565b90915550612aaf9050565b60001960ff861601612a765783816001016000828254612a4b9190614055565b60011960ff861601612a965783816002016000828254612a4b9190614055565b6040516303599be160e11b815260040160405180910390fd5b509195945050505050565b600060018211612ac8575090565b816001600160801b8210612ae15760809190911c9060401b5b680100000000000000008210612afc5760409190911c9060201b5b6401000000008210612b135760209190911c9060101b5b620100008210612b285760109190911c9060081b5b6101008210612b3c5760089190911c9060041b5b60108210612b4f5760049190911c9060021b5b60048210612b5b5760011b5b600302600190811c90818581612b7357612b73614175565b048201901c90506001818581612b8b57612b8b614175565b048201901c90506001818581612ba357612ba3614175565b048201901c90506001818581612bbb57612bbb614175565b048201901c90506001818581612bd357612bd3614175565b048201901c90506001818581612beb57612beb614175565b048201901c9050612c0a818581612c0457612c04614175565b04821190565b90039392505050565b60005b81831015612c6d576000612c2a8484613134565b60008781526020902090915065ffffffffffff86169082015465ffffffffffff161115612c5957809250612c67565b612c64816001614055565b93505b50612c16565b509392505050565b6000808451831180612c8657508284115b15612c9657506000905080612330565b6000612ca3856001614055565b84118015612ccb575061060f60f31b612cbf8787016020015190565b6001600160f01b031916145b90506000612cdc821515600261415e565b612ce7906028614055565b905080612cf48787613e61565b03612d1657600080612d0789898961314f565b90965094506123309350505050565b600080935093505050612330565b600063ffffffff821115611b72576040516306dfcc6560e41b81526020600482015260248101839052604401610e25565b606060ff8314612d6f57612d6883613215565b9050610a67565b818054612d7b90613d7e565b80601f0160208091040260200160405190810160405280929190818152602001828054612da790613d7e565b8015612df45780601f10612dc957610100808354040283529160200191612df4565b820191906000526020600020905b815481529060010190602001808311612dd757829003601f168201915b50505050509050610a67565b805115612e105780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b825460009081908015612f22576000612e4787611bfa600185613e61565b805490915065ffffffffffff80821691600160301b90046001600160d01b0316908816821115612e8a57604051632520601d60e01b815260040160405180910390fd5b8765ffffffffffff168265ffffffffffff1603612ec357825465ffffffffffff16600160301b6001600160d01b03891602178355612f14565b6040805180820190915265ffffffffffff808a1682526001600160d01b03808a1660208085019182528d54600181018f5560008f81529190912094519151909216600160301b029216919091179101555b945085935061233092505050565b50506040805180820190915265ffffffffffff80851682526001600160d01b0380851660208085019182528854600181018a5560008a815291822095519251909316600160301b029190931617920191909155905081612330565b600081815260096020526040812060028101546001820154612f9f9190614055565b612fab6109ca85610d91565b11159392505050565b600080612fc386868686611580565b905061301181612fd3600761175c565b612fdd600661175c565b612fe7600261175c565b6001612ff4600782614288565b612fff906002614380565b6130099190613e61565b18181861177f565b506000818152600460205260409081902080546001600160f81b0316600160f81b179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90610d809083815260200190565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156130a0575060009150600390508261312a565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa1580156130f4573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166131205750600092506001915082905061312a565b9250600091508190505b9450945094915050565b6000613143600284841861418b565b61143390848416614055565b600080848161315f866001614055565b85118015613187575061060f60f31b61317b8388016020015190565b6001600160f01b031916145b90506000613198821515600261415e565b90506000806131a7838a614055565b90505b878110156132045760006131c96131c48784016020015190565b613254565b9050600f8160ff1611156131e95760008097509750505050505050612330565b6131f460108461415e565b60ff9091160191506001016131aa565b506001999098509650505050505050565b60606000613222836132cd565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060f882901c602f8111801561326e5750603a8160ff16105b1561327c57602f1901610a67565b60608160ff16118015613292575060678160ff16105b156132a05760561901610a67565b60408160ff161180156132b6575060478160ff16105b156132c45760361901610a67565b5060ff92915050565b600060ff8216601f811115610a6757604051632cd44ac360e21b815260040160405180910390fd5b60006020828403121561330757600080fd5b81356001600160e01b03198116811461143357600080fd5b60006020828403121561333157600080fd5b5035919050565b60005b8381101561335357818101518382015260200161333b565b50506000910152565b60008151808452613374816020860160208601613338565b601f01601f19169290920160200192915050565b602081526000611433602083018461335c565b6001600160a01b0381168114610a7e57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156133ee576133ee6133b0565b604052919050565b60006001600160401b0382111561340f5761340f6133b0565b50601f01601f191660200190565b600061343061342b846133f6565b6133c6565b905082815283838301111561344457600080fd5b828260208301376000602084830101529392505050565b600082601f83011261346c57600080fd5b6114338383356020850161341d565b6000806000806080858703121561349157600080fd5b843561349c8161339b565b935060208501356134ac8161339b565b92506040850135915060608501356001600160401b038111156134ce57600080fd5b6134da8782880161345b565b91505092959194509250565b60006001600160401b038211156134ff576134ff6133b0565b5060051b60200190565b600082601f83011261351a57600080fd5b813561352861342b826134e6565b8082825260208201915060208360051b86010192508583111561354a57600080fd5b602085015b83811015610c1b5780356135628161339b565b83526020928301920161354f565b600082601f83011261358157600080fd5b813561358f61342b826134e6565b8082825260208201915060208360051b8601019250858311156135b157600080fd5b602085015b83811015610c1b5780358352602092830192016135b6565b600082601f8301126135df57600080fd5b81356135ed61342b826134e6565b8082825260208201915060208360051b86010192508583111561360f57600080fd5b602085015b83811015610c1b5780356001600160401b0381111561363257600080fd5b613641886020838a010161345b565b84525060209283019201613614565b6000806000806080858703121561366657600080fd5b84356001600160401b0381111561367c57600080fd5b61368887828801613509565b94505060208501356001600160401b038111156136a457600080fd5b6136b087828801613570565b93505060408501356001600160401b038111156136cc57600080fd5b6136d8878288016135ce565b949793965093946060013593505050565b634e487b7160e01b600052602160045260246000fd5b6008811061371d57634e487b7160e01b600052602160045260246000fd5b9052565b60208101610a6782846136ff565b6000806040838503121561374257600080fd5b8235915060208301356137548161339b565b809150509250929050565b803560ff81168114610f0157600080fd5b6000806040838503121561378357600080fd5b823591506137936020840161375f565b90509250929050565b60008083601f8401126137ae57600080fd5b5081356001600160401b038111156137c557600080fd5b6020830191508360208285010111156137dd57600080fd5b9250929050565b600080600080600080600060c0888a0312156137ff57600080fd5b8735965061380f6020890161375f565b9550604088013561381f8161339b565b945060608801356001600160401b0381111561383a57600080fd5b6138468a828b0161379c565b90955093505060808801356001600160401b0381111561386557600080fd5b6138718a828b0161345b565b92505060a08801356001600160401b0381111561388d57600080fd5b6138998a828b0161345b565b91505092959891949750929550565b6000806000806000608086880312156138c057600080fd5b853594506138d06020870161375f565b935060408601356001600160401b038111156138eb57600080fd5b6138f78882890161379c565b90945092505060608601356001600160401b0381111561391657600080fd5b6139228882890161345b565b9150509295509295909350565b65ffffffffffff81168114610a7e57600080fd5b60006020828403121561395557600080fd5b81356114338161392f565b6000806000806060858703121561397657600080fd5b843593506139866020860161375f565b925060408501356001600160401b038111156139a157600080fd5b6139ad8782880161379c565b95989497509550505050565b600080600080608085870312156139cf57600080fd5b84356001600160401b038111156139e557600080fd5b6139f187828801613509565b94505060208501356001600160401b03811115613a0d57600080fd5b613a1987828801613570565b93505060408501356001600160401b03811115613a3557600080fd5b613a41878288016135ce565b92505060608501356001600160401b03811115613a5d57600080fd5b8501601f81018713613a6e57600080fd5b6134da8782356020840161341d565b600060208284031215613a8f57600080fd5b81356114338161339b565b600081518084526020840193506020830160005b82811015613acc578151865260209586019590910190600101613aae565b5093949350505050565b60ff60f81b8816815260e060208201526000613af560e083018961335c565b8281036040840152613b07818961335c565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050613b388185613a9a565b9a9950505050505050505050565b60008060008060808587031215613b5c57600080fd5b84359350613b6c6020860161375f565b92506040850135613b7c8161339b565b915060608501356001600160401b038111156134ce57600080fd5b600080600060608486031215613bac57600080fd5b8335613bb78161339b565b92506020840135915060408401356001600160401b03811115613bd957600080fd5b613be58682870161345b565b9150509250925092565b600080600080600060a08688031215613c0757600080fd5b8535613c128161339b565b94506020860135613c228161339b565b935060408601356001600160401b03811115613c3d57600080fd5b613c4988828901613570565b93505060608601356001600160401b03811115613c6557600080fd5b613c7188828901613570565b92505060808601356001600160401b0381111561391657600080fd5b60008060008060608587031215613ca357600080fd5b8435613cae8161339b565b93506020850135925060408501356001600160401b038111156139a157600080fd5b600060208284031215613ce257600080fd5b813563ffffffff8116811461143357600080fd5b60008060408385031215613d0957600080fd5b8235613d148161339b565b946020939093013593505050565b600080600080600060a08688031215613d3a57600080fd5b8535613d458161339b565b94506020860135613d558161339b565b9350604086013592506060860135915060808601356001600160401b0381111561391657600080fd5b600181811c90821680613d9257607f821691505b602082108103613db257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215613de057600080fd5b81516001600160401b03811115613df657600080fd5b8201601f81018413613e0757600080fd5b8051613e1561342b826133f6565b818152856020838501011115613e2a57600080fd5b611990826020830160208601613338565b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610a6757610a67613e4b565b65ffffffffffff8281168282160390811115610a6757610a67613e4b565b600060208284031215613ea457600080fd5b81516114338161392f565b65ffffffffffff8181168382160190811115610a6757610a67613e4b565b600081518084526020840193506020830160005b82811015613acc5781516001600160a01b0316865260209586019590910190600101613ee1565b600082825180855260208501945060208160051b8301016020850160005b83811015613f5857601f19858403018852613f4283835161335c565b6020988901989093509190910190600101613f26565b50909695505050505050565b608081526000613f776080830187613ecd565b8281036020840152613f898187613a9a565b90508281036040840152613f9d8186613f08565b91505082606083015295945050505050565b83815260608101613fc360208301856136ff565b826040830152949350505050565b600060208284031215613fe357600080fd5b8151801515811461143357600080fd5b84815260ff84166020820152826040820152608060608201526000610e3a608083018461335c565b85815260ff8516602082015283604082015260a06060820152600061404360a083018561335c565b82810360808401526124d7818561335c565b80820180821115610a6757610a67613e4b565b8981526001600160a01b0389166020820152610120604082018190526000906140939083018a613ecd565b82810360608401526140a5818a613a9a565b9050828103608084015280885180835260208301915060208160051b84010160208b0160005b838110156140fd57601f198684030185526140e783835161335c565b60209586019590935091909101906001016140cb565b505085810360a0870152614111818b613f08565b93505050508560c08401528460e0840152828103610100840152614135818561335c565b9c9b505050505050505050505050565b60006020828403121561415757600080fd5b5051919050565b8082028115828204841417610a6757610a67613e4b565b634e487b7160e01b600052601260045260246000fd5b6000826141a857634e487b7160e01b600052601260045260246000fd5b500490565b60a0815260006141c060a0830188613ecd565b82810360208401526141d28188613a9a565b905082810360408401526141e68187613f08565b60608401959095525050608001529392505050565b60c08152600061420e60c0830189613ecd565b82810360208401526142208189613a9a565b905082810360408401526142348188613f08565b60608401969096525050608081019290925260a0909101529392505050565b828152604060208201526000611430604083018461335c565b6000825161427e818460208701613338565b9190910192915050565b60ff8181168382160190811115610a6757610a67613e4b565b6001815b6001841115612330578085048111156142c0576142c0613e4b565b60018416156142ce57908102905b60019390931c9280026142a5565b6000826142eb57506001610a67565b816142f857506000610a67565b816001811461430e576002811461431857614334565b6001915050610a67565b60ff84111561432957614329613e4b565b50506001821b610a67565b5060208310610133831016604e8410600b8410161715614357575081810a610a67565b61436460001984846142a1565b806000190482111561437857614378613e4b565b029392505050565b600061143360ff8416836142dc56fea264697066735822122000e93c9422d321f285245dc855588850e932fb7702cc4ee4c114c04b114efe6464736f6c634300081c0033000000000000000000000000da5450a161fa5f940d48ce84349049a903333858000000000000000000000000447b8216eb90fd93ea0ce67cb60982c890cadd13000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x6080604052600436106102975760003560e01c80637ecebe001161015a578063c01f9e37116100c1578063e540d01d1161007a578063e540d01d1461092f578063eb9019d41461094f578063ece40cc11461096f578063f23a6e611461098f578063f8ce560a146109af578063fc0c546a146109cf57600080fd5b8063c01f9e3714610844578063c28bc2fa14610864578063c59057e414610877578063d33219b414610897578063dd4e2ba5146108b5578063deaaa7cc146108fb57600080fd5b8063a7713a7011610113578063a7713a7014610782578063a890c91014610797578063a9a95294146107b7578063ab58fb8e146107d7578063b58131b01461080f578063bc197c811461082457600080fd5b80637ecebe00146106a457806384b0196e146106da5780638ff262e31461070257806391ddadf41461072257806397c3d3341461074e5780639a802a6d1461076257600080fd5b806343859632116101fe5780635b8d0e0d116101b75780635b8d0e0d146105e45780635f398a141461060457806360c4247f1461062457806379051887146106445780637b3c71d3146106645780637d5e81e21461068457600080fd5b806343859632146104c6578063452115d6146105105780634bf5d7e914610530578063544ffc9c1461054557806354fd4d501461059a57806356781388146105c457600080fd5b8063160cbed711610250578063160cbed7146103fd5780632656227d1461041d5780632d63f693146104305780632fe3e261146104505780633932abb1146104845780633e4f49e61461049957600080fd5b806301ffc9a7146102d357806302a251a31461030857806306f3f9e61461033457806306fdde0314610354578063143489d014610376578063150b7a02146103c457600080fd5b366102ce57306102a5610a02565b6001600160a01b0316146102cc57604051637485328f60e11b815260040160405180910390fd5b005b600080fd5b3480156102df57600080fd5b506102f36102ee3660046132f5565b610a1b565b60405190151581526020015b60405180910390f35b34801561031457600080fd5b50600854600160301b900463ffffffff165b6040519081526020016102ff565b34801561034057600080fd5b506102cc61034f36600461331f565b610a6d565b34801561036057600080fd5b50610369610a81565b6040516102ff9190613388565b34801561038257600080fd5b506103ac61039136600461331f565b6000908152600460205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016102ff565b3480156103d057600080fd5b506103e46103df36600461347b565b610b13565b6040516001600160e01b031990911681526020016102ff565b34801561040957600080fd5b50610326610418366004613650565b610b56565b61032661042b366004613650565b610c25565b34801561043c57600080fd5b5061032661044b36600461331f565b610d91565b34801561045c57600080fd5b506103267f3e83946653575f9a39005e1545185629e92736b7528ab20ca3816f315424a81181565b34801561049057600080fd5b50610326610db2565b3480156104a557600080fd5b506104b96104b436600461331f565b610dc5565b6040516102ff9190613721565b3480156104d257600080fd5b506102f36104e136600461372f565b60008281526009602090815260408083206001600160a01b038516845260030190915290205460ff1692915050565b34801561051c57600080fd5b5061032661052b366004613650565b610dd0565b34801561053c57600080fd5b50610369610e44565b34801561055157600080fd5b5061057f61056036600461331f565b6000908152600960205260409020805460018201546002909201549092565b604080519384526020840192909252908201526060016102ff565b3480156105a657600080fd5b506040805180820190915260018152603160f81b6020820152610369565b3480156105d057600080fd5b506103266105df366004613770565b610f06565b3480156105f057600080fd5b506103266105ff3660046137e4565b610f2f565b34801561061057600080fd5b5061032661061f3660046138a8565b61108e565b34801561063057600080fd5b5061032661063f36600461331f565b6110e3565b34801561065057600080fd5b506102cc61065f366004613943565b611171565b34801561067057600080fd5b5061032661067f366004613960565b611182565b34801561069057600080fd5b5061032661069f3660046139b9565b6111ca565b3480156106b057600080fd5b506103266106bf366004613a7d565b6001600160a01b031660009081526002602052604090205490565b3480156106e657600080fd5b506106ef611283565b6040516102ff9796959493929190613ad6565b34801561070e57600080fd5b5061032661071d366004613b46565b6112c9565b34801561072e57600080fd5b5061073761139b565b60405165ffffffffffff90911681526020016102ff565b34801561075a57600080fd5b506064610326565b34801561076e57600080fd5b5061032661077d366004613b97565b611423565b34801561078e57600080fd5b5061032661143a565b3480156107a357600080fd5b506102cc6107b2366004613a7d565b611454565b3480156107c357600080fd5b506102f36107d236600461331f565b611465565b3480156107e357600080fd5b506103266107f236600461331f565b60009081526004602052604090206001015465ffffffffffff1690565b34801561081b57600080fd5b5061032661146e565b34801561083057600080fd5b506103e461083f366004613bef565b611479565b34801561085057600080fd5b5061032661085f36600461331f565b6114bd565b6102cc610872366004613c8d565b611500565b34801561088357600080fd5b50610326610892366004613650565b611580565b3480156108a357600080fd5b50600b546001600160a01b03166103ac565b3480156108c157600080fd5b506040805180820190915260208082527f737570706f72743d627261766f2671756f72756d3d666f722c6162737461696e90820152610369565b34801561090757600080fd5b506103267ff2aad550cf55f045cb27e9c559f9889fdfb6e6cdaa032301d6ea397784ae51d781565b34801561093b57600080fd5b506102cc61094a366004613cd0565b6115ba565b34801561095b57600080fd5b5061032661096a366004613cf6565b6115cb565b34801561097b57600080fd5b506102cc61098a36600461331f565b6115ec565b34801561099b57600080fd5b506103e46109aa366004613d22565b6115fd565b3480156109bb57600080fd5b506103266109ca36600461331f565b611641565b3480156109db57600080fd5b507f000000000000000000000000da5450a161fa5f940d48ce84349049a9033338586103ac565b6000610a16600b546001600160a01b031690565b905090565b60006001600160e01b031982166332a2ad4360e11b1480610a4c57506001600160e01b03198216630271189760e51b145b80610a6757506301ffc9a760e01b6001600160e01b03198316145b92915050565b610a7561164c565b610a7e816116c6565b50565b606060038054610a9090613d7e565b80601f0160208091040260200160405190810160405280929190818152602001828054610abc90613d7e565b8015610b095780601f10610ade57610100808354040283529160200191610b09565b820191906000526020600020905b815481529060010190602001808311610aec57829003601f168201915b5050505050905090565b600030610b1e610a02565b6001600160a01b031614610b4557604051637485328f60e11b815260040160405180910390fd5b50630a85bd0160e11b949350505050565b600080610b6586868686611580565b9050610b7a81610b75600461175c565b61177f565b506000610b8a82888888886117be565b905065ffffffffffff811615610c0257600082815260046020908152604091829020600101805465ffffffffffff191665ffffffffffff85169081179091558251858152918201527f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892910160405180910390a1610c1b565b604051634844252360e11b815260040160405180910390fd5b5095945050505050565b600080610c3486868686611580565b9050610c5481610c44600561175c565b610c4e600461175c565b1761177f565b506000818152600460205260409020805460ff60f01b1916600160f01b17905530610c7d610a02565b6001600160a01b031614610d075760005b8651811015610d0557306001600160a01b0316878281518110610cb357610cb3613db8565b60200260200101516001600160a01b031603610cfd57610cfd858281518110610cde57610cde613db8565b60200260200101518051906020012060056117cd90919063ffffffff16565b600101610c8e565b505b610d14818787878761182f565b30610d1d610a02565b6001600160a01b031614158015610d4957506005546001600160801b03808216600160801b9092041614155b15610d545760006005555b6040518181527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f906020015b60405180910390a195945050505050565b600090815260046020526040902054600160a01b900465ffffffffffff1690565b6000610a1660085465ffffffffffff1690565b6000610a6782611843565b600080610ddf86868686611580565b9050610def81610b75600061175c565b506000818152600460205260409020546001600160a01b03163314610e2e5760405163233d98e360e01b81523360048201526024015b60405180910390fd5b610e3a86868686611982565b9695505050505050565b60607f000000000000000000000000da5450a161fa5f940d48ce84349049a9033338586001600160a01b0316634bf5d7e96040518163ffffffff1660e01b8152600401600060405180830381865afa925050508015610ec557506040513d6000823e601f3d908101601f19168201604052610ec29190810190613dce565b60015b610f01575060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b919050565b600080339050610f2784828560405180602001604052806000815250611999565b949350505050565b6000806110128761100c7f3e83946653575f9a39005e1545185629e92736b7528ab20ca3816f315424a8118c8c8c610f848e6001600160a01b0316600090815260026020526040902080546001810190915590565b8d8d604051610f94929190613e3b565b60405180910390208c80519060200120604051602001610ff19796959493929190968752602087019590955260ff9390931660408601526001600160a01b03919091166060850152608084015260a083015260c082015260e00190565b604051602081830303815290604052805190602001206119bc565b856119e9565b90508061103d576040516394ab6c0760e01b81526001600160a01b0388166004820152602401610e25565b61108189888a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b9250611a5d915050565b9998505050505050505050565b6000803390506110d887828888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250611a5d915050565b979650505050505050565b600a805460009182906110f7600184613e61565b8154811061110757611107613db8565b6000918252602090912001805490915065ffffffffffff811690600160301b90046001600160d01b031685821161114a576001600160d01b031695945050505050565b61115e61115687611b3f565b600a90611b76565b6001600160d01b03169695505050505050565b61117961164c565b610a7e81611c2b565b600080339050610e3a86828787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061199992505050565b6000336111d78184611c91565b6111ff5760405163d9b3955760e01b81526001600160a01b0382166004820152602401610e25565b600061120961146e565b9050801561127657600061123883600161122161139b565b61122b9190613e74565b65ffffffffffff166115cb565b90508181101561127457604051636121770b60e11b81526001600160a01b03841660048201526024810182905260448101839052606401610e25565b505b6110d88787878786611d18565b600060608060008060006060611297611f38565b61129f611f65565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b6000806113558461100c7ff2aad550cf55f045cb27e9c559f9889fdfb6e6cdaa032301d6ea397784ae51d789898961131e8b6001600160a01b0316600090815260026020526040902080546001810190915590565b60408051602081019690965285019390935260ff90911660608401526001600160a01b0316608083015260a082015260c001610ff1565b905080611380576040516394ab6c0760e01b81526001600160a01b0385166004820152602401610e25565b610e3a86858760405180602001604052806000815250611999565b60007f000000000000000000000000da5450a161fa5f940d48ce84349049a9033338586001600160a01b03166391ddadf46040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611417575060408051601f3d908101601f1916820190925261141491810190613e92565b60015b610f0157610a16611f92565b6000611430848484611f9d565b90505b9392505050565b6000611446600a612033565b6001600160d01b0316905090565b61145c61164c565b610a7e8161206c565b60006001610a67565b6000610a1660075490565b600030611484610a02565b6001600160a01b0316146114ab57604051637485328f60e11b815260040160405180910390fd5b5063bc197c8160e01b95945050505050565b6000818152600460205260408120546114f290600160d01b810463ffffffff1690600160a01b900465ffffffffffff16613eaf565b65ffffffffffff1692915050565b61150861164c565b600080856001600160a01b0316858585604051611526929190613e3b565b60006040518083038185875af1925050503d8060008114611563576040519150601f19603f3d011682016040523d82523d6000602084013e611568565b606091505b509150915061157782826120d5565b50505050505050565b6000848484846040516020016115999493929190613f64565b60408051601f19818403018152919052805160209091012095945050505050565b6115c261164c565b610a7e816120f1565b600061143383836115e760408051602081019091526000815290565b611f9d565b6115f461164c565b610a7e8161218f565b600030611608610a02565b6001600160a01b03161461162f57604051637485328f60e11b815260040160405180910390fd5b5063f23a6e6160e01b95945050505050565b6000610a67826121d0565b33611655610a02565b6001600160a01b03161461167e576040516347096e4760e01b8152336004820152602401610e25565b30611687610a02565b6001600160a01b0316146116c457600080366040516116a7929190613e3b565b604051809103902090505b806116bd600561227a565b036116b257505b565b6064808211156116f35760405163243e544560e01b81526004810183905260248101829052604401610e25565b60006116fd61143a565b905061171c61170a61139b565b611713856122e9565b600a919061231d565b505060408051828152602081018590527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b4633997910160405180910390a1505050565b6000816007811115611770576117706136e9565b600160ff919091161b92915050565b60008061178b84610dc5565b90506000836117998361175c565b1603611433578381846040516331b75e4d60e01b8152600401610e2593929190613faf565b6000610e3a8686868686612338565b81546001600160801b03600160801b8204811691811660018301909116036117f9576117f960416124e3565b6001600160801b03808216600090815260018086016020526040909120939093558354919092018216600160801b029116179055565b61183c85858585856124f5565b5050505050565b60008061184f8361258b565b90506005816007811115611865576118656136e9565b146118705792915050565b6000838152600c60205260409081902054600b549151632c258a9f60e11b81526004810182905290916001600160a01b03169063584b153e90602401602060405180830381865afa1580156118c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118ed9190613fd1565b156118fc575060059392505050565b600b54604051632ab0f52960e01b8152600481018390526001600160a01b0390911690632ab0f52990602401602060405180830381865afa158015611945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119699190613fd1565b15611978575060079392505050565b5060029392505050565b6000611990858585856126c5565b95945050505050565b6000611990858585856119b760408051602081019091526000815290565b611a5d565b6000610a676119c9612764565b8360405161190160f01b8152600281019290925260228201526042902090565b6000836001600160a01b03163b600003611a4b57600080611a0a858561288f565b5090925090506000816003811115611a2457611a246136e9565b148015611a425750856001600160a01b0316826001600160a01b0316145b92505050611433565b611a568484846128dc565b9050611433565b6000611a6d86610b75600161175c565b506000611a8386611a7d89610d91565b85611f9d565b90506000611a9488888885886129b7565b90508351600003611aeb57866001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda489888489604051611ade9493929190613ff3565b60405180910390a26110d8565b866001600160a01b03167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb87128988848989604051611b2c95949392919061401b565b60405180910390a2979650505050505050565b600065ffffffffffff821115611b72576040516306dfcc6560e41b81526030600482015260248101839052604401610e25565b5090565b815460009081816005811115611bd5576000611b9184612aba565b611b9b9085613e61565b60008881526020902090915081015465ffffffffffff9081169087161015611bc557809150611bd3565b611bd0816001614055565b92505b505b6000611be387878585612c13565b90508015611c1e57611c0887611bfa600184613e61565b600091825260209091200190565b54600160301b90046001600160d01b03166110d8565b6000979650505050505050565b6008546040805165ffffffffffff928316815291831660208301527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a16008805465ffffffffffff191665ffffffffffff92909216919091179055565b80516000906034811015611ca9576001915050610a67565b60131981840101516001600160b01b03198116692370726f706f7365723d60b01b14611cda57600192505050610a67565b600080611ceb86602a860386612c75565b915091508115806110d85750866001600160a01b0316816001600160a01b03161494505050505092915050565b6000611d2d8686868680519060200120611580565b905084518651141580611d4257508351865114155b80611d4c57508551155b15611d8157855184518651604051630447b05d60e41b8152600481019390935260248301919091526044820152606401610e25565b600081815260046020526040902054600160a01b900465ffffffffffff1615611dcc5780611dae82610dc5565b6040516331b75e4d60e01b8152610e25929190600090600401613faf565b6000611dd6610db2565b611dde61139b565b65ffffffffffff16611df09190614055565b90506000611e0b60085463ffffffff600160301b9091041690565b600084815260046020526040902080546001600160a01b0319166001600160a01b038716178155909150611e3e83611b3f565b815465ffffffffffff91909116600160a01b0265ffffffffffff60a01b19909116178155611e6b82612d24565b815463ffffffff91909116600160d01b0263ffffffff60d01b1990911617815588517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e090859087908c908c906001600160401b03811115611ece57611ece6133b0565b604051908082528060200260200182016040528015611f0157816020015b6060815260200190600190039081611eec5790505b508c89611f0e8a82614055565b8e604051611f2499989796959493929190614068565b60405180910390a150505095945050505050565b6060610a167f45636f4e6f7661476f7665726e6f72000000000000000000000000000000000f6000612d55565b6060610a167f31000000000000000000000000000000000000000000000000000000000000016001612d55565b6000610a1643611b3f565b60007f000000000000000000000000da5450a161fa5f940d48ce84349049a903333858604051630748d63560e31b81526001600160a01b038681166004830152602482018690529190911690633a46b1a890604401602060405180830381865afa15801561200f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114309190614145565b805460009080156120635761204d83611bfa600184613e61565b54600160301b90046001600160d01b0316611433565b60009392505050565b600b54604080516001600160a01b03928316815291831660208301527f08f74ea46ef7894f65eabfb5e6e695de773a000b47c529ab559178069b226401910160405180910390a1600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6060826120ea576120e582612e00565b610a67565b5080610a67565b8063ffffffff1660000361211b5760405163f1cfbf0560e01b815260006004820152602401610e25565b6008546040805163ffffffff600160301b9093048316815291831660208301527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a16008805463ffffffff909216600160301b0269ffffffff00000000000019909216919091179055565b60075460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600755565b600060646121dd836110e3565b604051632394e7a360e21b8152600481018590526001600160a01b037f000000000000000000000000da5450a161fa5f940d48ce84349049a9033338581690638e539e8c90602401602060405180830381865afa158015612242573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122669190614145565b612270919061415e565b610a67919061418b565b80546000906001600160801b0380821691600160801b90041681036122a3576122a360316124e3565b6001600160801b038181166000908152600185810160205260408220805492905585546fffffffffffffffffffffffffffffffff19169301909116919091179092555090565b60006001600160d01b03821115611b72576040516306dfcc6560e41b815260d0600482015260248101839052604401610e25565b60008061232b858585612e29565b915091505b935093915050565b600080600b60009054906101000a90046001600160a01b03166001600160a01b031663f27a0c926040518163ffffffff1660e01b8152600401602060405180830381865afa15801561238e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123b29190614145565b905060003060601b6bffffffffffffffffffffffff19168418600b5460405163b1c5f42760e01b81529192506001600160a01b03169063b1c5f42790612405908a908a908a9060009088906004016141ad565b602060405180830381865afa158015612422573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124469190614145565b6000898152600c602052604080822092909255600b5491516308f2a0bb60e41b81526001600160a01b0390921691638f2a0bb091612491918b918b918b919088908a906004016141fb565b600060405180830381600087803b1580156124ab57600080fd5b505af11580156124bf573d6000803e3d6000fd5b505050506124d782426124d29190614055565b611b3f565b98975050505050505050565b634e487b71600052806020526024601cfd5b600b546001600160a01b031663e38335e53486868660003060601b6bffffffffffffffffffffffff191688186040518763ffffffff1660e01b81526004016125419594939291906141ad565b6000604051808303818588803b15801561255a57600080fd5b505af115801561256e573d6000803e3d6000fd5b50505060009687525050600c602052505060408320929092555050565b6000818152600460205260408120805460ff600160f01b8204811691600160f81b90041681156125c057506007949350505050565b80156125d157506002949350505050565b60006125dc86610d91565b90508060000361260257604051636ad0607560e01b815260048101879052602401610e25565b600061260c61139b565b65ffffffffffff16905080821061262a575060009695505050505050565b6000612635886114bd565b905081811061264c57506001979650505050505050565b61265588612f7d565b158061267557506000888152600960205260409020805460019091015411155b1561268857506003979650505050505050565b60008881526004602052604090206001015465ffffffffffff166000036126b757506004979650505050505050565b506005979650505050505050565b6000806126d486868686612fb4565b6000818152600c60205260409020549091508015610c1b57600b5460405163c4d252f560e01b8152600481018390526001600160a01b039091169063c4d252f590602401600060405180830381600087803b15801561273257600080fd5b505af1158015612746573d6000803e3d6000fd5b5050506000838152600c602052604081205550509050949350505050565b6000306001600160a01b037f000000000000000000000000f41cedf993265e1bff33de74046449b1cda2d8b6161480156127bd57507f000000000000000000000000000000000000000000000000000000000000dede46145b156127e757507fb75f7d30628eaa994803dee89ac0336d810033246d719fa262c7801a073b76d490565b610a16604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f01d79d4c11a217e4d1f48346a77f2b35bb4014c8f4c4f2a9e6cb4091c51230e6918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b600080600083516041036128c95760208401516040850151606086015160001a6128bb88828585613065565b9550955095505050506128d5565b50508151600091506002905b9250925092565b6000806000856001600160a01b031685856040516024016128fe929190614253565b60408051601f198184030181529181526020820180516001600160e01b0316630b135d3f60e11b17905251612933919061426c565b600060405180830381855afa9150503d806000811461296e576040519150601f19603f3d011682016040523d82523d6000602084013e612973565b606091505b509150915081801561298757506020815110155b8015610e3a57508051630b135d3f60e11b906129ac9083016020908101908401614145565b149695505050505050565b60008581526009602090815260408083206001600160a01b03881684526003810190925282205460ff1615612a0a576040516371c6af4960e01b81526001600160a01b0387166004820152602401610e25565b6001600160a01b03861660009081526003820160205260409020805460ff1916600117905560ff8516612a565783816000016000828254612a4b9190614055565b90915550612aaf9050565b60001960ff861601612a765783816001016000828254612a4b9190614055565b60011960ff861601612a965783816002016000828254612a4b9190614055565b6040516303599be160e11b815260040160405180910390fd5b509195945050505050565b600060018211612ac8575090565b816001600160801b8210612ae15760809190911c9060401b5b680100000000000000008210612afc5760409190911c9060201b5b6401000000008210612b135760209190911c9060101b5b620100008210612b285760109190911c9060081b5b6101008210612b3c5760089190911c9060041b5b60108210612b4f5760049190911c9060021b5b60048210612b5b5760011b5b600302600190811c90818581612b7357612b73614175565b048201901c90506001818581612b8b57612b8b614175565b048201901c90506001818581612ba357612ba3614175565b048201901c90506001818581612bbb57612bbb614175565b048201901c90506001818581612bd357612bd3614175565b048201901c90506001818581612beb57612beb614175565b048201901c9050612c0a818581612c0457612c04614175565b04821190565b90039392505050565b60005b81831015612c6d576000612c2a8484613134565b60008781526020902090915065ffffffffffff86169082015465ffffffffffff161115612c5957809250612c67565b612c64816001614055565b93505b50612c16565b509392505050565b6000808451831180612c8657508284115b15612c9657506000905080612330565b6000612ca3856001614055565b84118015612ccb575061060f60f31b612cbf8787016020015190565b6001600160f01b031916145b90506000612cdc821515600261415e565b612ce7906028614055565b905080612cf48787613e61565b03612d1657600080612d0789898961314f565b90965094506123309350505050565b600080935093505050612330565b600063ffffffff821115611b72576040516306dfcc6560e41b81526020600482015260248101839052604401610e25565b606060ff8314612d6f57612d6883613215565b9050610a67565b818054612d7b90613d7e565b80601f0160208091040260200160405190810160405280929190818152602001828054612da790613d7e565b8015612df45780601f10612dc957610100808354040283529160200191612df4565b820191906000526020600020905b815481529060010190602001808311612dd757829003601f168201915b50505050509050610a67565b805115612e105780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b825460009081908015612f22576000612e4787611bfa600185613e61565b805490915065ffffffffffff80821691600160301b90046001600160d01b0316908816821115612e8a57604051632520601d60e01b815260040160405180910390fd5b8765ffffffffffff168265ffffffffffff1603612ec357825465ffffffffffff16600160301b6001600160d01b03891602178355612f14565b6040805180820190915265ffffffffffff808a1682526001600160d01b03808a1660208085019182528d54600181018f5560008f81529190912094519151909216600160301b029216919091179101555b945085935061233092505050565b50506040805180820190915265ffffffffffff80851682526001600160d01b0380851660208085019182528854600181018a5560008a815291822095519251909316600160301b029190931617920191909155905081612330565b600081815260096020526040812060028101546001820154612f9f9190614055565b612fab6109ca85610d91565b11159392505050565b600080612fc386868686611580565b905061301181612fd3600761175c565b612fdd600661175c565b612fe7600261175c565b6001612ff4600782614288565b612fff906002614380565b6130099190613e61565b18181861177f565b506000818152600460205260409081902080546001600160f81b0316600160f81b179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c90610d809083815260200190565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08411156130a0575060009150600390508261312a565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa1580156130f4573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166131205750600092506001915082905061312a565b9250600091508190505b9450945094915050565b6000613143600284841861418b565b61143390848416614055565b600080848161315f866001614055565b85118015613187575061060f60f31b61317b8388016020015190565b6001600160f01b031916145b90506000613198821515600261415e565b90506000806131a7838a614055565b90505b878110156132045760006131c96131c48784016020015190565b613254565b9050600f8160ff1611156131e95760008097509750505050505050612330565b6131f460108461415e565b60ff9091160191506001016131aa565b506001999098509650505050505050565b60606000613222836132cd565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060f882901c602f8111801561326e5750603a8160ff16105b1561327c57602f1901610a67565b60608160ff16118015613292575060678160ff16105b156132a05760561901610a67565b60408160ff161180156132b6575060478160ff16105b156132c45760361901610a67565b5060ff92915050565b600060ff8216601f811115610a6757604051632cd44ac360e21b815260040160405180910390fd5b60006020828403121561330757600080fd5b81356001600160e01b03198116811461143357600080fd5b60006020828403121561333157600080fd5b5035919050565b60005b8381101561335357818101518382015260200161333b565b50506000910152565b60008151808452613374816020860160208601613338565b601f01601f19169290920160200192915050565b602081526000611433602083018461335c565b6001600160a01b0381168114610a7e57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156133ee576133ee6133b0565b604052919050565b60006001600160401b0382111561340f5761340f6133b0565b50601f01601f191660200190565b600061343061342b846133f6565b6133c6565b905082815283838301111561344457600080fd5b828260208301376000602084830101529392505050565b600082601f83011261346c57600080fd5b6114338383356020850161341d565b6000806000806080858703121561349157600080fd5b843561349c8161339b565b935060208501356134ac8161339b565b92506040850135915060608501356001600160401b038111156134ce57600080fd5b6134da8782880161345b565b91505092959194509250565b60006001600160401b038211156134ff576134ff6133b0565b5060051b60200190565b600082601f83011261351a57600080fd5b813561352861342b826134e6565b8082825260208201915060208360051b86010192508583111561354a57600080fd5b602085015b83811015610c1b5780356135628161339b565b83526020928301920161354f565b600082601f83011261358157600080fd5b813561358f61342b826134e6565b8082825260208201915060208360051b8601019250858311156135b157600080fd5b602085015b83811015610c1b5780358352602092830192016135b6565b600082601f8301126135df57600080fd5b81356135ed61342b826134e6565b8082825260208201915060208360051b86010192508583111561360f57600080fd5b602085015b83811015610c1b5780356001600160401b0381111561363257600080fd5b613641886020838a010161345b565b84525060209283019201613614565b6000806000806080858703121561366657600080fd5b84356001600160401b0381111561367c57600080fd5b61368887828801613509565b94505060208501356001600160401b038111156136a457600080fd5b6136b087828801613570565b93505060408501356001600160401b038111156136cc57600080fd5b6136d8878288016135ce565b949793965093946060013593505050565b634e487b7160e01b600052602160045260246000fd5b6008811061371d57634e487b7160e01b600052602160045260246000fd5b9052565b60208101610a6782846136ff565b6000806040838503121561374257600080fd5b8235915060208301356137548161339b565b809150509250929050565b803560ff81168114610f0157600080fd5b6000806040838503121561378357600080fd5b823591506137936020840161375f565b90509250929050565b60008083601f8401126137ae57600080fd5b5081356001600160401b038111156137c557600080fd5b6020830191508360208285010111156137dd57600080fd5b9250929050565b600080600080600080600060c0888a0312156137ff57600080fd5b8735965061380f6020890161375f565b9550604088013561381f8161339b565b945060608801356001600160401b0381111561383a57600080fd5b6138468a828b0161379c565b90955093505060808801356001600160401b0381111561386557600080fd5b6138718a828b0161345b565b92505060a08801356001600160401b0381111561388d57600080fd5b6138998a828b0161345b565b91505092959891949750929550565b6000806000806000608086880312156138c057600080fd5b853594506138d06020870161375f565b935060408601356001600160401b038111156138eb57600080fd5b6138f78882890161379c565b90945092505060608601356001600160401b0381111561391657600080fd5b6139228882890161345b565b9150509295509295909350565b65ffffffffffff81168114610a7e57600080fd5b60006020828403121561395557600080fd5b81356114338161392f565b6000806000806060858703121561397657600080fd5b843593506139866020860161375f565b925060408501356001600160401b038111156139a157600080fd5b6139ad8782880161379c565b95989497509550505050565b600080600080608085870312156139cf57600080fd5b84356001600160401b038111156139e557600080fd5b6139f187828801613509565b94505060208501356001600160401b03811115613a0d57600080fd5b613a1987828801613570565b93505060408501356001600160401b03811115613a3557600080fd5b613a41878288016135ce565b92505060608501356001600160401b03811115613a5d57600080fd5b8501601f81018713613a6e57600080fd5b6134da8782356020840161341d565b600060208284031215613a8f57600080fd5b81356114338161339b565b600081518084526020840193506020830160005b82811015613acc578151865260209586019590910190600101613aae565b5093949350505050565b60ff60f81b8816815260e060208201526000613af560e083018961335c565b8281036040840152613b07818961335c565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501529050613b388185613a9a565b9a9950505050505050505050565b60008060008060808587031215613b5c57600080fd5b84359350613b6c6020860161375f565b92506040850135613b7c8161339b565b915060608501356001600160401b038111156134ce57600080fd5b600080600060608486031215613bac57600080fd5b8335613bb78161339b565b92506020840135915060408401356001600160401b03811115613bd957600080fd5b613be58682870161345b565b9150509250925092565b600080600080600060a08688031215613c0757600080fd5b8535613c128161339b565b94506020860135613c228161339b565b935060408601356001600160401b03811115613c3d57600080fd5b613c4988828901613570565b93505060608601356001600160401b03811115613c6557600080fd5b613c7188828901613570565b92505060808601356001600160401b0381111561391657600080fd5b60008060008060608587031215613ca357600080fd5b8435613cae8161339b565b93506020850135925060408501356001600160401b038111156139a157600080fd5b600060208284031215613ce257600080fd5b813563ffffffff8116811461143357600080fd5b60008060408385031215613d0957600080fd5b8235613d148161339b565b946020939093013593505050565b600080600080600060a08688031215613d3a57600080fd5b8535613d458161339b565b94506020860135613d558161339b565b9350604086013592506060860135915060808601356001600160401b0381111561391657600080fd5b600181811c90821680613d9257607f821691505b602082108103613db257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215613de057600080fd5b81516001600160401b03811115613df657600080fd5b8201601f81018413613e0757600080fd5b8051613e1561342b826133f6565b818152856020838501011115613e2a57600080fd5b611990826020830160208601613338565b8183823760009101908152919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610a6757610a67613e4b565b65ffffffffffff8281168282160390811115610a6757610a67613e4b565b600060208284031215613ea457600080fd5b81516114338161392f565b65ffffffffffff8181168382160190811115610a6757610a67613e4b565b600081518084526020840193506020830160005b82811015613acc5781516001600160a01b0316865260209586019590910190600101613ee1565b600082825180855260208501945060208160051b8301016020850160005b83811015613f5857601f19858403018852613f4283835161335c565b6020988901989093509190910190600101613f26565b50909695505050505050565b608081526000613f776080830187613ecd565b8281036020840152613f898187613a9a565b90508281036040840152613f9d8186613f08565b91505082606083015295945050505050565b83815260608101613fc360208301856136ff565b826040830152949350505050565b600060208284031215613fe357600080fd5b8151801515811461143357600080fd5b84815260ff84166020820152826040820152608060608201526000610e3a608083018461335c565b85815260ff8516602082015283604082015260a06060820152600061404360a083018561335c565b82810360808401526124d7818561335c565b80820180821115610a6757610a67613e4b565b8981526001600160a01b0389166020820152610120604082018190526000906140939083018a613ecd565b82810360608401526140a5818a613a9a565b9050828103608084015280885180835260208301915060208160051b84010160208b0160005b838110156140fd57601f198684030185526140e783835161335c565b60209586019590935091909101906001016140cb565b505085810360a0870152614111818b613f08565b93505050508560c08401528460e0840152828103610100840152614135818561335c565b9c9b505050505050505050505050565b60006020828403121561415757600080fd5b5051919050565b8082028115828204841417610a6757610a67613e4b565b634e487b7160e01b600052601260045260246000fd5b6000826141a857634e487b7160e01b600052601260045260246000fd5b500490565b60a0815260006141c060a0830188613ecd565b82810360208401526141d28188613a9a565b905082810360408401526141e68187613f08565b60608401959095525050608001529392505050565b60c08152600061420e60c0830189613ecd565b82810360208401526142208189613a9a565b905082810360408401526142348188613f08565b60608401969096525050608081019290925260a0909101529392505050565b828152604060208201526000611430604083018461335c565b6000825161427e818460208701613338565b9190910192915050565b60ff8181168382160190811115610a6757610a67613e4b565b6001815b6001841115612330578085048111156142c0576142c0613e4b565b60018416156142ce57908102905b60019390931c9280026142a5565b6000826142eb57506001610a67565b816142f857506000610a67565b816001811461430e576002811461431857614334565b6001915050610a67565b60ff84111561432957614329613e4b565b50506001821b610a67565b5060208310610133831016604e8410600b8410161715614357575081810a610a67565b61436460001984846142a1565b806000190482111561437857614378613e4b565b029392505050565b600061143360ff8416836142dc56fea264697066735822122000e93c9422d321f285245dc855588850e932fb7702cc4ee4c114c04b114efe6464736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000da5450a161fa5f940d48ce84349049a903333858000000000000000000000000447b8216eb90fd93ea0ce67cb60982c890cadd13000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : _token (address): 0xda5450A161FA5f940d48Ce84349049a903333858
Arg [1] : _timelock (address): 0x447B8216Eb90FD93Ea0Ce67cb60982C890Cadd13
Arg [2] : _quorumPercentage (uint256): 4
Arg [3] : _votingPeriod (uint32): 5
Arg [4] : _votingDelay (uint48): 1
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000da5450a161fa5f940d48ce84349049a903333858
Arg [1] : 000000000000000000000000447b8216eb90fd93ea0ce67cb60982c890cadd13
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.