Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 44 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Execute | 24571553 | 9 days ago | IN | 0 ETH | 0.00027877 | ||||
| Queue | 24571220 | 9 days ago | IN | 0 ETH | 0.00039765 | ||||
| Cast Vote | 24571110 | 9 days ago | IN | 0 ETH | 0.00004935 | ||||
| Cast Vote | 24571062 | 9 days ago | IN | 0 ETH | 0.00027728 | ||||
| Propose | 24570864 | 9 days ago | IN | 0 ETH | 0.00106867 | ||||
| Execute | 24570670 | 9 days ago | IN | 0 ETH | 0.00047875 | ||||
| Queue | 24570348 | 9 days ago | IN | 0 ETH | 0.0003146 | ||||
| Cast Vote | 24570193 | 9 days ago | IN | 0 ETH | 0.00027105 | ||||
| Propose | 24570014 | 9 days ago | IN | 0 ETH | 0.00066088 | ||||
| Execute | 24348572 | 40 days ago | IN | 0 ETH | 0.00057336 | ||||
| Queue | 24348144 | 40 days ago | IN | 0 ETH | 0.00033146 | ||||
| Cast Vote | 24347923 | 40 days ago | IN | 0 ETH | 0.00025452 | ||||
| Propose | 24347763 | 40 days ago | IN | 0 ETH | 0.00083167 | ||||
| Execute | 24341931 | 41 days ago | IN | 0 ETH | 0.00035958 | ||||
| Queue | 24341592 | 41 days ago | IN | 0 ETH | 0.00081286 | ||||
| Cast Vote | 24341308 | 41 days ago | IN | 0 ETH | 0.00029553 | ||||
| Cast Vote | 24341297 | 41 days ago | IN | 0 ETH | 0.00021206 | ||||
| Propose | 24341137 | 41 days ago | IN | 0 ETH | 0.00098256 | ||||
| Execute | 24279574 | 50 days ago | IN | 0 ETH | 0.00025025 | ||||
| Queue | 24279157 | 50 days ago | IN | 0 ETH | 0.00031446 | ||||
| Cast Vote | 24278940 | 50 days ago | IN | 0 ETH | 0.00024831 | ||||
| Propose | 24278754 | 50 days ago | IN | 0 ETH | 0.00077767 | ||||
| Execute | 24234689 | 56 days ago | IN | 0 ETH | 0.00025905 | ||||
| Queue | 24234281 | 56 days ago | IN | 0 ETH | 0.00040242 | ||||
| Cast Vote | 24234051 | 56 days ago | IN | 0 ETH | 0.00028967 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
OZGovernor
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
// Import OpenZeppelin governance contracts
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorStorage.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorPreventLateQuorum.sol";
/**
* @title OZGovernor
* @dev OZGovernor is a smart contract that extends OpenZeppelin's Governor with additional features
* for voting, timelock, and quorum.
*/
contract OZGovernor is Governor, GovernorSettings, GovernorCountingSimple, GovernorStorage, GovernorVotes,GovernorPreventLateQuorum, GovernorVotesQuorumFraction, GovernorTimelockControl {
/**
* @dev Initializes the OZGovernor contract.
* @param _name The name of the governor.
* @param _token The voting token.
* @param _timelock The timelock controller.
* @param _initialVotingDelay, 7200, 1 day
* @param _initialVotingPeriod, 50400, 1 week
* @param _initialProposalThreshold, 0, proposal threshold
* @param _quorumNumeratorValue, 4, numerator value for quorum
* @param _initialVoteExtension,
*/
constructor(
string memory _name, IVotes _token, TimelockController _timelock,
uint48 _initialVotingDelay, uint32 _initialVotingPeriod, uint256 _initialProposalThreshold,
uint256 _quorumNumeratorValue,
uint48 _initialVoteExtension
)
Governor(_name)
GovernorSettings(_initialVotingDelay, _initialVotingPeriod, _initialProposalThreshold)
GovernorVotes(_token)
GovernorVotesQuorumFraction(_quorumNumeratorValue)
GovernorPreventLateQuorum(_initialVoteExtension)
GovernorTimelockControl(_timelock)
{}
/**
* @notice Retrieves the voting delay configured in the settings.
* @return The configured voting delay.
*/
function votingDelay()
public
view
override(Governor, GovernorSettings)
returns (uint256)
{
return super.votingDelay();
}
/**
* @notice Retrieves the voting period configured in the settings.
* @return The configured voting period.
*/
function votingPeriod()
public
view
override(Governor, GovernorSettings)
returns (uint256)
{
return super.votingPeriod();
}
/**
* @notice Retrieves the quorum required for a vote to succeed.
* @param blockNumber The block number for which to determine the quorum.
* @return The required quorum at the given block number.
*/
function quorum(uint256 blockNumber)
public
view
override(Governor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
/**
* @notice Retrieves the current state of a proposal.
* @param proposalId The ID of the proposal to query.
* @return The current state of the proposal (e.g., Pending, Active, Canceled, Defeated, Succeeded, Queued, Executed).
*/
function state(uint256 proposalId)
public
view
override(Governor, GovernorTimelockControl)
returns (ProposalState)
{
return super.state(proposalId);
}
/**
* @notice Checks if a proposal needs to be queued.
* @param proposalId The ID of the proposal to check.
* @return A boolean indicating whether the proposal needs to be queued.
*/
function proposalNeedsQueuing(uint256 proposalId)
public
view
override(Governor, GovernorTimelockControl)
returns (bool)
{
return super.proposalNeedsQueuing(proposalId);
}
/**
* @notice Retrieves the threshold required for a proposal to be enacted.
* @return The threshold required for a proposal to be enacted.
*/
function proposalThreshold()
public
view
override(Governor, GovernorSettings)
returns (uint256)
{
return super.proposalThreshold();
}
/**
* @notice Proposes an action to be taken.
* @param targets The addresses of the contracts to interact with.
* @param values The values (ETH) to send in the interactions.
* @param calldatas The encoded data of the interactions.
* @param description A brief description of the proposal.
* @param proposer The address of the proposer.
* @return The ID of the newly created proposal.
*/
function _propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description, address proposer)
internal
override(Governor, GovernorStorage)
returns (uint256)
{
return super._propose(targets, values, calldatas, description, proposer);
}
/**
* @notice Queues operations for execution.
* @param proposalId The ID of the proposal containing the operations.
* @param targets The addresses of the contracts to interact with.
* @param values The values (ETH) to send in the interactions.
* @param calldatas The encoded data of the interactions.
* @param descriptionHash The hash of the proposal description.
* @return The ID of the timelock transaction.
*/
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);
}
/**
* @notice Executes operations from a proposal.
* @param proposalId The ID of the proposal containing the operations.
* @param targets The addresses of the contracts to interact with.
* @param values The values (ETH) to send in the interactions.
* @param calldatas The encoded data of the interactions.
* @param descriptionHash The hash of the proposal description.
*/
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);
}
/**
* @notice Cancels operations from a proposal.
* @param targets The addresses of the contracts to interact with.
* @param values The values (ETH) to send in the interactions.
* @param calldatas The encoded data of the interactions.
* @param descriptionHash The hash of the proposal description.
* @return The ID of the canceled proposal.
*/
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);
}
/**
* @notice Casts a vote on a proposal.
* @param proposalId The ID of the proposal to vote on.
* @param account The address of the voter.
* @param support The vote choice (true for yes, false for no).
* @param reason A brief description of the reason for the vote.
* @param params The parameters for the vote.
* @return The ID of the vote.
*/
function _castVote(
uint256 proposalId,
address account,
uint8 support,
string memory reason,
bytes memory params
)
internal
virtual
override(Governor, GovernorPreventLateQuorum)
returns (uint256) {
return super._castVote(proposalId, account, support, reason,params);
}
/**
*
* @notice Retrieves the deadline for submitting proposals.
* @param proposalId The ID of the proposal to query.
* @return The deadline for submitting proposals.
*/
function proposalDeadline(uint256 proposalId)
public
view
override(Governor,GovernorPreventLateQuorum)
returns (uint256)
{
return super.proposalDeadline(proposalId);
}
/**
* @notice Retrieves the address of the executor configured in the timelock control.
* @return The address of the executor.
*/
function _executor()
internal
view
override(Governor, GovernorTimelockControl)
returns (address)
{
return super._executor();
}
/**
* @dev Returns the current timestamp as a `uint48`.
* @return The current timestamp.
*/
function clock()
public
view
override(Governor,GovernorVotes)
returns (uint48) {
return uint48(block.timestamp);
}
/**
* @dev Returns the clock mode as a string.
* @return The clock mode.
*/
function CLOCK_MODE()
public
view
virtual
override(Governor,GovernorVotes)
returns (string memory) {
return "mode=timestamp";
}
}// 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.0.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC165 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, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
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.0.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 weight,
bytes memory // params
) internal virtual override {
ProposalVote storage proposalVote = _proposalVotes[proposalId];
if (proposalVote.hasVoted[account]) {
revert GovernorAlreadyCastVote(account);
}
proposalVote.hasVoted[account] = true;
if (support == uint8(VoteType.Against)) {
proposalVote.againstVotes += weight;
} else if (support == uint8(VoteType.For)) {
proposalVote.forVotes += weight;
} else if (support == uint8(VoteType.Abstain)) {
proposalVote.abstainVotes += weight;
} else {
revert GovernorInvalidVoteType();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (governance/extensions/GovernorPreventLateQuorum.sol)
pragma solidity ^0.8.20;
import {Governor} from "../Governor.sol";
import {Math} from "../../utils/math/Math.sol";
/**
* @dev A module that ensures there is a minimum voting period after quorum is reached. This prevents a large voter from
* swaying a vote and triggering quorum at the last minute, by ensuring there is always time for other voters to react
* and try to oppose the decision.
*
* If a vote causes quorum to be reached, the proposal's voting period may be extended so that it does not end before at
* least a specified time has passed (the "vote extension" parameter). This parameter can be set through a governance
* proposal.
*/
abstract contract GovernorPreventLateQuorum is Governor {
uint48 private _voteExtension;
mapping(uint256 proposalId => uint48) private _extendedDeadlines;
/// @dev Emitted when a proposal deadline is pushed back due to reaching quorum late in its voting period.
event ProposalExtended(uint256 indexed proposalId, uint64 extendedDeadline);
/// @dev Emitted when the {lateQuorumVoteExtension} parameter is changed.
event LateQuorumVoteExtensionSet(uint64 oldVoteExtension, uint64 newVoteExtension);
/**
* @dev Initializes the vote extension parameter: the time in either number of blocks or seconds (depending on the
* governor clock mode) that is required to pass since the moment a proposal reaches quorum until its voting period
* ends. If necessary the voting period will be extended beyond the one set during proposal creation.
*/
constructor(uint48 initialVoteExtension) {
_setLateQuorumVoteExtension(initialVoteExtension);
}
/**
* @dev Returns the proposal deadline, which may have been extended beyond that set at proposal creation, if the
* proposal reached quorum late in the voting period. See {Governor-proposalDeadline}.
*/
function proposalDeadline(uint256 proposalId) public view virtual override returns (uint256) {
return Math.max(super.proposalDeadline(proposalId), _extendedDeadlines[proposalId]);
}
/**
* @dev Casts a vote and detects if it caused quorum to be reached, potentially extending the voting period. See
* {Governor-_castVote}.
*
* May emit a {ProposalExtended} event.
*/
function _castVote(
uint256 proposalId,
address account,
uint8 support,
string memory reason,
bytes memory params
) internal virtual override returns (uint256) {
uint256 result = super._castVote(proposalId, account, support, reason, params);
if (_extendedDeadlines[proposalId] == 0 && _quorumReached(proposalId)) {
uint48 extendedDeadline = clock() + lateQuorumVoteExtension();
if (extendedDeadline > proposalDeadline(proposalId)) {
emit ProposalExtended(proposalId, extendedDeadline);
}
_extendedDeadlines[proposalId] = extendedDeadline;
}
return result;
}
/**
* @dev Returns the current value of the vote extension parameter: the number of blocks that are required to pass
* from the time a proposal reaches quorum until its voting period ends.
*/
function lateQuorumVoteExtension() public view virtual returns (uint48) {
return _voteExtension;
}
/**
* @dev Changes the {lateQuorumVoteExtension}. This operation can only be performed by the governance executor,
* generally through a governance proposal.
*
* Emits a {LateQuorumVoteExtensionSet} event.
*/
function setLateQuorumVoteExtension(uint48 newVoteExtension) public virtual onlyGovernance {
_setLateQuorumVoteExtension(newVoteExtension);
}
/**
* @dev Changes the {lateQuorumVoteExtension}. This is an internal function that can be exposed in a public function
* like {setLateQuorumVoteExtension} if another access control mechanism is needed.
*
* Emits a {LateQuorumVoteExtensionSet} event.
*/
function _setLateQuorumVoteExtension(uint48 newVoteExtension) internal virtual {
emit LateQuorumVoteExtensionSet(_voteExtension, newVoteExtension);
_voteExtension = newVoteExtension;
}
}// 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.0.0) (governance/extensions/GovernorStorage.sol)
pragma solidity ^0.8.20;
import {Governor} from "../Governor.sol";
/**
* @dev Extension of {Governor} that implements storage of proposal details. This modules also provides primitives for
* the enumerability of proposals.
*
* Use cases for this module include:
* - UIs that explore the proposal state without relying on event indexing.
* - Using only the proposalId as an argument in the {Governor-queue} and {Governor-execute} functions for L2 chains
* where storage is cheap compared to calldata.
*/
abstract contract GovernorStorage is Governor {
struct ProposalDetails {
address[] targets;
uint256[] values;
bytes[] calldatas;
bytes32 descriptionHash;
}
uint256[] private _proposalIds;
mapping(uint256 proposalId => ProposalDetails) private _proposalDetails;
/**
* @dev Hook into the proposing mechanism
*/
function _propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description,
address proposer
) internal virtual override returns (uint256) {
uint256 proposalId = super._propose(targets, values, calldatas, description, proposer);
// store
_proposalIds.push(proposalId);
_proposalDetails[proposalId] = ProposalDetails({
targets: targets,
values: values,
calldatas: calldatas,
descriptionHash: keccak256(bytes(description))
});
return proposalId;
}
/**
* @dev Version of {IGovernorTimelock-queue} with only `proposalId` as an argument.
*/
function queue(uint256 proposalId) public virtual {
// here, using storage is more efficient than memory
ProposalDetails storage details = _proposalDetails[proposalId];
queue(details.targets, details.values, details.calldatas, details.descriptionHash);
}
/**
* @dev Version of {IGovernor-execute} with only `proposalId` as an argument.
*/
function execute(uint256 proposalId) public payable virtual {
// here, using storage is more efficient than memory
ProposalDetails storage details = _proposalDetails[proposalId];
execute(details.targets, details.values, details.calldatas, details.descriptionHash);
}
/**
* @dev ProposalId version of {IGovernor-cancel}.
*/
function cancel(uint256 proposalId) public virtual {
// here, using storage is more efficient than memory
ProposalDetails storage details = _proposalDetails[proposalId];
cancel(details.targets, details.values, details.calldatas, details.descriptionHash);
}
/**
* @dev Returns the number of stored proposals.
*/
function proposalCount() public view virtual returns (uint256) {
return _proposalIds.length;
}
/**
* @dev Returns the details of a proposalId. Reverts if `proposalId` is not a known proposal.
*/
function proposalDetails(
uint256 proposalId
) public view virtual returns (address[] memory, uint256[] memory, bytes[] memory, bytes32) {
// here, using memory is more efficient than storage
ProposalDetails memory details = _proposalDetails[proposalId];
if (details.descriptionHash == 0) {
revert GovernorNonexistentProposal(proposalId);
}
return (details.targets, details.values, details.calldatas, details.descriptionHash);
}
/**
* @dev Returns the details (including the proposalId) of a proposal given its sequential index.
*/
function proposalDetailsAt(
uint256 index
) public view virtual returns (uint256, address[] memory, uint256[] memory, bytes[] memory, bytes32) {
uint256 proposalId = _proposalIds[index];
(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) = proposalDetails(proposalId);
return (proposalId, targets, values, calldatas, descriptionHash);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.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) 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.
*
* NOTE: `AccessManager` does not support scheduling more than one operation with the same target and calldata at
* the same time. See {AccessManager-schedule} for a workaround.
*/
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.0.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 EIP-6372) is set to match the token's clock. Fallback to block numbers if the token
* does not implement EIP-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 EIP-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.0.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 {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 weight,
bytes memory params
) 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 proposerVotes = getVotes(proposer, clock() - 1);
uint256 votesThreshold = proposalThreshold();
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 weight = _getVotes(account, proposalSnapshot(proposalId), params);
_countVote(proposalId, account, support, weight, params);
if (params.length == 0) {
emit VoteCast(account, proposalId, support, weight, reason);
} else {
emit VoteCastWithParams(account, proposalId, support, weight, reason, params);
}
return weight;
}
/**
* @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) private 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) {
uint256 len = bytes(description).length;
// Length is too short to contain a valid proposer suffix
if (len < 52) {
return true;
}
// Extract what would be the `#proposer=0x` marker beginning the suffix
bytes12 marker;
assembly {
// - Start of the string contents in memory = description + 32
// - First character of the marker = len - 52
// - Length of "#proposer=0x0000000000000000000000000000000000000000" = 52
// - We read the memory word starting at the first character of the marker:
// - (description + 32) + (len - 52) = description + (len - 20)
// - Note: Solidity will ignore anything past the first 12 bytes
marker := mload(add(description, sub(len, 20)))
}
// If the marker is not found, there is no proposer suffix to check
if (marker != bytes12("#proposer=0x")) {
return true;
}
// Parse the 40 characters following the marker as uint160
uint160 recovered = 0;
for (uint256 i = len - 40; i < len; ++i) {
(bool isHex, uint8 value) = _tryHexToUint(bytes(description)[i]);
// If any of the characters is not a hex digit, ignore the suffix entirely
if (!isHex) {
return true;
}
recovered = (recovered << 4) | value;
}
return recovered == uint160(proposer);
}
/**
* @dev Try to parse a character from a string as a hex value. Returns `(true, value)` if the char is in
* `[0-9a-fA-F]` and `(false, 0)` otherwise. Value is guaranteed to be in the range `0 <= value < 16`
*/
function _tryHexToUint(bytes1 char) private pure returns (bool, uint8) {
uint8 c = uint8(char);
unchecked {
// Case 0-9
if (47 < c && c < 58) {
return (true, c - 48);
}
// Case A-F
else if (64 < c && c < 71) {
return (true, c - 55);
}
// Case a-f
else if (96 < c && c < 103) {
return (true, c - 87);
}
// Else: not a hex char
else {
return (false, 0);
}
}
}
/**
* @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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.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.
*/
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 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 interpepretation 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 ERC712 domain separator).
*/
function name() external view returns (string memory);
/**
* @notice module:core
* @dev Version of the governor instance (used in building the ERC712 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 EIP-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 EIP-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.
*/
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.0.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, uint224) {
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 memory 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, uint224) {
uint256 pos = self.length;
if (pos > 0) {
// Copying to memory is important here.
Checkpoint224 memory last = _unsafeAccess(self, pos - 1);
// Checkpoint keys must be non-decreasing.
if (last._key > key) {
revert CheckpointUnorderedInsertion();
}
// Update or push new checkpoint
if (last._key == key) {
_unsafeAccess(self, pos - 1)._value = value;
} else {
self.push(Checkpoint224({_key: key, _value: value}));
}
return (last._value, value);
} else {
self.push(Checkpoint224({_key: key, _value: value}));
return (0, value);
}
}
/**
* @dev Return the index of the last (most recent) checkpoint with key lower 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 _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 is 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, uint208) {
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 memory 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, uint208) {
uint256 pos = self.length;
if (pos > 0) {
// Copying to memory is important here.
Checkpoint208 memory last = _unsafeAccess(self, pos - 1);
// Checkpoint keys must be non-decreasing.
if (last._key > key) {
revert CheckpointUnorderedInsertion();
}
// Update or push new checkpoint
if (last._key == key) {
_unsafeAccess(self, pos - 1)._value = value;
} else {
self.push(Checkpoint208({_key: key, _value: value}));
}
return (last._value, value);
} else {
self.push(Checkpoint208({_key: key, _value: value}));
return (0, value);
}
}
/**
* @dev Return the index of the last (most recent) checkpoint with key lower 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 _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 is 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, uint160) {
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 memory 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, uint160) {
uint256 pos = self.length;
if (pos > 0) {
// Copying to memory is important here.
Checkpoint160 memory last = _unsafeAccess(self, pos - 1);
// Checkpoint keys must be non-decreasing.
if (last._key > key) {
revert CheckpointUnorderedInsertion();
}
// Update or push new checkpoint
if (last._key == key) {
_unsafeAccess(self, pos - 1)._value = value;
} else {
self.push(Checkpoint160({_key: key, _value: value}));
}
return (last._value, value);
} else {
self.push(Checkpoint160({_key: key, _value: value}));
return (0, value);
}
}
/**
* @dev Return the index of the last (most recent) checkpoint with key lower 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 _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 is 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.0.0) (utils/structs/DoubleEndedQueue.sol)
pragma solidity ^0.8.20;
/**
* @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 An operation (e.g. {front}) couldn't be completed due to the queue being empty.
*/
error QueueEmpty();
/**
* @dev A push operation couldn't be completed due to the queue being full.
*/
error QueueFull();
/**
* @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.
*/
error QueueOutOfBounds();
/**
* @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 {QueueFull} if the queue is full.
*/
function pushBack(Bytes32Deque storage deque, bytes32 value) internal {
unchecked {
uint128 backIndex = deque._end;
if (backIndex + 1 == deque._begin) revert QueueFull();
deque._data[backIndex] = value;
deque._end = backIndex + 1;
}
}
/**
* @dev Removes the item at the end of the queue and returns it.
*
* Reverts with {QueueEmpty} if the queue is empty.
*/
function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {
unchecked {
uint128 backIndex = deque._end;
if (backIndex == deque._begin) revert QueueEmpty();
--backIndex;
value = deque._data[backIndex];
delete deque._data[backIndex];
deque._end = backIndex;
}
}
/**
* @dev Inserts an item at the beginning of the queue.
*
* Reverts with {QueueFull} if the queue is full.
*/
function pushFront(Bytes32Deque storage deque, bytes32 value) internal {
unchecked {
uint128 frontIndex = deque._begin - 1;
if (frontIndex == deque._end) revert QueueFull();
deque._data[frontIndex] = value;
deque._begin = frontIndex;
}
}
/**
* @dev Removes the item at the beginning of the queue and returns it.
*
* Reverts with `QueueEmpty` if the queue is empty.
*/
function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {
unchecked {
uint128 frontIndex = deque._begin;
if (frontIndex == deque._end) revert QueueEmpty();
value = deque._data[frontIndex];
delete deque._data[frontIndex];
deque._begin = frontIndex + 1;
}
}
/**
* @dev Returns the item at the beginning of the queue.
*
* Reverts with `QueueEmpty` if the queue is empty.
*/
function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {
if (empty(deque)) revert QueueEmpty();
return deque._data[deque._begin];
}
/**
* @dev Returns the item at the end of the queue.
*
* Reverts with `QueueEmpty` if the queue is empty.
*/
function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {
if (empty(deque)) revert QueueEmpty();
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 `QueueOutOfBounds` if the index is out of bounds.
*/
function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {
if (index >= length(deque)) revert QueueOutOfBounds();
// 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.0.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, uint32, uint48) {
(uint32 valueBefore, uint32 valueAfter, uint48 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, uint32, uint48) {
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));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.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.0.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[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]
* specifications.
*/
library MessageHashUtils {
/**
* @dev Returns the keccak256 digest of an EIP-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) {
/// @solidity memory-safe-assembly
assembly {
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 EIP-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 EIP-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 (EIP-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) {
/// @solidity memory-safe-assembly
assembly {
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.0.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 ERC1271 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 ERC1271, 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) {
(address recovered, ECDSA.RecoverError error, ) = ECDSA.tryRecover(hash, signature);
return
(error == ECDSA.RecoverError.NoError && recovered == signer) ||
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 ERC1271.
*
* 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.0.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 ERC165 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.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* 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[EIP 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.0.0) (utils/math/Math.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @dev Muldiv operation overflow.
*/
error MathOverflowedMulDiv();
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 overflow flag.
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
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 division by zero flag.
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return 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.
return a / b;
}
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
* denominator == 0.
* @dev 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^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + 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^256. Also prevents denominator == 0.
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
///////////////////////////////////////////////
// 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^256 / 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^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
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^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// 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^256. Since the preconditions guarantee that the outcome is
// less than 2^256, 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;
}
}
/**
* @notice 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) {
uint256 result = mulDiv(x, y, denominator);
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
* towards zero.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
}
}
/**
* @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;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
}
}
/**
* @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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
}
}
/**
* @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;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
/**
* @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.0.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 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);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return 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 {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}// 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.0.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);
/// @solidity memory-safe-assembly
assembly {
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.0.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 ERC1967 implementation slot:
* ```solidity
* contract ERC1967 {
* 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;
* }
* }
* ```
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 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) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
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) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
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) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)
pragma solidity ^0.8.20;
import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";
/**
* @dev String operations.
*/
library Strings {
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 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;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
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 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));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1271.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC1271 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.0.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 ERC1155 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 ERC1155 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.0.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 ERC1155 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.0.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.20;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 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.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @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 AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
/**
* @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
* {FailedInnerCall} 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 AddressInsufficientBalance(address(this));
}
(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 {FailedInnerCall}) 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 {FailedInnerCall} 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 {FailedInnerCall}.
*/
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
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.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, RecoverError, bytes32) {
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.
/// @solidity memory-safe-assembly
assembly {
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[EIP-2098 short signatures]
*/
function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {
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, RecoverError, bytes32) {
// 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);
}
}
}{
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": true
},
"optimizer": {
"runs": 800,
"enabled": true
},
"evmVersion": "paris",
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"contract IVotes","name":"_token","type":"address"},{"internalType":"contract TimelockController","name":"_timelock","type":"address"},{"internalType":"uint48","name":"_initialVotingDelay","type":"uint48"},{"internalType":"uint32","name":"_initialVotingPeriod","type":"uint32"},{"internalType":"uint256","name":"_initialProposalThreshold","type":"uint256"},{"internalType":"uint256","name":"_quorumNumeratorValue","type":"uint256"},{"internalType":"uint48","name":"_initialVoteExtension","type":"uint48"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CheckpointUnorderedInsertion","type":"error"},{"inputs":[],"name":"FailedInnerCall","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":"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":[],"name":"QueueEmpty","type":"error"},{"inputs":[],"name":"QueueFull","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":"uint64","name":"oldVoteExtension","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"newVoteExtension","type":"uint64"}],"name":"LateQuorumVoteExtensionSet","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":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"extendedDeadline","type":"uint64"}],"name":"ProposalExtended","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":"uint256","name":"proposalId","type":"uint256"}],"name":"cancel","outputs":[],"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":"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":"uint256","name":"proposalId","type":"uint256"}],"name":"execute","outputs":[],"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":"lateQuorumVoteExtension","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","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":[],"name":"proposalCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"proposalDetails","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"proposalDetailsAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"proposalId","type":"uint256"}],"name":"queue","outputs":[],"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":"uint48","name":"newVoteExtension","type":"uint48"}],"name":"setLateQuorumVoteExtension","outputs":[],"stateMutability":"nonpayable","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
6101806040523480156200001257600080fd5b5060405162005b7b38038062005b7b833981016040819052620000359162000790565b858282898888888e806200005d6040805180820190915260018152603160f81b602082015290565b6200006a82600062000186565b610120526200007b81600162000186565b61014052815160208084019190912060e052815190820120610100524660a0526200010960e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c05260036200012082826200094a565b506200012e905083620001bf565b620001398262000225565b6200014481620002cc565b5050506001600160a01b0316610160526200015f816200030d565b506200016b8162000373565b5062000177816200040a565b50505050505050505062000a92565b6000602083511015620001a6576200019e8362000473565b9050620001b9565b81620001b384826200094a565b5060ff90505b92915050565b6008546040805165ffffffffffff928316815291831660208301527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a16008805465ffffffffffff191665ffffffffffff92909216919091179055565b8063ffffffff16600003620002555760405163f1cfbf0560e01b8152600060048201526024015b60405180910390fd5b6008546040805163ffffffff66010000000000009093048316815291831660208301527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a16008805463ffffffff90921666010000000000000263ffffffff60301b19909216919091179055565b60075460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600755565b600c546040805165ffffffffffff928316815291831660208301527f7ca4ac117ed3cdce75c1161d8207c440389b1a15d69d096831664657c07dafc2910160405180910390a1600c805465ffffffffffff191665ffffffffffff92909216919091179055565b606480821115620003a25760405163243e544560e01b815260048101839052602481018290526044016200024c565b6000620003ae620004b6565b9050620003ca42620003c085620004d2565b600e91906200050c565b505060408051828152602081018590527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b4633997910160405180910390a1505050565b600f54604080516001600160a01b03928316815291831660208301527f08f74ea46ef7894f65eabfb5e6e695de773a000b47c529ab559178069b226401910160405180910390a1600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600080829050601f81511115620004a1578260405163305a27a960e01b81526004016200024c919062000a16565b8051620004ae8262000a4b565b179392505050565b6000620004c4600e62000529565b6001600160d01b0316905090565b60006001600160d01b0382111562000508576040516306dfcc6560e41b815260d06004820152602481018390526044016200024c565b5090565b6000806200051c85858562000579565b915091505b935093915050565b805460009080156200056f5762000555836200054760018462000a70565b600091825260209091200190565b54660100000000000090046001600160d01b031662000572565b60005b9392505050565b825460009081908015620006ac5760006200059b876200054760018562000a70565b60408051808201909152905465ffffffffffff80821680845266010000000000009092046001600160d01b031660208401529192509087161015620005f357604051632520601d60e01b815260040160405180910390fd5b805165ffffffffffff8088169116036200064757846200061a886200054760018662000a70565b80546001600160d01b039290921666010000000000000265ffffffffffff9092169190911790556200069b565b6040805180820190915265ffffffffffff80881682526001600160d01b0380881660208085019182528b54600181018d5560008d815291909120945191519092166601000000000000029216919091179101555b602001519250839150620005219050565b50506040805180820190915265ffffffffffff80851682526001600160d01b0380851660208085019182528854600181018a5560008a815291822095519251909316660100000000000002919093161792019190915590508162000521565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200073e57818101518382015260200162000724565b50506000910152565b80516001600160a01b03811681146200075f57600080fd5b919050565b805165ffffffffffff811681146200075f57600080fd5b805163ffffffff811681146200075f57600080fd5b600080600080600080600080610100898b031215620007ae57600080fd5b88516001600160401b0380821115620007c657600080fd5b818b0191508b601f830112620007db57600080fd5b815181811115620007f057620007f06200070b565b604051601f8201601f19908116603f011681019083821181831017156200081b576200081b6200070b565b816040528281528e60208487010111156200083557600080fd5b6200084883602083016020880162000721565b809c5050505050506200085e60208a0162000747565b96506200086e60408a0162000747565b95506200087e60608a0162000764565b94506200088e60808a016200077b565b935060a0890151925060c08901519150620008ac60e08a0162000764565b90509295985092959890939650565b600181811c90821680620008d057607f821691505b602082108103620008f157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200094557600081815260208120601f850160051c81016020861015620009205750805b601f850160051c820191505b8181101562000941578281556001016200092c565b5050505b505050565b81516001600160401b038111156200096657620009666200070b565b6200097e81620009778454620008bb565b84620008f7565b602080601f831160018114620009b657600084156200099d5750858301515b600019600386901b1c1916600185901b17855562000941565b600085815260208120601f198616915b82811015620009e757888601518255948401946001909101908401620009c6565b508582101562000a065787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602081526000825180602084015262000a3781604085016020870162000721565b601f01601f19169190910160400192915050565b80516020808301519190811015620008f15760001960209190910360031b1b16919050565b81810381811115620001b957634e487b7160e01b600052601160045260246000fd5b60805160a05160c05160e0516101005161012051610140516101605161507562000b0660003960008181610bf00152818161258e0152612812015260006125640152600061253701526000612e6001526000612e3801526000612d9301526000612dbd01526000612de701526150756000f3fe60806040526004361061036f5760003560e01c80637d5e81e2116101c6578063c28bc2fa116100f7578063e540d01d11610095578063f23a6e611161006f578063f23a6e6114610ba1578063f8ce560a14610bc1578063fc0c546a14610be1578063fe0d94c114610c1457600080fd5b8063e540d01d14610b41578063eb9019d414610b61578063ece40cc114610b8157600080fd5b8063da35c664116100d1578063da35c66414610a92578063dd4e2ba514610aa7578063ddf0b00914610aed578063deaaa7cc14610b0d57600080fd5b8063c28bc2fa14610a41578063c59057e414610a54578063d33219b414610a7457600080fd5b8063a7713a7011610164578063ab58fb8e1161013e578063ab58fb8e146109b4578063b58131b0146109ec578063bc197c8114610a01578063c01f9e3714610a2157600080fd5b8063a7713a701461095f578063a890c91014610974578063a9a952941461099457600080fd5b80638ff262e3116101a05780638ff262e3146108f857806391ddadf41461091857806397c3d3341461092b5780639a802a6d1461093f57600080fd5b80637d5e81e21461087a5780637ecebe001461089a57806384b0196e146108d057600080fd5b80633932abb1116102a057806354fd4d501161023e5780635f398a14116102185780635f398a14146107fa57806360c4247f1461081a578063790518871461083a5780637b3c71d31461085a57600080fd5b806354fd4d501461079057806356781388146107ba5780635b8d0e0d146107da57600080fd5b8063438596321161027a578063438596321461068b578063452115d6146106d55780634bf5d7e9146106f5578063544ffc9c1461073b57600080fd5b80633932abb1146106295780633e4f49e61461063e57806340e58ee51461066b57600080fd5b806316e9eaec1161030d5780632e82db94116102e75780632e82db94146105745780632fe3e261146105a557806332b8113e146105d9578063330df7ff1461060957600080fd5b806316e9eaec146104f55780632656227d146105255780632d63f6931461053857600080fd5b806306fdde031161034957806306fdde031461042c578063143489d01461044e578063150b7a021461049c578063160cbed7146104d557600080fd5b806301ffc9a7146103ab57806302a251a3146103e057806306f3f9e61461040c57600080fd5b366103a6573061037d610c27565b6001600160a01b0316146103a457604051637485328f60e11b815260040160405180910390fd5b005b600080fd5b3480156103b757600080fd5b506103cb6103c6366004613f09565b610c40565b60405190151581526020015b60405180910390f35b3480156103ec57600080fd5b50600854600160301b900463ffffffff165b6040519081526020016103d7565b34801561041857600080fd5b506103a4610427366004613f33565b610c92565b34801561043857600080fd5b50610441610ca6565b6040516103d79190613f9c565b34801561045a57600080fd5b50610484610469366004613f33565b6000908152600460205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016103d7565b3480156104a857600080fd5b506104bc6104b7366004614083565b610d38565b6040516001600160e01b031990911681526020016103d7565b3480156104e157600080fd5b506103fe6104f0366004614262565b610d7b565b34801561050157600080fd5b50610515610510366004613f33565b610e4a565b6040516103d794939291906143be565b6103fe610533366004614262565b611054565b34801561054457600080fd5b506103fe610553366004613f33565b600090815260046020526040902054600160a01b900465ffffffffffff1690565b34801561058057600080fd5b5061059461058f366004613f33565b6111ec565b6040516103d7959493929190614409565b3480156105b157600080fd5b506103fe7f3e83946653575f9a39005e1545185629e92736b7528ab20ca3816f315424a81181565b3480156105e557600080fd5b50600c5465ffffffffffff165b60405165ffffffffffff90911681526020016103d7565b34801561061557600080fd5b506103a461062436600461445b565b61123c565b34801561063557600080fd5b506103fe61124d565b34801561064a57600080fd5b5061065e610659366004613f33565b611260565b6040516103d791906144bb565b34801561067757600080fd5b506103a4610686366004613f33565b61126b565b34801561069757600080fd5b506103cb6106a63660046144c9565b60008281526009602090815260408083206001600160a01b038516845260030190915290205460ff1692915050565b3480156106e157600080fd5b506103fe6106f0366004614262565b61140c565b34801561070157600080fd5b5060408051808201909152600e81527f6d6f64653d74696d657374616d700000000000000000000000000000000000006020820152610441565b34801561074757600080fd5b50610775610756366004613f33565b6000908152600960205260409020805460018201546002909201549092565b604080519384526020840192909252908201526060016103d7565b34801561079c57600080fd5b506040805180820190915260018152603160f81b6020820152610441565b3480156107c657600080fd5b506103fe6107d536600461450f565b61147b565b3480156107e657600080fd5b506103fe6107f5366004614584565b6114a4565b34801561080657600080fd5b506103fe61081536600461463f565b611603565b34801561082657600080fd5b506103fe610835366004613f33565b611658565b34801561084657600080fd5b506103a461085536600461445b565b6116e6565b34801561086657600080fd5b506103fe6108753660046146c3565b6116f7565b34801561088657600080fd5b506103fe61089536600461471d565b61173f565b3480156108a657600080fd5b506103fe6108b53660046147d2565b6001600160a01b031660009081526002602052604090205490565b3480156108dc57600080fd5b506108e56117f3565b6040516103d797969594939291906147ef565b34801561090457600080fd5b506103fe61091336600461485d565b611839565b34801561092457600080fd5b50426105f2565b34801561093757600080fd5b5060646103fe565b34801561094b57600080fd5b506103fe61095a3660046148af565b61190b565b34801561096b57600080fd5b506103fe611918565b34801561098057600080fd5b506103a461098f3660046147d2565b611932565b3480156109a057600080fd5b506103cb6109af366004613f33565b611943565b3480156109c057600080fd5b506103fe6109cf366004613f33565b60009081526004602052604090206001015465ffffffffffff1690565b3480156109f857600080fd5b506103fe61194c565b348015610a0d57600080fd5b506104bc610a1c366004614908565b611957565b348015610a2d57600080fd5b506103fe610a3c366004613f33565b61199b565b6103a4610a4f36600461499c565b6119a6565b348015610a6057600080fd5b506103fe610a6f366004614262565b611a26565b348015610a8057600080fd5b50600f546001600160a01b0316610484565b348015610a9e57600080fd5b50600a546103fe565b348015610ab357600080fd5b506040805180820190915260208082527f737570706f72743d627261766f2671756f72756d3d666f722c6162737461696e90820152610441565b348015610af957600080fd5b506103a4610b08366004613f33565b611a60565b348015610b1957600080fd5b506103fe7ff2aad550cf55f045cb27e9c559f9889fdfb6e6cdaa032301d6ea397784ae51d781565b348015610b4d57600080fd5b506103a4610b5c3660046149e0565b611bfc565b348015610b6d57600080fd5b506103fe610b7c366004614a06565b611c0d565b348015610b8d57600080fd5b506103a4610b9c366004613f33565b611c35565b348015610bad57600080fd5b506104bc610bbc366004614a32565b611c46565b348015610bcd57600080fd5b506103fe610bdc366004613f33565b611c8a565b348015610bed57600080fd5b507f0000000000000000000000000000000000000000000000000000000000000000610484565b6103a4610c22366004613f33565b611c95565b6000610c3b600f546001600160a01b031690565b905090565b60006001600160e01b031982166332a2ad4360e11b1480610c7157506001600160e01b03198216630271189760e51b145b80610c8c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610c9a611e31565b610ca381611eab565b50565b606060038054610cb590614a9b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ce190614a9b565b8015610d2e5780601f10610d0357610100808354040283529160200191610d2e565b820191906000526020600020905b815481529060010190602001808311610d1157829003601f168201915b5050505050905090565b600030610d43610c27565b6001600160a01b031614610d6a57604051637485328f60e11b815260040160405180910390fd5b50630a85bd0160e11b949350505050565b600080610d8a86868686611a26565b9050610d9f81610d9a6004611f3a565b611f5d565b506000610daf8288888888611f9c565b905065ffffffffffff811615610e2757600082815260046020908152604091829020600101805465ffffffffffff191665ffffffffffff85169081179091558251858152918201527f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892910160405180910390a1610e40565b604051634844252360e11b815260040160405180910390fd5b5095945050505050565b6000818152600b602090815260408083208151815460a0948102820185019093526080810183815260609586958695919485949390928492849190840182828015610ebe57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ea0575b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015610f1657602002820191906000526020600020905b815481526020019060010190808311610f02575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020016000905b82821015610ff0578382906000526020600020018054610f6390614a9b565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8f90614a9b565b8015610fdc5780601f10610fb157610100808354040283529160200191610fdc565b820191906000526020600020905b815481529060010190602001808311610fbf57829003601f168201915b505050505081526020019060010190610f44565b505050508152602001600382015481525050905080606001516000801b0361103357604051636ad0607560e01b8152600481018790526024015b60405180910390fd5b80516020820151604083015160609093015191989097509195509350915050565b60008061106386868686611a26565b9050611083816110736005611f3a565b61107d6004611f3a565b17611f5d565b50600081815260046020526040902080547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160f01b179055306110c7610c27565b6001600160a01b0316146111595760005b865181101561115757306001600160a01b03168782815181106110fd576110fd614ad5565b60200260200101516001600160a01b0316036111475761114785828151811061112857611128614ad5565b6020026020010151805190602001206005611fab90919063ffffffff16565b61115081614b01565b90506110d8565b505b611166818787878761202e565b3061116f610c27565b6001600160a01b0316141580156111a457506005546fffffffffffffffffffffffffffffffff808216600160801b9092041614155b156111af5760006005555b6040518181527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f906020015b60405180910390a195945050505050565b60006060806060600080600a878154811061120957611209614ad5565b9060005260206000200154905060008060008061122585610e4a565b979e929d50909b5099509497509395505050505050565b611244611e31565b610ca381612042565b6000610c3b60085465ffffffffffff1690565b6000610c8c826120a8565b6000818152600b60209081526040918290208054835181840281018401909452808452909261140792909184918301828280156112d157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112b3575b50505050508260010180548060200260200160405190810160405280929190818152602001828054801561132457602002820191906000526020600020905b815481526020019060010190808311611310575b505050505083600201805480602002602001604051908101604052809291908181526020016000905b828210156113f957838290600052602060002001805461136c90614a9b565b80601f016020809104026020016040519081016040528092919081815260200182805461139890614a9b565b80156113e55780601f106113ba576101008083540402835291602001916113e5565b820191906000526020600020905b8154815290600101906020018083116113c857829003601f168201915b50505050508152602001906001019061134d565b50505050846003015461140c565b505050565b60008061141b86868686611a26565b905061142b81610d9a6000611f3a565b506000818152600460205260409020546001600160a01b031633146114655760405163233d98e360e01b815233600482015260240161102a565b611471868686866121e7565b9695505050505050565b60008033905061149c848285604051806020016040528060008152506121fe565b949350505050565b600080611587876115817f3e83946653575f9a39005e1545185629e92736b7528ab20ca3816f315424a8118c8c8c6114f98e6001600160a01b0316600090815260026020526040902080546001810190915590565b8d8d604051611509929190614b1a565b60405180910390208c805190602001206040516020016115669796959493929190968752602087019590955260ff9390931660408601526001600160a01b03919091166060850152608084015260a083015260c082015260e00190565b60405160208183030381529060405280519060200120612221565b8561224e565b9050806115b2576040516394ab6c0760e01b81526001600160a01b038816600482015260240161102a565b6115f689888a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92506122a6915050565b9998505050505050505050565b60008033905061164d87828888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506122a6915050565b979650505050505050565b600e8054600091829061166c600184614b2a565b8154811061167c5761167c614ad5565b6000918252602090912001805490915065ffffffffffff811690600160301b90046001600160d01b03168582116116bf576001600160d01b031695945050505050565b6116d36116cb876122b5565b600e906122ec565b6001600160d01b03169695505050505050565b6116ee611e31565b610ca3816123a1565b60008033905061147186828787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121fe92505050565b60003361174c8184612407565b6117745760405163d9b3955760e01b81526001600160a01b038216600482015260240161102a565b600061179282611785600142614b3d565b65ffffffffffff16611c0d565b9050600061179e61194c565b9050808210156117da57604051636121770b60e11b81526001600160a01b0384166004820152602481018390526044810182905260640161102a565b6117e78888888887612521565b98975050505050505050565b600060608060008060006060611807612530565b61180f61255d565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b6000806118c5846115817ff2aad550cf55f045cb27e9c559f9889fdfb6e6cdaa032301d6ea397784ae51d789898961188e8b6001600160a01b0316600090815260026020526040902080546001810190915590565b60408051602081019690965285019390935260ff90911660608401526001600160a01b0316608083015260a082015260c001611566565b9050806118f0576040516394ab6c0760e01b81526001600160a01b038516600482015260240161102a565b611471868587604051806020016040528060008152506121fe565b600061149c84848461258a565b6000611924600e612620565b6001600160d01b0316905090565b61193a611e31565b610ca381612659565b60006001610c8c565b6000610c3b60075490565b600030611962610c27565b6001600160a01b03161461198957604051637485328f60e11b815260040160405180910390fd5b5063bc197c8160e01b95945050505050565b6000610c8c826126c2565b6119ae611e31565b600080856001600160a01b03168585856040516119cc929190614b1a565b60006040518083038185875af1925050503d8060008114611a09576040519150601f19603f3d011682016040523d82523d6000602084013e611a0e565b606091505b5091509150611a1d82826126ec565b50505050505050565b600084848484604051602001611a3f94939291906143be565b60408051601f19818403018152919052805160209091012095945050505050565b6000818152600b6020908152604091829020805483518184028101840190945280845290926114079290918491830182828015611ac657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611aa8575b505050505082600101805480602002602001604051908101604052809291908181526020018280548015611b1957602002820191906000526020600020905b815481526020019060010190808311611b05575b505050505083600201805480602002602001604051908101604052809291908181526020016000905b82821015611bee578382906000526020600020018054611b6190614a9b565b80601f0160208091040260200160405190810160405280929190818152602001828054611b8d90614a9b565b8015611bda5780601f10611baf57610100808354040283529160200191611bda565b820191906000526020600020905b815481529060010190602001808311611bbd57829003601f168201915b505050505081526020019060010190611b42565b505050508460030154610d7b565b611c04611e31565b610ca381612708565b6000611c2e8383611c2960408051602081019091526000815290565b61258a565b9392505050565b611c3d611e31565b610ca3816127a6565b600030611c51610c27565b6001600160a01b031614611c7857604051637485328f60e11b815260040160405180910390fd5b5063f23a6e6160e01b95945050505050565b6000610c8c826127e7565b6000818152600b6020908152604091829020805483518184028101840190945280845290926114079290918491830182828015611cfb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611cdd575b505050505082600101805480602002602001604051908101604052809291908181526020018280548015611d4e57602002820191906000526020600020905b815481526020019060010190808311611d3a575b505050505083600201805480602002602001604051908101604052809291908181526020016000905b82821015611e23578382906000526020600020018054611d9690614a9b565b80601f0160208091040260200160405190810160405280929190818152602001828054611dc290614a9b565b8015611e0f5780601f10611de457610100808354040283529160200191611e0f565b820191906000526020600020905b815481529060010190602001808311611df257829003601f168201915b505050505081526020019060010190611d77565b505050508460030154611054565b33611e3a610c27565b6001600160a01b031614611e63576040516347096e4760e01b815233600482015260240161102a565b30611e6c610c27565b6001600160a01b031614611ea95760008036604051611e8c929190614b1a565b604051809103902090505b80611ea26005612891565b03611e9757505b565b606480821115611ed85760405163243e544560e01b8152600481018390526024810182905260440161102a565b6000611ee2611918565b9050611efa42611ef185612921565b600e9190612955565b505060408051828152602081018590527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b4633997910160405180910390a1505050565b6000816007811115611f4e57611f4e614483565b600160ff919091161b92915050565b600080611f6984611260565b9050600083611f7783611f3a565b1603611c2e578381846040516331b75e4d60e01b815260040161102a93929190614b63565b60006114718686868686612970565b81546fffffffffffffffffffffffffffffffff600160801b820481169181166001830190911603611fef57604051638acb5f2760e01b815260040160405180910390fd5b6fffffffffffffffffffffffffffffffff808216600090815260018086016020526040909120939093558354919092018216600160801b029116179055565b61203b8585858585612b0f565b5050505050565b600c546040805165ffffffffffff928316815291831660208301527f7ca4ac117ed3cdce75c1161d8207c440389b1a15d69d096831664657c07dafc2910160405180910390a1600c805465ffffffffffff191665ffffffffffff92909216919091179055565b6000806120b483612ba5565b905060058160078111156120ca576120ca614483565b146120d55792915050565b6000838152601060205260409081902054600f549151632c258a9f60e11b81526004810182905290916001600160a01b03169063584b153e90602401602060405180830381865afa15801561212e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121529190614b85565b15612161575060059392505050565b600f54604051632ab0f52960e01b8152600481018390526001600160a01b0390911690632ab0f52990602401602060405180830381865afa1580156121aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ce9190614b85565b156121dd575060079392505050565b5060029392505050565b60006121f585858585612ce7565b95945050505050565b60006121f58585858561221c60408051602081019091526000815290565b6122a6565b6000610c8c61222e612d86565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600061225d8585612eb1565b509092509050600081600381111561227757612277614483565b1480156122955750856001600160a01b0316826001600160a01b0316145b806114715750611471868686612efe565b60006114718686868686612fee565b600065ffffffffffff8211156122e8576040516306dfcc6560e41b8152603060048201526024810183905260440161102a565b5090565b81546000908181600581111561234b576000612307846130d7565b6123119085614b2a565b60008881526020902090915081015465ffffffffffff908116908716101561233b57809150612349565b612346816001614ba7565b92505b505b6000612359878785856131bf565b905080156123945761237e87612370600184614b2a565b600091825260209091200190565b54600160301b90046001600160d01b031661164d565b6000979650505050505050565b6008546040805165ffffffffffff928316815291831660208301527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a16008805465ffffffffffff191665ffffffffffff92909216919091179055565b8051600090603481101561241f576001915050610c8c565b82810160131901516001600160a01b031981167f2370726f706f7365723d307800000000000000000000000000000000000000001461246357600192505050610c8c565b600080612471602885614b2a565b90505b83811015612500576000806124c088848151811061249457612494614ad5565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016613221565b91509150816124d85760019650505050505050610c8c565b8060ff166004856001600160a01b0316901b1793505050806124f990614b01565b9050612474565b50856001600160a01b0316816001600160a01b031614935050505092915050565b600061147186868686866132b3565b6060610c3b7f0000000000000000000000000000000000000000000000000000000000000000600061338e565b6060610c3b7f0000000000000000000000000000000000000000000000000000000000000000600161338e565b60007f0000000000000000000000000000000000000000000000000000000000000000604051630748d63560e31b81526001600160a01b038681166004830152602482018690529190911690633a46b1a890604401602060405180830381865afa1580156125fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149c9190614bba565b805460009080156126505761263a83612370600184614b2a565b54600160301b90046001600160d01b0316611c2e565b60009392505050565b600f54604080516001600160a01b03928316815291831660208301527f08f74ea46ef7894f65eabfb5e6e695de773a000b47c529ab559178069b226401910160405180910390a1600f80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610c8c6126d083613439565b6000848152600d602052604090205465ffffffffffff1661347c565b606082612701576126fc82613492565b610c8c565b5080610c8c565b8063ffffffff166000036127325760405163f1cfbf0560e01b81526000600482015260240161102a565b6008546040805163ffffffff600160301b9093048316815291831660208301527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a16008805463ffffffff909216600160301b0269ffffffff00000000000019909216919091179055565b60075460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600755565b600060646127f483611658565b604051632394e7a360e21b8152600481018590526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638e539e8c90602401602060405180830381865afa158015612859573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061287d9190614bba565b6128879190614bd3565b610c8c9190614c00565b80546000906fffffffffffffffffffffffffffffffff80821691600160801b90041681036128d2576040516375e52f4f60e01b815260040160405180910390fd5b6fffffffffffffffffffffffffffffffff8181166000908152600185810160205260408220805492905585546fffffffffffffffffffffffffffffffff19169301909116919091179092555090565b60006001600160d01b038211156122e8576040516306dfcc6560e41b815260d060048201526024810183905260440161102a565b6000806129638585856134bb565b915091505b935093915050565b600080600f60009054906101000a90046001600160a01b03166001600160a01b031663f27a0c926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ea9190614bba565b905060003060601b6bffffffffffffffffffffffff19168418600f5460405163b1c5f42760e01b81529192506001600160a01b03169063b1c5f42790612a3d908a908a908a906000908890600401614c22565b602060405180830381865afa158015612a5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7e9190614bba565b60008981526010602052604080822092909255600f5491516308f2a0bb60e41b81526001600160a01b0390921691638f2a0bb091612ac9918b918b918b919088908a90600401614c70565b600060405180830381600087803b158015612ae357600080fd5b505af1158015612af7573d6000803e3d6000fd5b505050506117e78242612b0a9190614ba7565b6122b5565b600f546001600160a01b031663e38335e53486868660003060601b6bffffffffffffffffffffffff191688186040518763ffffffff1660e01b8152600401612b5b959493929190614c22565b6000604051808303818588803b158015612b7457600080fd5b505af1158015612b88573d6000803e3d6000fd5b505050600096875250506010602052505060408320929092555050565b6000818152600460205260408120805460ff600160f01b8204811691600160f81b9004168115612bda57506007949350505050565b8015612beb57506002949350505050565b600085815260046020526040812054600160a01b900465ffffffffffff16905080600003612c2f57604051636ad0607560e01b81526004810187905260240161102a565b65ffffffffffff4216808210612c4c575060009695505050505050565b6000612c578861199b565b9050818110612c6e57506001979650505050505050565b612c7788613635565b1580612c9757506000888152600960205260409020805460019091015411155b15612caa57506003979650505050505050565b60008881526004602052604090206001015465ffffffffffff16600003612cd957506004979650505050505050565b506005979650505050505050565b600080612cf686868686613687565b6000818152601060205260409020549091508015610e4057600f5460405163c4d252f560e01b8152600481018390526001600160a01b039091169063c4d252f590602401600060405180830381600087803b158015612d5457600080fd5b505af1158015612d68573d6000803e3d6000fd5b50505060008381526010602052604081205550509050949350505050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015612ddf57507f000000000000000000000000000000000000000000000000000000000000000046145b15612e0957507f000000000000000000000000000000000000000000000000000000000000000090565b610c3b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60008060008351604103612eeb5760208401516040850151606086015160001a612edd88828585613750565b955095509550505050612ef7565b50508151600091506002905b9250925092565b6000806000856001600160a01b03168585604051602401612f20929190614cc8565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b135d3f60e11b17905251612f6a9190614ce1565b600060405180830381855afa9150503d8060008114612fa5576040519150601f19603f3d011682016040523d82523d6000602084013e612faa565b606091505b5091509150818015612fbe57506020815110155b801561147157508051630b135d3f60e11b90612fe39083016020908101908401614bba565b149695505050505050565b600080612ffe878787878761381f565b6000888152600d602052604090205490915065ffffffffffff16158015613029575061302987613635565b15611471576000613041600c5465ffffffffffff1690565b61304b9042614cfd565b90506130568861199b565b8165ffffffffffff1611156130a35760405165ffffffffffff8216815288907f541f725fb9f7c98a30cc9c0ff32fbb14358cd7159c847a3aa20a2bdc442ba5119060200160405180910390a25b6000888152600d60205260409020805465ffffffffffff191665ffffffffffff929092169190911790559695505050505050565b6000816000036130e957506000919050565b600060016130f684613911565b901c6001901b9050600181848161310f5761310f614bea565b048201901c9050600181848161312757613127614bea565b048201901c9050600181848161313f5761313f614bea565b048201901c9050600181848161315757613157614bea565b048201901c9050600181848161316f5761316f614bea565b048201901c9050600181848161318757613187614bea565b048201901c9050600181848161319f5761319f614bea565b048201901c9050611c2e818285816131b9576131b9614bea565b046139a5565b60005b818310156132195760006131d684846139b4565b60008781526020902090915065ffffffffffff86169082015465ffffffffffff16111561320557809250613213565b613210816001614ba7565b93505b506131c2565b509392505050565b60008060f883901c602f8111801561323c5750603a8160ff16105b1561325157600194602f199091019350915050565b8060ff166040108015613267575060478160ff16105b1561327c576001946036199091019350915050565b8060ff166060108015613292575060678160ff16105b156132a7576001946056199091019350915050565b50600093849350915050565b6000806132c387878787876139cf565b600a805460018101825560009182527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a801829055604080516080810182528a815260208181018b90528183018a90528851898201206060830152848452600b8152919092208251805194955092939092613341928492910190613daf565b50602082810151805161335a9260018501920190613e10565b5060408201518051613376916002840191602090910190613e4b565b50606091909101516003909101559695505050505050565b606060ff83146133a8576133a183613c16565b9050610c8c565b8180546133b490614a9b565b80601f01602080910402602001604051908101604052809291908181526020018280546133e090614a9b565b801561342d5780601f106134025761010080835404028352916020019161342d565b820191906000526020600020905b81548152906001019060200180831161341057829003601f168201915b50505050509050610c8c565b60008181526004602052604081205461346e90600160d01b810463ffffffff1690600160a01b900465ffffffffffff16614cfd565b65ffffffffffff1692915050565b600081831161348b5781611c2e565b5090919050565b8051156134a25780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b8254600090819080156135da5760006134d987612370600185614b2a565b60408051808201909152905465ffffffffffff808216808452600160301b9092046001600160d01b03166020840152919250908716101561352d57604051632520601d60e01b815260040160405180910390fd5b805165ffffffffffff808816911603613579578461355088612370600186614b2a565b80546001600160d01b0392909216600160301b0265ffffffffffff9092169190911790556135ca565b6040805180820190915265ffffffffffff80881682526001600160d01b0380881660208085019182528b54600181018d5560008d81529190912094519151909216600160301b029216919091179101555b6020015192508391506129689050565b50506040805180820190915265ffffffffffff80851682526001600160d01b0380851660208085019182528854600181018a5560008a815291822095519251909316600160301b029190931617920191909155905081612968565b6000818152600960205260408120600281015460018201546136579190614ba7565b60008481526004602052604090205461367e90600160a01b900465ffffffffffff16611c8a565b11159392505050565b60008061369686868686611a26565b90506136e4816136a66007611f3a565b6136b06006611f3a565b6136ba6002611f3a565b60016136c7600782614d1c565b6136d2906002614e19565b6136dc9190614b2a565b181818611f5d565b506000818152600460205260409081902080547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160f81b179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c906111db9083815260200190565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561378b5750600091506003905082613815565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa1580156137df573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661380b57506000925060019150829050613815565b9250600091508190505b9450945094915050565b600061382f86610d9a6001611f3a565b5060008681526004602052604081205461385a908790600160a01b900465ffffffffffff168561258a565b90506138698787878487613c55565b82516000036138be57856001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4888784886040516138b19493929190614e28565b60405180910390a2611471565b856001600160a01b03167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb871288878488886040516138ff959493929190614e50565b60405180910390a29695505050505050565b600080608083901c1561392657608092831c92015b604083901c1561393857604092831c92015b602083901c1561394a57602092831c92015b601083901c1561395c57601092831c92015b600883901c1561396e57600892831c92015b600483901c1561398057600492831c92015b600283901c1561399257600292831c92015b600183901c15610c8c5760010192915050565b600081831061348b5781611c2e565b60006139c36002848418614c00565b611c2e90848416614ba7565b60006139e48686868680519060200120611a26565b9050845186511415806139f957508351865114155b80613a0357508551155b15613a3857855184518651604051630447b05d60e41b815260048101939093526024830191909152604482015260640161102a565b600081815260046020526040902054600160a01b900465ffffffffffff1615613a835780613a6582611260565b6040516331b75e4d60e01b815261102a929190600090600401614b63565b6000613a8d61124d565b613a9f9065ffffffffffff4216614ba7565b90506000613aba60085463ffffffff600160301b9091041690565b600084815260046020526040902080546001600160a01b0319166001600160a01b038716178155909150613aed836122b5565b815465ffffffffffff91909116600160a01b027fffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff909116178155613b3082613d56565b815463ffffffff91909116600160d01b027fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff90911617815588517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e090859087908c908c9067ffffffffffffffff811115613bac57613bac613fc4565b604051908082528060200260200182016040528015613bdf57816020015b6060815260200190600190039081613bca5790505b508c89613bec8a82614ba7565b8e604051613c0299989796959493929190614e8a565b60405180910390a150505095945050505050565b60606000613c2383613d87565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b60008581526009602090815260408083206001600160a01b0388168452600381019092529091205460ff1615613ca9576040516371c6af4960e01b81526001600160a01b038616600482015260240161102a565b6001600160a01b03851660009081526003820160205260409020805460ff1916600117905560ff8416613cf55782816000016000828254613cea9190614ba7565b90915550613d4e9050565b60001960ff851601613d155782816001016000828254613cea9190614ba7565b60011960ff851601613d355782816002016000828254613cea9190614ba7565b6040516303599be160e11b815260040160405180910390fd5b505050505050565b600063ffffffff8211156122e8576040516306dfcc6560e41b8152602060048201526024810183905260440161102a565b600060ff8216601f811115610c8c57604051632cd44ac360e21b815260040160405180910390fd5b828054828255906000526020600020908101928215613e04579160200282015b82811115613e0457825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613dcf565b506122e8929150613e9d565b828054828255906000526020600020908101928215613e04579160200282015b82811115613e04578251825591602001919060010190613e30565b828054828255906000526020600020908101928215613e91579160200282015b82811115613e915782518290613e819082614fa8565b5091602001919060010190613e6b565b506122e8929150613eb2565b5b808211156122e85760008155600101613e9e565b808211156122e8576000613ec68282613ecf565b50600101613eb2565b508054613edb90614a9b565b6000825580601f10613eeb575050565b601f016020900490600052602060002090810190610ca39190613e9d565b600060208284031215613f1b57600080fd5b81356001600160e01b031981168114611c2e57600080fd5b600060208284031215613f4557600080fd5b5035919050565b60005b83811015613f67578181015183820152602001613f4f565b50506000910152565b60008151808452613f88816020860160208601613f4c565b601f01601f19169290920160200192915050565b602081526000611c2e6020830184613f70565b6001600160a01b0381168114610ca357600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561400357614003613fc4565b604052919050565b600067ffffffffffffffff83111561402557614025613fc4565b614038601f8401601f1916602001613fda565b905082815283838301111561404c57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261407457600080fd5b611c2e8383356020850161400b565b6000806000806080858703121561409957600080fd5b84356140a481613faf565b935060208501356140b481613faf565b925060408501359150606085013567ffffffffffffffff8111156140d757600080fd5b6140e387828801614063565b91505092959194509250565b600067ffffffffffffffff82111561410957614109613fc4565b5060051b60200190565b600082601f83011261412457600080fd5b81356020614139614134836140ef565b613fda565b82815260059290921b8401810191818101908684111561415857600080fd5b8286015b8481101561417c57803561416f81613faf565b835291830191830161415c565b509695505050505050565b600082601f83011261419857600080fd5b813560206141a8614134836140ef565b82815260059290921b840181019181810190868411156141c757600080fd5b8286015b8481101561417c57803583529183019183016141cb565b600082601f8301126141f357600080fd5b81356020614203614134836140ef565b82815260059290921b8401810191818101908684111561422257600080fd5b8286015b8481101561417c57803567ffffffffffffffff8111156142465760008081fd5b6142548986838b0101614063565b845250918301918301614226565b6000806000806080858703121561427857600080fd5b843567ffffffffffffffff8082111561429057600080fd5b61429c88838901614113565b955060208701359150808211156142b257600080fd5b6142be88838901614187565b945060408701359150808211156142d457600080fd5b506142e1878288016141e2565b949793965093946060013593505050565b600081518084526020808501945080840160005b8381101561432b5781516001600160a01b031687529582019590820190600101614306565b509495945050505050565b600081518084526020808501945080840160005b8381101561432b5781518752958201959082019060010161434a565b600082825180855260208086019550808260051b84010181860160005b848110156143b157601f1986840301895261439f838351613f70565b98840198925090830190600101614383565b5090979650505050505050565b6080815260006143d160808301876142f2565b82810360208401526143e38187614336565b905082810360408401526143f78186614366565b91505082606083015295945050505050565b85815260a06020820152600061442260a08301876142f2565b82810360408401526144348187614336565b905082810360608401526144488186614366565b9150508260808301529695505050505050565b60006020828403121561446d57600080fd5b813565ffffffffffff81168114611c2e57600080fd5b634e487b7160e01b600052602160045260246000fd5b600881106144b757634e487b7160e01b600052602160045260246000fd5b9052565b60208101610c8c8284614499565b600080604083850312156144dc57600080fd5b8235915060208301356144ee81613faf565b809150509250929050565b803560ff8116811461450a57600080fd5b919050565b6000806040838503121561452257600080fd5b82359150614532602084016144f9565b90509250929050565b60008083601f84011261454d57600080fd5b50813567ffffffffffffffff81111561456557600080fd5b60208301915083602082850101111561457d57600080fd5b9250929050565b600080600080600080600060c0888a03121561459f57600080fd5b873596506145af602089016144f9565b955060408801356145bf81613faf565b9450606088013567ffffffffffffffff808211156145dc57600080fd5b6145e88b838c0161453b565b909650945060808a013591508082111561460157600080fd5b61460d8b838c01614063565b935060a08a013591508082111561462357600080fd5b506146308a828b01614063565b91505092959891949750929550565b60008060008060006080868803121561465757600080fd5b85359450614667602087016144f9565b9350604086013567ffffffffffffffff8082111561468457600080fd5b61469089838a0161453b565b909550935060608801359150808211156146a957600080fd5b506146b688828901614063565b9150509295509295909350565b600080600080606085870312156146d957600080fd5b843593506146e9602086016144f9565b9250604085013567ffffffffffffffff81111561470557600080fd5b6147118782880161453b565b95989497509550505050565b6000806000806080858703121561473357600080fd5b843567ffffffffffffffff8082111561474b57600080fd5b61475788838901614113565b9550602087013591508082111561476d57600080fd5b61477988838901614187565b9450604087013591508082111561478f57600080fd5b61479b888389016141e2565b935060608701359150808211156147b157600080fd5b508501601f810187136147c357600080fd5b6140e38782356020840161400b565b6000602082840312156147e457600080fd5b8135611c2e81613faf565b60ff60f81b8816815260e06020820152600061480e60e0830189613f70565b82810360408401526148208189613f70565b90508660608401526001600160a01b03861660808401528460a084015282810360c084015261484f8185614336565b9a9950505050505050505050565b6000806000806080858703121561487357600080fd5b84359350614883602086016144f9565b9250604085013561489381613faf565b9150606085013567ffffffffffffffff8111156140d757600080fd5b6000806000606084860312156148c457600080fd5b83356148cf81613faf565b925060208401359150604084013567ffffffffffffffff8111156148f257600080fd5b6148fe86828701614063565b9150509250925092565b600080600080600060a0868803121561492057600080fd5b853561492b81613faf565b9450602086013561493b81613faf565b9350604086013567ffffffffffffffff8082111561495857600080fd5b61496489838a01614187565b9450606088013591508082111561497a57600080fd5b61498689838a01614187565b935060808801359150808211156146a957600080fd5b600080600080606085870312156149b257600080fd5b84356149bd81613faf565b935060208501359250604085013567ffffffffffffffff81111561470557600080fd5b6000602082840312156149f257600080fd5b813563ffffffff81168114611c2e57600080fd5b60008060408385031215614a1957600080fd5b8235614a2481613faf565b946020939093013593505050565b600080600080600060a08688031215614a4a57600080fd5b8535614a5581613faf565b94506020860135614a6581613faf565b93506040860135925060608601359150608086013567ffffffffffffffff811115614a8f57600080fd5b6146b688828901614063565b600181811c90821680614aaf57607f821691505b602082108103614acf57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201614b1357614b13614aeb565b5060010190565b8183823760009101908152919050565b81810381811115610c8c57610c8c614aeb565b65ffffffffffff828116828216039080821115614b5c57614b5c614aeb565b5092915050565b83815260608101614b776020830185614499565b826040830152949350505050565b600060208284031215614b9757600080fd5b81518015158114611c2e57600080fd5b80820180821115610c8c57610c8c614aeb565b600060208284031215614bcc57600080fd5b5051919050565b8082028115828204841417610c8c57610c8c614aeb565b634e487b7160e01b600052601260045260246000fd5b600082614c1d57634e487b7160e01b600052601260045260246000fd5b500490565b60a081526000614c3560a08301886142f2565b8281036020840152614c478188614336565b90508281036040840152614c5b8187614366565b60608401959095525050608001529392505050565b60c081526000614c8360c08301896142f2565b8281036020840152614c958189614336565b90508281036040840152614ca98188614366565b60608401969096525050608081019290925260a0909101529392505050565b82815260406020820152600061149c6040830184613f70565b60008251614cf3818460208701613f4c565b9190910192915050565b65ffffffffffff818116838216019080821115614b5c57614b5c614aeb565b60ff8181168382160190811115610c8c57610c8c614aeb565b600181815b80851115614d70578160001904821115614d5657614d56614aeb565b80851615614d6357918102915b93841c9390800290614d3a565b509250929050565b600082614d8757506001610c8c565b81614d9457506000610c8c565b8160018114614daa5760028114614db457614dd0565b6001915050610c8c565b60ff841115614dc557614dc5614aeb565b50506001821b610c8c565b5060208310610133831016604e8410600b8410161715614df3575081810a610c8c565b614dfd8383614d35565b8060001904821115614e1157614e11614aeb565b029392505050565b6000611c2e60ff841683614d78565b84815260ff841660208201528260408201526080606082015260006114716080830184613f70565b85815260ff8516602082015283604082015260a060608201526000614e7860a0830185613f70565b82810360808401526117e78185613f70565b60006101208b835260206001600160a01b038c1681850152816040850152614eb48285018c6142f2565b91508382036060850152614ec8828b614336565b915083820360808501528189518084528284019150828160051b850101838c0160005b83811015614f1957601f19878403018552614f07838351613f70565b94860194925090850190600101614eeb565b505086810360a0880152614f2d818c614366565b9450505050508560c08401528460e0840152828103610100840152614f528185613f70565b9c9b505050505050505050505050565b601f82111561140757600081815260208120601f850160051c81016020861015614f895750805b601f850160051c820191505b81811015613d4e57828155600101614f95565b815167ffffffffffffffff811115614fc257614fc2613fc4565b614fd681614fd08454614a9b565b84614f62565b602080601f83116001811461500b5760008415614ff35750858301515b600019600386901b1c1916600185901b178555613d4e565b600085815260208120601f198616915b8281101561503a5788860151825594840194600190910190840161501b565b50858210156150585787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000814000a0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000ae6fefd97266c482efedc0ef88636c75f1c83e87000000000000000000000000992f2ae6ec322fdeafa97fbc2aa3e046f0171227000000000000000000000000000000000000000000000000000000000000070800000000000000000000000000000000000000000000000000000000000007080000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000000000c4f70656e5363616e2044414f0000000000000000000000000000000000000000
Deployed Bytecode
0x60806040526004361061036f5760003560e01c80637d5e81e2116101c6578063c28bc2fa116100f7578063e540d01d11610095578063f23a6e611161006f578063f23a6e6114610ba1578063f8ce560a14610bc1578063fc0c546a14610be1578063fe0d94c114610c1457600080fd5b8063e540d01d14610b41578063eb9019d414610b61578063ece40cc114610b8157600080fd5b8063da35c664116100d1578063da35c66414610a92578063dd4e2ba514610aa7578063ddf0b00914610aed578063deaaa7cc14610b0d57600080fd5b8063c28bc2fa14610a41578063c59057e414610a54578063d33219b414610a7457600080fd5b8063a7713a7011610164578063ab58fb8e1161013e578063ab58fb8e146109b4578063b58131b0146109ec578063bc197c8114610a01578063c01f9e3714610a2157600080fd5b8063a7713a701461095f578063a890c91014610974578063a9a952941461099457600080fd5b80638ff262e3116101a05780638ff262e3146108f857806391ddadf41461091857806397c3d3341461092b5780639a802a6d1461093f57600080fd5b80637d5e81e21461087a5780637ecebe001461089a57806384b0196e146108d057600080fd5b80633932abb1116102a057806354fd4d501161023e5780635f398a14116102185780635f398a14146107fa57806360c4247f1461081a578063790518871461083a5780637b3c71d31461085a57600080fd5b806354fd4d501461079057806356781388146107ba5780635b8d0e0d146107da57600080fd5b8063438596321161027a578063438596321461068b578063452115d6146106d55780634bf5d7e9146106f5578063544ffc9c1461073b57600080fd5b80633932abb1146106295780633e4f49e61461063e57806340e58ee51461066b57600080fd5b806316e9eaec1161030d5780632e82db94116102e75780632e82db94146105745780632fe3e261146105a557806332b8113e146105d9578063330df7ff1461060957600080fd5b806316e9eaec146104f55780632656227d146105255780632d63f6931461053857600080fd5b806306fdde031161034957806306fdde031461042c578063143489d01461044e578063150b7a021461049c578063160cbed7146104d557600080fd5b806301ffc9a7146103ab57806302a251a3146103e057806306f3f9e61461040c57600080fd5b366103a6573061037d610c27565b6001600160a01b0316146103a457604051637485328f60e11b815260040160405180910390fd5b005b600080fd5b3480156103b757600080fd5b506103cb6103c6366004613f09565b610c40565b60405190151581526020015b60405180910390f35b3480156103ec57600080fd5b50600854600160301b900463ffffffff165b6040519081526020016103d7565b34801561041857600080fd5b506103a4610427366004613f33565b610c92565b34801561043857600080fd5b50610441610ca6565b6040516103d79190613f9c565b34801561045a57600080fd5b50610484610469366004613f33565b6000908152600460205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020016103d7565b3480156104a857600080fd5b506104bc6104b7366004614083565b610d38565b6040516001600160e01b031990911681526020016103d7565b3480156104e157600080fd5b506103fe6104f0366004614262565b610d7b565b34801561050157600080fd5b50610515610510366004613f33565b610e4a565b6040516103d794939291906143be565b6103fe610533366004614262565b611054565b34801561054457600080fd5b506103fe610553366004613f33565b600090815260046020526040902054600160a01b900465ffffffffffff1690565b34801561058057600080fd5b5061059461058f366004613f33565b6111ec565b6040516103d7959493929190614409565b3480156105b157600080fd5b506103fe7f3e83946653575f9a39005e1545185629e92736b7528ab20ca3816f315424a81181565b3480156105e557600080fd5b50600c5465ffffffffffff165b60405165ffffffffffff90911681526020016103d7565b34801561061557600080fd5b506103a461062436600461445b565b61123c565b34801561063557600080fd5b506103fe61124d565b34801561064a57600080fd5b5061065e610659366004613f33565b611260565b6040516103d791906144bb565b34801561067757600080fd5b506103a4610686366004613f33565b61126b565b34801561069757600080fd5b506103cb6106a63660046144c9565b60008281526009602090815260408083206001600160a01b038516845260030190915290205460ff1692915050565b3480156106e157600080fd5b506103fe6106f0366004614262565b61140c565b34801561070157600080fd5b5060408051808201909152600e81527f6d6f64653d74696d657374616d700000000000000000000000000000000000006020820152610441565b34801561074757600080fd5b50610775610756366004613f33565b6000908152600960205260409020805460018201546002909201549092565b604080519384526020840192909252908201526060016103d7565b34801561079c57600080fd5b506040805180820190915260018152603160f81b6020820152610441565b3480156107c657600080fd5b506103fe6107d536600461450f565b61147b565b3480156107e657600080fd5b506103fe6107f5366004614584565b6114a4565b34801561080657600080fd5b506103fe61081536600461463f565b611603565b34801561082657600080fd5b506103fe610835366004613f33565b611658565b34801561084657600080fd5b506103a461085536600461445b565b6116e6565b34801561086657600080fd5b506103fe6108753660046146c3565b6116f7565b34801561088657600080fd5b506103fe61089536600461471d565b61173f565b3480156108a657600080fd5b506103fe6108b53660046147d2565b6001600160a01b031660009081526002602052604090205490565b3480156108dc57600080fd5b506108e56117f3565b6040516103d797969594939291906147ef565b34801561090457600080fd5b506103fe61091336600461485d565b611839565b34801561092457600080fd5b50426105f2565b34801561093757600080fd5b5060646103fe565b34801561094b57600080fd5b506103fe61095a3660046148af565b61190b565b34801561096b57600080fd5b506103fe611918565b34801561098057600080fd5b506103a461098f3660046147d2565b611932565b3480156109a057600080fd5b506103cb6109af366004613f33565b611943565b3480156109c057600080fd5b506103fe6109cf366004613f33565b60009081526004602052604090206001015465ffffffffffff1690565b3480156109f857600080fd5b506103fe61194c565b348015610a0d57600080fd5b506104bc610a1c366004614908565b611957565b348015610a2d57600080fd5b506103fe610a3c366004613f33565b61199b565b6103a4610a4f36600461499c565b6119a6565b348015610a6057600080fd5b506103fe610a6f366004614262565b611a26565b348015610a8057600080fd5b50600f546001600160a01b0316610484565b348015610a9e57600080fd5b50600a546103fe565b348015610ab357600080fd5b506040805180820190915260208082527f737570706f72743d627261766f2671756f72756d3d666f722c6162737461696e90820152610441565b348015610af957600080fd5b506103a4610b08366004613f33565b611a60565b348015610b1957600080fd5b506103fe7ff2aad550cf55f045cb27e9c559f9889fdfb6e6cdaa032301d6ea397784ae51d781565b348015610b4d57600080fd5b506103a4610b5c3660046149e0565b611bfc565b348015610b6d57600080fd5b506103fe610b7c366004614a06565b611c0d565b348015610b8d57600080fd5b506103a4610b9c366004613f33565b611c35565b348015610bad57600080fd5b506104bc610bbc366004614a32565b611c46565b348015610bcd57600080fd5b506103fe610bdc366004613f33565b611c8a565b348015610bed57600080fd5b507f000000000000000000000000ae6fefd97266c482efedc0ef88636c75f1c83e87610484565b6103a4610c22366004613f33565b611c95565b6000610c3b600f546001600160a01b031690565b905090565b60006001600160e01b031982166332a2ad4360e11b1480610c7157506001600160e01b03198216630271189760e51b145b80610c8c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610c9a611e31565b610ca381611eab565b50565b606060038054610cb590614a9b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ce190614a9b565b8015610d2e5780601f10610d0357610100808354040283529160200191610d2e565b820191906000526020600020905b815481529060010190602001808311610d1157829003601f168201915b5050505050905090565b600030610d43610c27565b6001600160a01b031614610d6a57604051637485328f60e11b815260040160405180910390fd5b50630a85bd0160e11b949350505050565b600080610d8a86868686611a26565b9050610d9f81610d9a6004611f3a565b611f5d565b506000610daf8288888888611f9c565b905065ffffffffffff811615610e2757600082815260046020908152604091829020600101805465ffffffffffff191665ffffffffffff85169081179091558251858152918201527f9a2e42fd6722813d69113e7d0079d3d940171428df7373df9c7f7617cfda2892910160405180910390a1610e40565b604051634844252360e11b815260040160405180910390fd5b5095945050505050565b6000818152600b602090815260408083208151815460a0948102820185019093526080810183815260609586958695919485949390928492849190840182828015610ebe57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610ea0575b5050505050815260200160018201805480602002602001604051908101604052809291908181526020018280548015610f1657602002820191906000526020600020905b815481526020019060010190808311610f02575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020016000905b82821015610ff0578382906000526020600020018054610f6390614a9b565b80601f0160208091040260200160405190810160405280929190818152602001828054610f8f90614a9b565b8015610fdc5780601f10610fb157610100808354040283529160200191610fdc565b820191906000526020600020905b815481529060010190602001808311610fbf57829003601f168201915b505050505081526020019060010190610f44565b505050508152602001600382015481525050905080606001516000801b0361103357604051636ad0607560e01b8152600481018790526024015b60405180910390fd5b80516020820151604083015160609093015191989097509195509350915050565b60008061106386868686611a26565b9050611083816110736005611f3a565b61107d6004611f3a565b17611f5d565b50600081815260046020526040902080547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160f01b179055306110c7610c27565b6001600160a01b0316146111595760005b865181101561115757306001600160a01b03168782815181106110fd576110fd614ad5565b60200260200101516001600160a01b0316036111475761114785828151811061112857611128614ad5565b6020026020010151805190602001206005611fab90919063ffffffff16565b61115081614b01565b90506110d8565b505b611166818787878761202e565b3061116f610c27565b6001600160a01b0316141580156111a457506005546fffffffffffffffffffffffffffffffff808216600160801b9092041614155b156111af5760006005555b6040518181527f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f906020015b60405180910390a195945050505050565b60006060806060600080600a878154811061120957611209614ad5565b9060005260206000200154905060008060008061122585610e4a565b979e929d50909b5099509497509395505050505050565b611244611e31565b610ca381612042565b6000610c3b60085465ffffffffffff1690565b6000610c8c826120a8565b6000818152600b60209081526040918290208054835181840281018401909452808452909261140792909184918301828280156112d157602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112b3575b50505050508260010180548060200260200160405190810160405280929190818152602001828054801561132457602002820191906000526020600020905b815481526020019060010190808311611310575b505050505083600201805480602002602001604051908101604052809291908181526020016000905b828210156113f957838290600052602060002001805461136c90614a9b565b80601f016020809104026020016040519081016040528092919081815260200182805461139890614a9b565b80156113e55780601f106113ba576101008083540402835291602001916113e5565b820191906000526020600020905b8154815290600101906020018083116113c857829003601f168201915b50505050508152602001906001019061134d565b50505050846003015461140c565b505050565b60008061141b86868686611a26565b905061142b81610d9a6000611f3a565b506000818152600460205260409020546001600160a01b031633146114655760405163233d98e360e01b815233600482015260240161102a565b611471868686866121e7565b9695505050505050565b60008033905061149c848285604051806020016040528060008152506121fe565b949350505050565b600080611587876115817f3e83946653575f9a39005e1545185629e92736b7528ab20ca3816f315424a8118c8c8c6114f98e6001600160a01b0316600090815260026020526040902080546001810190915590565b8d8d604051611509929190614b1a565b60405180910390208c805190602001206040516020016115669796959493929190968752602087019590955260ff9390931660408601526001600160a01b03919091166060850152608084015260a083015260c082015260e00190565b60405160208183030381529060405280519060200120612221565b8561224e565b9050806115b2576040516394ab6c0760e01b81526001600160a01b038816600482015260240161102a565b6115f689888a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b92506122a6915050565b9998505050505050505050565b60008033905061164d87828888888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506122a6915050565b979650505050505050565b600e8054600091829061166c600184614b2a565b8154811061167c5761167c614ad5565b6000918252602090912001805490915065ffffffffffff811690600160301b90046001600160d01b03168582116116bf576001600160d01b031695945050505050565b6116d36116cb876122b5565b600e906122ec565b6001600160d01b03169695505050505050565b6116ee611e31565b610ca3816123a1565b60008033905061147186828787878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506121fe92505050565b60003361174c8184612407565b6117745760405163d9b3955760e01b81526001600160a01b038216600482015260240161102a565b600061179282611785600142614b3d565b65ffffffffffff16611c0d565b9050600061179e61194c565b9050808210156117da57604051636121770b60e11b81526001600160a01b0384166004820152602481018390526044810182905260640161102a565b6117e78888888887612521565b98975050505050505050565b600060608060008060006060611807612530565b61180f61255d565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b6000806118c5846115817ff2aad550cf55f045cb27e9c559f9889fdfb6e6cdaa032301d6ea397784ae51d789898961188e8b6001600160a01b0316600090815260026020526040902080546001810190915590565b60408051602081019690965285019390935260ff90911660608401526001600160a01b0316608083015260a082015260c001611566565b9050806118f0576040516394ab6c0760e01b81526001600160a01b038516600482015260240161102a565b611471868587604051806020016040528060008152506121fe565b600061149c84848461258a565b6000611924600e612620565b6001600160d01b0316905090565b61193a611e31565b610ca381612659565b60006001610c8c565b6000610c3b60075490565b600030611962610c27565b6001600160a01b03161461198957604051637485328f60e11b815260040160405180910390fd5b5063bc197c8160e01b95945050505050565b6000610c8c826126c2565b6119ae611e31565b600080856001600160a01b03168585856040516119cc929190614b1a565b60006040518083038185875af1925050503d8060008114611a09576040519150601f19603f3d011682016040523d82523d6000602084013e611a0e565b606091505b5091509150611a1d82826126ec565b50505050505050565b600084848484604051602001611a3f94939291906143be565b60408051601f19818403018152919052805160209091012095945050505050565b6000818152600b6020908152604091829020805483518184028101840190945280845290926114079290918491830182828015611ac657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611aa8575b505050505082600101805480602002602001604051908101604052809291908181526020018280548015611b1957602002820191906000526020600020905b815481526020019060010190808311611b05575b505050505083600201805480602002602001604051908101604052809291908181526020016000905b82821015611bee578382906000526020600020018054611b6190614a9b565b80601f0160208091040260200160405190810160405280929190818152602001828054611b8d90614a9b565b8015611bda5780601f10611baf57610100808354040283529160200191611bda565b820191906000526020600020905b815481529060010190602001808311611bbd57829003601f168201915b505050505081526020019060010190611b42565b505050508460030154610d7b565b611c04611e31565b610ca381612708565b6000611c2e8383611c2960408051602081019091526000815290565b61258a565b9392505050565b611c3d611e31565b610ca3816127a6565b600030611c51610c27565b6001600160a01b031614611c7857604051637485328f60e11b815260040160405180910390fd5b5063f23a6e6160e01b95945050505050565b6000610c8c826127e7565b6000818152600b6020908152604091829020805483518184028101840190945280845290926114079290918491830182828015611cfb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611cdd575b505050505082600101805480602002602001604051908101604052809291908181526020018280548015611d4e57602002820191906000526020600020905b815481526020019060010190808311611d3a575b505050505083600201805480602002602001604051908101604052809291908181526020016000905b82821015611e23578382906000526020600020018054611d9690614a9b565b80601f0160208091040260200160405190810160405280929190818152602001828054611dc290614a9b565b8015611e0f5780601f10611de457610100808354040283529160200191611e0f565b820191906000526020600020905b815481529060010190602001808311611df257829003601f168201915b505050505081526020019060010190611d77565b505050508460030154611054565b33611e3a610c27565b6001600160a01b031614611e63576040516347096e4760e01b815233600482015260240161102a565b30611e6c610c27565b6001600160a01b031614611ea95760008036604051611e8c929190614b1a565b604051809103902090505b80611ea26005612891565b03611e9757505b565b606480821115611ed85760405163243e544560e01b8152600481018390526024810182905260440161102a565b6000611ee2611918565b9050611efa42611ef185612921565b600e9190612955565b505060408051828152602081018590527f0553476bf02ef2726e8ce5ced78d63e26e602e4a2257b1f559418e24b4633997910160405180910390a1505050565b6000816007811115611f4e57611f4e614483565b600160ff919091161b92915050565b600080611f6984611260565b9050600083611f7783611f3a565b1603611c2e578381846040516331b75e4d60e01b815260040161102a93929190614b63565b60006114718686868686612970565b81546fffffffffffffffffffffffffffffffff600160801b820481169181166001830190911603611fef57604051638acb5f2760e01b815260040160405180910390fd5b6fffffffffffffffffffffffffffffffff808216600090815260018086016020526040909120939093558354919092018216600160801b029116179055565b61203b8585858585612b0f565b5050505050565b600c546040805165ffffffffffff928316815291831660208301527f7ca4ac117ed3cdce75c1161d8207c440389b1a15d69d096831664657c07dafc2910160405180910390a1600c805465ffffffffffff191665ffffffffffff92909216919091179055565b6000806120b483612ba5565b905060058160078111156120ca576120ca614483565b146120d55792915050565b6000838152601060205260409081902054600f549151632c258a9f60e11b81526004810182905290916001600160a01b03169063584b153e90602401602060405180830381865afa15801561212e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121529190614b85565b15612161575060059392505050565b600f54604051632ab0f52960e01b8152600481018390526001600160a01b0390911690632ab0f52990602401602060405180830381865afa1580156121aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ce9190614b85565b156121dd575060079392505050565b5060029392505050565b60006121f585858585612ce7565b95945050505050565b60006121f58585858561221c60408051602081019091526000815290565b6122a6565b6000610c8c61222e612d86565b8360405161190160f01b8152600281019290925260228201526042902090565b600080600061225d8585612eb1565b509092509050600081600381111561227757612277614483565b1480156122955750856001600160a01b0316826001600160a01b0316145b806114715750611471868686612efe565b60006114718686868686612fee565b600065ffffffffffff8211156122e8576040516306dfcc6560e41b8152603060048201526024810183905260440161102a565b5090565b81546000908181600581111561234b576000612307846130d7565b6123119085614b2a565b60008881526020902090915081015465ffffffffffff908116908716101561233b57809150612349565b612346816001614ba7565b92505b505b6000612359878785856131bf565b905080156123945761237e87612370600184614b2a565b600091825260209091200190565b54600160301b90046001600160d01b031661164d565b6000979650505050505050565b6008546040805165ffffffffffff928316815291831660208301527fc565b045403dc03c2eea82b81a0465edad9e2e7fc4d97e11421c209da93d7a93910160405180910390a16008805465ffffffffffff191665ffffffffffff92909216919091179055565b8051600090603481101561241f576001915050610c8c565b82810160131901516001600160a01b031981167f2370726f706f7365723d307800000000000000000000000000000000000000001461246357600192505050610c8c565b600080612471602885614b2a565b90505b83811015612500576000806124c088848151811061249457612494614ad5565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016613221565b91509150816124d85760019650505050505050610c8c565b8060ff166004856001600160a01b0316901b1793505050806124f990614b01565b9050612474565b50856001600160a01b0316816001600160a01b031614935050505092915050565b600061147186868686866132b3565b6060610c3b7f4f70656e5363616e2044414f000000000000000000000000000000000000000c600061338e565b6060610c3b7f3100000000000000000000000000000000000000000000000000000000000001600161338e565b60007f000000000000000000000000ae6fefd97266c482efedc0ef88636c75f1c83e87604051630748d63560e31b81526001600160a01b038681166004830152602482018690529190911690633a46b1a890604401602060405180830381865afa1580156125fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149c9190614bba565b805460009080156126505761263a83612370600184614b2a565b54600160301b90046001600160d01b0316611c2e565b60009392505050565b600f54604080516001600160a01b03928316815291831660208301527f08f74ea46ef7894f65eabfb5e6e695de773a000b47c529ab559178069b226401910160405180910390a1600f80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610c8c6126d083613439565b6000848152600d602052604090205465ffffffffffff1661347c565b606082612701576126fc82613492565b610c8c565b5080610c8c565b8063ffffffff166000036127325760405163f1cfbf0560e01b81526000600482015260240161102a565b6008546040805163ffffffff600160301b9093048316815291831660208301527f7e3f7f0708a84de9203036abaa450dccc85ad5ff52f78c170f3edb55cf5e8828910160405180910390a16008805463ffffffff909216600160301b0269ffffffff00000000000019909216919091179055565b60075460408051918252602082018390527fccb45da8d5717e6c4544694297c4ba5cf151d455c9bb0ed4fc7a38411bc05461910160405180910390a1600755565b600060646127f483611658565b604051632394e7a360e21b8152600481018590526001600160a01b037f000000000000000000000000ae6fefd97266c482efedc0ef88636c75f1c83e871690638e539e8c90602401602060405180830381865afa158015612859573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061287d9190614bba565b6128879190614bd3565b610c8c9190614c00565b80546000906fffffffffffffffffffffffffffffffff80821691600160801b90041681036128d2576040516375e52f4f60e01b815260040160405180910390fd5b6fffffffffffffffffffffffffffffffff8181166000908152600185810160205260408220805492905585546fffffffffffffffffffffffffffffffff19169301909116919091179092555090565b60006001600160d01b038211156122e8576040516306dfcc6560e41b815260d060048201526024810183905260440161102a565b6000806129638585856134bb565b915091505b935093915050565b600080600f60009054906101000a90046001600160a01b03166001600160a01b031663f27a0c926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ea9190614bba565b905060003060601b6bffffffffffffffffffffffff19168418600f5460405163b1c5f42760e01b81529192506001600160a01b03169063b1c5f42790612a3d908a908a908a906000908890600401614c22565b602060405180830381865afa158015612a5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7e9190614bba565b60008981526010602052604080822092909255600f5491516308f2a0bb60e41b81526001600160a01b0390921691638f2a0bb091612ac9918b918b918b919088908a90600401614c70565b600060405180830381600087803b158015612ae357600080fd5b505af1158015612af7573d6000803e3d6000fd5b505050506117e78242612b0a9190614ba7565b6122b5565b600f546001600160a01b031663e38335e53486868660003060601b6bffffffffffffffffffffffff191688186040518763ffffffff1660e01b8152600401612b5b959493929190614c22565b6000604051808303818588803b158015612b7457600080fd5b505af1158015612b88573d6000803e3d6000fd5b505050600096875250506010602052505060408320929092555050565b6000818152600460205260408120805460ff600160f01b8204811691600160f81b9004168115612bda57506007949350505050565b8015612beb57506002949350505050565b600085815260046020526040812054600160a01b900465ffffffffffff16905080600003612c2f57604051636ad0607560e01b81526004810187905260240161102a565b65ffffffffffff4216808210612c4c575060009695505050505050565b6000612c578861199b565b9050818110612c6e57506001979650505050505050565b612c7788613635565b1580612c9757506000888152600960205260409020805460019091015411155b15612caa57506003979650505050505050565b60008881526004602052604090206001015465ffffffffffff16600003612cd957506004979650505050505050565b506005979650505050505050565b600080612cf686868686613687565b6000818152601060205260409020549091508015610e4057600f5460405163c4d252f560e01b8152600481018390526001600160a01b039091169063c4d252f590602401600060405180830381600087803b158015612d5457600080fd5b505af1158015612d68573d6000803e3d6000fd5b50505060008381526010602052604081205550509050949350505050565b6000306001600160a01b037f0000000000000000000000002cb9e4d600c52832a43e201dc3535e29300ea21216148015612ddf57507f000000000000000000000000000000000000000000000000000000000000000146145b15612e0957507f288c7afa4d8bc24344aad5aa944ad1b92649302fd7fbbbe718f9005f0b7cc9bf90565b610c3b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f28554d1d0f17223e1c6edee924e17ca39f2fda2e436511864223991fc06660c5918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60008060008351604103612eeb5760208401516040850151606086015160001a612edd88828585613750565b955095509550505050612ef7565b50508151600091506002905b9250925092565b6000806000856001600160a01b03168585604051602401612f20929190614cc8565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b135d3f60e11b17905251612f6a9190614ce1565b600060405180830381855afa9150503d8060008114612fa5576040519150601f19603f3d011682016040523d82523d6000602084013e612faa565b606091505b5091509150818015612fbe57506020815110155b801561147157508051630b135d3f60e11b90612fe39083016020908101908401614bba565b149695505050505050565b600080612ffe878787878761381f565b6000888152600d602052604090205490915065ffffffffffff16158015613029575061302987613635565b15611471576000613041600c5465ffffffffffff1690565b61304b9042614cfd565b90506130568861199b565b8165ffffffffffff1611156130a35760405165ffffffffffff8216815288907f541f725fb9f7c98a30cc9c0ff32fbb14358cd7159c847a3aa20a2bdc442ba5119060200160405180910390a25b6000888152600d60205260409020805465ffffffffffff191665ffffffffffff929092169190911790559695505050505050565b6000816000036130e957506000919050565b600060016130f684613911565b901c6001901b9050600181848161310f5761310f614bea565b048201901c9050600181848161312757613127614bea565b048201901c9050600181848161313f5761313f614bea565b048201901c9050600181848161315757613157614bea565b048201901c9050600181848161316f5761316f614bea565b048201901c9050600181848161318757613187614bea565b048201901c9050600181848161319f5761319f614bea565b048201901c9050611c2e818285816131b9576131b9614bea565b046139a5565b60005b818310156132195760006131d684846139b4565b60008781526020902090915065ffffffffffff86169082015465ffffffffffff16111561320557809250613213565b613210816001614ba7565b93505b506131c2565b509392505050565b60008060f883901c602f8111801561323c5750603a8160ff16105b1561325157600194602f199091019350915050565b8060ff166040108015613267575060478160ff16105b1561327c576001946036199091019350915050565b8060ff166060108015613292575060678160ff16105b156132a7576001946056199091019350915050565b50600093849350915050565b6000806132c387878787876139cf565b600a805460018101825560009182527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a801829055604080516080810182528a815260208181018b90528183018a90528851898201206060830152848452600b8152919092208251805194955092939092613341928492910190613daf565b50602082810151805161335a9260018501920190613e10565b5060408201518051613376916002840191602090910190613e4b565b50606091909101516003909101559695505050505050565b606060ff83146133a8576133a183613c16565b9050610c8c565b8180546133b490614a9b565b80601f01602080910402602001604051908101604052809291908181526020018280546133e090614a9b565b801561342d5780601f106134025761010080835404028352916020019161342d565b820191906000526020600020905b81548152906001019060200180831161341057829003601f168201915b50505050509050610c8c565b60008181526004602052604081205461346e90600160d01b810463ffffffff1690600160a01b900465ffffffffffff16614cfd565b65ffffffffffff1692915050565b600081831161348b5781611c2e565b5090919050565b8051156134a25780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b8254600090819080156135da5760006134d987612370600185614b2a565b60408051808201909152905465ffffffffffff808216808452600160301b9092046001600160d01b03166020840152919250908716101561352d57604051632520601d60e01b815260040160405180910390fd5b805165ffffffffffff808816911603613579578461355088612370600186614b2a565b80546001600160d01b0392909216600160301b0265ffffffffffff9092169190911790556135ca565b6040805180820190915265ffffffffffff80881682526001600160d01b0380881660208085019182528b54600181018d5560008d81529190912094519151909216600160301b029216919091179101555b6020015192508391506129689050565b50506040805180820190915265ffffffffffff80851682526001600160d01b0380851660208085019182528854600181018a5560008a815291822095519251909316600160301b029190931617920191909155905081612968565b6000818152600960205260408120600281015460018201546136579190614ba7565b60008481526004602052604090205461367e90600160a01b900465ffffffffffff16611c8a565b11159392505050565b60008061369686868686611a26565b90506136e4816136a66007611f3a565b6136b06006611f3a565b6136ba6002611f3a565b60016136c7600782614d1c565b6136d2906002614e19565b6136dc9190614b2a565b181818611f5d565b506000818152600460205260409081902080547effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160f81b179055517f789cf55be980739dad1d0699b93b58e806b51c9d96619bfa8fe0a28abaa7b30c906111db9083815260200190565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084111561378b5750600091506003905082613815565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa1580156137df573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661380b57506000925060019150829050613815565b9250600091508190505b9450945094915050565b600061382f86610d9a6001611f3a565b5060008681526004602052604081205461385a908790600160a01b900465ffffffffffff168561258a565b90506138698787878487613c55565b82516000036138be57856001600160a01b03167fb8e138887d0aa13bab447e82de9d5c1777041ecd21ca36ba824ff1e6c07ddda4888784886040516138b19493929190614e28565b60405180910390a2611471565b856001600160a01b03167fe2babfbac5889a709b63bb7f598b324e08bc5a4fb9ec647fb3cbc9ec07eb871288878488886040516138ff959493929190614e50565b60405180910390a29695505050505050565b600080608083901c1561392657608092831c92015b604083901c1561393857604092831c92015b602083901c1561394a57602092831c92015b601083901c1561395c57601092831c92015b600883901c1561396e57600892831c92015b600483901c1561398057600492831c92015b600283901c1561399257600292831c92015b600183901c15610c8c5760010192915050565b600081831061348b5781611c2e565b60006139c36002848418614c00565b611c2e90848416614ba7565b60006139e48686868680519060200120611a26565b9050845186511415806139f957508351865114155b80613a0357508551155b15613a3857855184518651604051630447b05d60e41b815260048101939093526024830191909152604482015260640161102a565b600081815260046020526040902054600160a01b900465ffffffffffff1615613a835780613a6582611260565b6040516331b75e4d60e01b815261102a929190600090600401614b63565b6000613a8d61124d565b613a9f9065ffffffffffff4216614ba7565b90506000613aba60085463ffffffff600160301b9091041690565b600084815260046020526040902080546001600160a01b0319166001600160a01b038716178155909150613aed836122b5565b815465ffffffffffff91909116600160a01b027fffffffffffff000000000000ffffffffffffffffffffffffffffffffffffffff909116178155613b3082613d56565b815463ffffffff91909116600160d01b027fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff90911617815588517f7d84a6263ae0d98d3329bd7b46bb4e8d6f98cd35a7adb45c274c8b7fd5ebd5e090859087908c908c9067ffffffffffffffff811115613bac57613bac613fc4565b604051908082528060200260200182016040528015613bdf57816020015b6060815260200190600190039081613bca5790505b508c89613bec8a82614ba7565b8e604051613c0299989796959493929190614e8a565b60405180910390a150505095945050505050565b60606000613c2383613d87565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b60008581526009602090815260408083206001600160a01b0388168452600381019092529091205460ff1615613ca9576040516371c6af4960e01b81526001600160a01b038616600482015260240161102a565b6001600160a01b03851660009081526003820160205260409020805460ff1916600117905560ff8416613cf55782816000016000828254613cea9190614ba7565b90915550613d4e9050565b60001960ff851601613d155782816001016000828254613cea9190614ba7565b60011960ff851601613d355782816002016000828254613cea9190614ba7565b6040516303599be160e11b815260040160405180910390fd5b505050505050565b600063ffffffff8211156122e8576040516306dfcc6560e41b8152602060048201526024810183905260440161102a565b600060ff8216601f811115610c8c57604051632cd44ac360e21b815260040160405180910390fd5b828054828255906000526020600020908101928215613e04579160200282015b82811115613e0457825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190613dcf565b506122e8929150613e9d565b828054828255906000526020600020908101928215613e04579160200282015b82811115613e04578251825591602001919060010190613e30565b828054828255906000526020600020908101928215613e91579160200282015b82811115613e915782518290613e819082614fa8565b5091602001919060010190613e6b565b506122e8929150613eb2565b5b808211156122e85760008155600101613e9e565b808211156122e8576000613ec68282613ecf565b50600101613eb2565b508054613edb90614a9b565b6000825580601f10613eeb575050565b601f016020900490600052602060002090810190610ca39190613e9d565b600060208284031215613f1b57600080fd5b81356001600160e01b031981168114611c2e57600080fd5b600060208284031215613f4557600080fd5b5035919050565b60005b83811015613f67578181015183820152602001613f4f565b50506000910152565b60008151808452613f88816020860160208601613f4c565b601f01601f19169290920160200192915050565b602081526000611c2e6020830184613f70565b6001600160a01b0381168114610ca357600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561400357614003613fc4565b604052919050565b600067ffffffffffffffff83111561402557614025613fc4565b614038601f8401601f1916602001613fda565b905082815283838301111561404c57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261407457600080fd5b611c2e8383356020850161400b565b6000806000806080858703121561409957600080fd5b84356140a481613faf565b935060208501356140b481613faf565b925060408501359150606085013567ffffffffffffffff8111156140d757600080fd5b6140e387828801614063565b91505092959194509250565b600067ffffffffffffffff82111561410957614109613fc4565b5060051b60200190565b600082601f83011261412457600080fd5b81356020614139614134836140ef565b613fda565b82815260059290921b8401810191818101908684111561415857600080fd5b8286015b8481101561417c57803561416f81613faf565b835291830191830161415c565b509695505050505050565b600082601f83011261419857600080fd5b813560206141a8614134836140ef565b82815260059290921b840181019181810190868411156141c757600080fd5b8286015b8481101561417c57803583529183019183016141cb565b600082601f8301126141f357600080fd5b81356020614203614134836140ef565b82815260059290921b8401810191818101908684111561422257600080fd5b8286015b8481101561417c57803567ffffffffffffffff8111156142465760008081fd5b6142548986838b0101614063565b845250918301918301614226565b6000806000806080858703121561427857600080fd5b843567ffffffffffffffff8082111561429057600080fd5b61429c88838901614113565b955060208701359150808211156142b257600080fd5b6142be88838901614187565b945060408701359150808211156142d457600080fd5b506142e1878288016141e2565b949793965093946060013593505050565b600081518084526020808501945080840160005b8381101561432b5781516001600160a01b031687529582019590820190600101614306565b509495945050505050565b600081518084526020808501945080840160005b8381101561432b5781518752958201959082019060010161434a565b600082825180855260208086019550808260051b84010181860160005b848110156143b157601f1986840301895261439f838351613f70565b98840198925090830190600101614383565b5090979650505050505050565b6080815260006143d160808301876142f2565b82810360208401526143e38187614336565b905082810360408401526143f78186614366565b91505082606083015295945050505050565b85815260a06020820152600061442260a08301876142f2565b82810360408401526144348187614336565b905082810360608401526144488186614366565b9150508260808301529695505050505050565b60006020828403121561446d57600080fd5b813565ffffffffffff81168114611c2e57600080fd5b634e487b7160e01b600052602160045260246000fd5b600881106144b757634e487b7160e01b600052602160045260246000fd5b9052565b60208101610c8c8284614499565b600080604083850312156144dc57600080fd5b8235915060208301356144ee81613faf565b809150509250929050565b803560ff8116811461450a57600080fd5b919050565b6000806040838503121561452257600080fd5b82359150614532602084016144f9565b90509250929050565b60008083601f84011261454d57600080fd5b50813567ffffffffffffffff81111561456557600080fd5b60208301915083602082850101111561457d57600080fd5b9250929050565b600080600080600080600060c0888a03121561459f57600080fd5b873596506145af602089016144f9565b955060408801356145bf81613faf565b9450606088013567ffffffffffffffff808211156145dc57600080fd5b6145e88b838c0161453b565b909650945060808a013591508082111561460157600080fd5b61460d8b838c01614063565b935060a08a013591508082111561462357600080fd5b506146308a828b01614063565b91505092959891949750929550565b60008060008060006080868803121561465757600080fd5b85359450614667602087016144f9565b9350604086013567ffffffffffffffff8082111561468457600080fd5b61469089838a0161453b565b909550935060608801359150808211156146a957600080fd5b506146b688828901614063565b9150509295509295909350565b600080600080606085870312156146d957600080fd5b843593506146e9602086016144f9565b9250604085013567ffffffffffffffff81111561470557600080fd5b6147118782880161453b565b95989497509550505050565b6000806000806080858703121561473357600080fd5b843567ffffffffffffffff8082111561474b57600080fd5b61475788838901614113565b9550602087013591508082111561476d57600080fd5b61477988838901614187565b9450604087013591508082111561478f57600080fd5b61479b888389016141e2565b935060608701359150808211156147b157600080fd5b508501601f810187136147c357600080fd5b6140e38782356020840161400b565b6000602082840312156147e457600080fd5b8135611c2e81613faf565b60ff60f81b8816815260e06020820152600061480e60e0830189613f70565b82810360408401526148208189613f70565b90508660608401526001600160a01b03861660808401528460a084015282810360c084015261484f8185614336565b9a9950505050505050505050565b6000806000806080858703121561487357600080fd5b84359350614883602086016144f9565b9250604085013561489381613faf565b9150606085013567ffffffffffffffff8111156140d757600080fd5b6000806000606084860312156148c457600080fd5b83356148cf81613faf565b925060208401359150604084013567ffffffffffffffff8111156148f257600080fd5b6148fe86828701614063565b9150509250925092565b600080600080600060a0868803121561492057600080fd5b853561492b81613faf565b9450602086013561493b81613faf565b9350604086013567ffffffffffffffff8082111561495857600080fd5b61496489838a01614187565b9450606088013591508082111561497a57600080fd5b61498689838a01614187565b935060808801359150808211156146a957600080fd5b600080600080606085870312156149b257600080fd5b84356149bd81613faf565b935060208501359250604085013567ffffffffffffffff81111561470557600080fd5b6000602082840312156149f257600080fd5b813563ffffffff81168114611c2e57600080fd5b60008060408385031215614a1957600080fd5b8235614a2481613faf565b946020939093013593505050565b600080600080600060a08688031215614a4a57600080fd5b8535614a5581613faf565b94506020860135614a6581613faf565b93506040860135925060608601359150608086013567ffffffffffffffff811115614a8f57600080fd5b6146b688828901614063565b600181811c90821680614aaf57607f821691505b602082108103614acf57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201614b1357614b13614aeb565b5060010190565b8183823760009101908152919050565b81810381811115610c8c57610c8c614aeb565b65ffffffffffff828116828216039080821115614b5c57614b5c614aeb565b5092915050565b83815260608101614b776020830185614499565b826040830152949350505050565b600060208284031215614b9757600080fd5b81518015158114611c2e57600080fd5b80820180821115610c8c57610c8c614aeb565b600060208284031215614bcc57600080fd5b5051919050565b8082028115828204841417610c8c57610c8c614aeb565b634e487b7160e01b600052601260045260246000fd5b600082614c1d57634e487b7160e01b600052601260045260246000fd5b500490565b60a081526000614c3560a08301886142f2565b8281036020840152614c478188614336565b90508281036040840152614c5b8187614366565b60608401959095525050608001529392505050565b60c081526000614c8360c08301896142f2565b8281036020840152614c958189614336565b90508281036040840152614ca98188614366565b60608401969096525050608081019290925260a0909101529392505050565b82815260406020820152600061149c6040830184613f70565b60008251614cf3818460208701613f4c565b9190910192915050565b65ffffffffffff818116838216019080821115614b5c57614b5c614aeb565b60ff8181168382160190811115610c8c57610c8c614aeb565b600181815b80851115614d70578160001904821115614d5657614d56614aeb565b80851615614d6357918102915b93841c9390800290614d3a565b509250929050565b600082614d8757506001610c8c565b81614d9457506000610c8c565b8160018114614daa5760028114614db457614dd0565b6001915050610c8c565b60ff841115614dc557614dc5614aeb565b50506001821b610c8c565b5060208310610133831016604e8410600b8410161715614df3575081810a610c8c565b614dfd8383614d35565b8060001904821115614e1157614e11614aeb565b029392505050565b6000611c2e60ff841683614d78565b84815260ff841660208201528260408201526080606082015260006114716080830184613f70565b85815260ff8516602082015283604082015260a060608201526000614e7860a0830185613f70565b82810360808401526117e78185613f70565b60006101208b835260206001600160a01b038c1681850152816040850152614eb48285018c6142f2565b91508382036060850152614ec8828b614336565b915083820360808501528189518084528284019150828160051b850101838c0160005b83811015614f1957601f19878403018552614f07838351613f70565b94860194925090850190600101614eeb565b505086810360a0880152614f2d818c614366565b9450505050508560c08401528460e0840152828103610100840152614f528185613f70565b9c9b505050505050505050505050565b601f82111561140757600081815260208120601f850160051c81016020861015614f895750805b601f850160051c820191505b81811015613d4e57828155600101614f95565b815167ffffffffffffffff811115614fc257614fc2613fc4565b614fd681614fd08454614a9b565b84614f62565b602080601f83116001811461500b5760008415614ff35750858301515b600019600386901b1c1916600185901b178555613d4e565b600085815260208120601f198616915b8281101561503a5788860151825594840194600190910190840161501b565b50858210156150585787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea164736f6c6343000814000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000ae6fefd97266c482efedc0ef88636c75f1c83e87000000000000000000000000992f2ae6ec322fdeafa97fbc2aa3e046f0171227000000000000000000000000000000000000000000000000000000000000070800000000000000000000000000000000000000000000000000000000000007080000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000000000000000000000310000000000000000000000000000000000000000000000000000000000000258000000000000000000000000000000000000000000000000000000000000000c4f70656e5363616e2044414f0000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _name (string): OpenScan DAO
Arg [1] : _token (address): 0xAe6fefD97266c482EfeDC0eF88636c75f1C83e87
Arg [2] : _timelock (address): 0x992f2Ae6eC322fdeaFA97FBC2Aa3E046F0171227
Arg [3] : _initialVotingDelay (uint48): 1800
Arg [4] : _initialVotingPeriod (uint32): 1800
Arg [5] : _initialProposalThreshold (uint256): 100000000000000000000
Arg [6] : _quorumNumeratorValue (uint256): 49
Arg [7] : _initialVoteExtension (uint48): 600
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [1] : 000000000000000000000000ae6fefd97266c482efedc0ef88636c75f1c83e87
Arg [2] : 000000000000000000000000992f2ae6ec322fdeafa97fbc2aa3e046f0171227
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000708
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000708
Arg [5] : 0000000000000000000000000000000000000000000000056bc75e2d63100000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000031
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000258
Arg [8] : 000000000000000000000000000000000000000000000000000000000000000c
Arg [9] : 4f70656e5363616e2044414f0000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
896:8607:40:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3805:4:2;3782:11;:9;:11::i;:::-;-1:-1:-1;;;;;3782:28:2;;3778:91;;3833:25;;-1:-1:-1;;;3833:25:2;;;;;;;;;;;3778:91;896:8607:40;;;;;3942:303:2;;;;;;;;;;-1:-1:-1;3942:303:2;;;;;:::i;:::-;;:::i;:::-;;;470:14:41;;463:22;445:41;;433:2;418:18;3942:303:2;;;;;;;;2591:171:40;;;;;;;;;;-1:-1:-1;1460:13:7;;-1:-1:-1;;;1460:13:7;;;;2591:171:40;;;643:25:41;;;631:2;616:18;2591:171:40;497:177:41;3161:150:11;;;;;;;;;;-1:-1:-1;3161:150:11;;;;;:::i;:::-;;:::i;4301:89:2:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;7771:139::-;;;;;;;;;;-1:-1:-1;7771:139:2;;;;;:::i;:::-;7846:7;7872:22;;;:10;:22;;;;;:31;-1:-1:-1;;;;;7872:31:2;;7771:139;;;;-1:-1:-1;;;;;1784:55:41;;;1766:74;;1754:2;1739:18;7771:139:2;1620:226:41;24712:253:2;;;;;;;;;;-1:-1:-1;24712:253:2;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;3890:33:41;;;3872:52;;3860:2;3845:18;24712:253:2;3728:202:41;12950:729:2;;;;;;;;;;-1:-1:-1;12950:729:2;;;;;:::i;:::-;;:::i;3105:496:8:-;;;;;;;;;;-1:-1:-1;3105:496:8;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;14737:1233:2:-;;;;;;:::i;:::-;;:::i;7317:140::-;;;;;;;;;;-1:-1:-1;7317:140:2;;;;;:::i;:::-;7392:7;7418:22;;;:10;:22;;;;;:32;-1:-1:-1;;;7418:32:2;;;;;7317:140;3724:486:8;;;;;;;;;;-1:-1:-1;3724:486:8;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;1511:197:2:-;;;;;;;;;;;;1570:138;1511:197;;3351:110:6;;;;;;;;;;-1:-1:-1;3440:14:6;;;;3351:110;;;10804:14:41;10792:27;;;10774:46;;10762:2;10747:18;3351:110:6;10630:196:41;3705:153:6;;;;;;;;;;-1:-1:-1;3705:153:6;;;;;:::i;:::-;;:::i;2284:169:40:-;;;;;;;;;;;;;:::i;3453:198::-;;;;;;;;;;-1:-1:-1;3453:198:40;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2521:284:8:-;;;;;;;;;;-1:-1:-1;2521:284:8;;;;;:::i;:::-;;:::i;1043:167:5:-;;;;;;;;;;-1:-1:-1;1043:167:5;;;;;:::i;:::-;1136:4;1159:26;;;:14;:26;;;;;;;;-1:-1:-1;;;;;1159:44:5;;;;:35;;:44;;;;;;;;1043:167;;;;;16920:977:2;;;;;;;;;;-1:-1:-1;16920:977:2;;;;;:::i;:::-;;:::i;9321:180:40:-;;;;;;;;;;-1:-1:-1;9471:23:40;;;;;;;;;;;;;;;;;9321:180;;1282:321:5;;;;;;;;;;-1:-1:-1;1282:321:5;;;;;:::i;:::-;1368:20;1476:26;;;:14;:26;;;;;1520:25;;1547:21;;;;1570:25;;;;;1520;;1282:321;;;;;12237:25:41;;;12293:2;12278:18;;12271:34;;;;12321:18;;;12314:34;12225:2;12210:18;1282:321:5;12035:319:41;4449:90:2;;;;;;;;;;-1:-1:-1;4522:10:2;;;;;;;;;;;;-1:-1:-1;;;4522:10:2;;;;4449:90;;19443:189;;;;;;;;;;-1:-1:-1;19443:189:2;;;;;:::i;:::-;;:::i;21036:950::-;;;;;;;;;;-1:-1:-1;21036:950:2;;;;;:::i;:::-;;:::i;20038:303::-;;;;;;;;;;-1:-1:-1;20038:303:2;;;;;:::i;:::-;;:::i;1738:616:11:-;;;;;;;;;;-1:-1:-1;1738:616:11;;;;;:::i;:::-;;:::i;1839:125:7:-;;;;;;;;;;-1:-1:-1;1839:125:7;;;;;:::i;:::-;;:::i;19702:257:2:-;;;;;;;;;;-1:-1:-1;19702:257:2;;;;;:::i;:::-;;:::i;10540:803::-;;;;;;;;;;-1:-1:-1;10540:803:2;;;;;:::i;:::-;;:::i;538:107:24:-;;;;;;;;;;-1:-1:-1;538:107:24;;;;;:::i;:::-;-1:-1:-1;;;;;624:14:24;598:7;624:14;;;:7;:14;;;;;;;538:107;5144:557:29;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;20406:546:2:-;;;;;;;;;;-1:-1:-1;20406:546:2;;;;;:::i;:::-;;:::i;9057:163:40:-;;;;;;;;;;-1:-1:-1;9197:15:40;9057:163;;2460:94:11;;;;;;;;;;-1:-1:-1;2544:3:11;2460:94;;19169:214:2;;;;;;;;;;-1:-1:-1;19169:214:2;;;;;:::i;:::-;;:::i;1504:121:11:-;;;;;;;;;;;;;:::i;6194:133:9:-;;;;;;;;;;-1:-1:-1;6194:133:9;;;;;:::i;:::-;;:::i;3864:219:40:-;;;;;;;;;;-1:-1:-1;3864:219:40;;;;;:::i;:::-;;:::i;7973:136:2:-;;;;;;;;;;-1:-1:-1;7973:136:2;;;;;:::i;:::-;8043:7;8069:22;;;:10;:22;;;;;:33;;;;;;7973:136;4251:181:40;;;;;;;;;;;;;:::i;25648:338:2:-;;;;;;;;;;-1:-1:-1;25648:338:2;;;;;:::i;:::-;;:::i;8396:215:40:-;;;;;;;;;;-1:-1:-1;8396:215:40;;;;;:::i;:::-;;:::i;23969:252:2:-;;;;;;:::i;:::-;;:::i;5484:299::-;;;;;;;;;;-1:-1:-1;5484:299:2;;;;;:::i;:::-;;:::i;3118:100:9:-;;;;;;;;;;-1:-1:-1;3201:9:9;;-1:-1:-1;;;;;3201:9:9;3118:100;;2879:106:8;;;;;;;;;;-1:-1:-1;2959:12:8;:19;2879:106;;847:136:5;;;;;;;;;;-1:-1:-1;935:41:5;;;;;;;;;;;;;;;;;;847:136;;1765:282:8;;;;;;;;;;-1:-1:-1;1765:282:8;;;;;:::i;:::-;;:::i;1374:131:2:-;;;;;;;;;;;;1424:81;1374:131;;2139:129:7;;;;;;;;;;-1:-1:-1;2139:129:7;;;;;:::i;:::-;;:::i;18936:163:2:-;;;;;;;;;;-1:-1:-1;18936:163:2;;;;;:::i;:::-;;:::i;2453:150:7:-;;;;;;;;;;-1:-1:-1;2453:150:7;;;;;:::i;:::-;;:::i;25172:264:2:-;;;;;;;;;;-1:-1:-1;25172:264:2;;;;;:::i;:::-;;:::i;2992:200:40:-;;;;;;;;;;-1:-1:-1;2992:200:40;;;;;:::i;:::-;;:::i;794:86:10:-;;;;;;;;;;-1:-1:-1;867:6:10;794:86;;2151:294:8;;;;;;:::i;:::-;;:::i;8766:174:40:-;8886:7;8916:17;3201:9:9;;-1:-1:-1;;;;;3201:9:9;;3118:100;8916:17:40;8909:24;;8766:174;:::o;3942:303:2:-;4044:4;-1:-1:-1;;;;;;4079:42:2;;-1:-1:-1;;;4079:42:2;;:107;;-1:-1:-1;;;;;;;4137:49:2;;-1:-1:-1;;;4137:49:2;4079:107;:159;;;-1:-1:-1;;;;;;;;;;861:40:32;;;4202:36:2;4060:178;3942:303;-1:-1:-1;;3942:303:2:o;3161:150:11:-;3391:18:2;:16;:18::i;:::-;3262:42:11::1;3285:18;3262:22;:42::i;:::-;3161:150:::0;:::o;4301:89:2:-;4346:13;4378:5;4371:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4301:89;:::o;24712:253::-;24803:6;24848:4;24825:11;:9;:11::i;:::-;-1:-1:-1;;;;;24825:28:2;;24821:91;;24876:25;;-1:-1:-1;;;24876:25:2;;;;;;;;;;;24821:91;-1:-1:-1;;;;24712:253:2;;;;;;:::o;12950:729::-;13129:7;13148:18;13169:57;13182:7;13191:6;13199:9;13210:15;13169:12;:57::i;:::-;13148:78;;13237:77;13258:10;13270:43;13289:23;13270:18;:43::i;:::-;13237:20;:77::i;:::-;;13325:17;13345:73;13362:10;13374:7;13383:6;13391:9;13402:15;13345:16;:73::i;:::-;13325:93;-1:-1:-1;13433:15:2;;;;13429:216;;13464:22;;;;:10;:22;;;;;;;;;:33;;:46;;-1:-1:-1;;13464:46:2;;;;;;;;;;13529:38;;23173:25:41;;;23214:18;;;23207:55;13529:38:2;;23146:18:41;13529:38:2;;;;;;;13429:216;;;13605:29;;-1:-1:-1;;;13605:29:2;;;;;;;;;;;13429:216;-1:-1:-1;13662:10:2;12950:729;-1:-1:-1;;;;;12950:729:2:o;3105:496:8:-;3245:7;3358:28;;;:16;:28;;;;;;;;3325:61;;;;;;;;;;;;;;;;;;;;;3193:16;;;;;;3245:7;;;;3325:61;3358:28;;3325:61;;3358:28;;3325:61;;;3358:28;3325:61;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3325:61:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3400:7;:23;;;3427:1;3400:28;;;3396:105;;3451:39;;-1:-1:-1;;;3451:39:8;;;;;643:25:41;;;616:18;;3451:39:8;;;;;;;;3396:105;3518:15;;3535:14;;;;3551:17;;;;3570:23;;;;;3518:15;;3535:14;;-1:-1:-1;3551:17:8;;-1:-1:-1;3570:23:8;-1:-1:-1;3105:496:8;-1:-1:-1;;3105:496:8:o;14737:1233:2:-;14926:7;14945:18;14966:57;14979:7;14988:6;14996:9;15007:15;14966:12;:57::i;:::-;14945:78;;15034:154;15068:10;15138:40;15157:20;15138:18;:40::i;:::-;15092:43;15111:23;15092:18;:43::i;:::-;:86;15034:20;:154::i;:::-;-1:-1:-1;15260:22:2;;;;:10;:22;;;;;:38;;;;-1:-1:-1;;;15260:38:2;;;15398:4;15375:11;:9;:11::i;:::-;-1:-1:-1;;;;;15375:28:2;;15371:258;;15424:9;15419:200;15443:7;:14;15439:1;:18;15419:200;;;15508:4;-1:-1:-1;;;;;15486:27:2;:7;15494:1;15486:10;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;15486:27:2;;15482:123;;15537:49;15572:9;15582:1;15572:12;;;;;;;;:::i;:::-;;;;;;;15562:23;;;;;;15537:15;:24;;:49;;;;:::i;:::-;15459:3;;;:::i;:::-;;;15419:200;;;;15371:258;15639:75;15658:10;15670:7;15679:6;15687:9;15698:15;15639:18;:75::i;:::-;15809:4;15786:11;:9;:11::i;:::-;-1:-1:-1;;;;;15786:28:2;;;:56;;;;-1:-1:-1;15819:15:2;5832:12:38;;;;;-1:-1:-1;;;5818:10:38;;;;:26;15818:24:2;15786:56;15782:110;;;5383:1:38;15858:15:2;5394:14:38;15858:23:2;15907:28;;643:25:41;;;15907:28:2;;631:2:41;616:18;15907:28:2;;;;;;;;15953:10;14737:1233;-1:-1:-1;;;;;14737:1233:2:o;3724:486:8:-;3809:7;3818:16;3836;3854:14;3870:7;3889:18;3910:12;3923:5;3910:19;;;;;;;;:::i;:::-;;;;;;;;;3889:40;;3953:24;3991:23;4028:24;4066:23;4102:27;4118:10;4102:15;:27::i;:::-;4147:10;;3939:190;;-1:-1:-1;3939:190:8;;-1:-1:-1;3939:190:8;-1:-1:-1;4147:10:8;;-1:-1:-1;3724:486:8;;-1:-1:-1;;;;;;3724:486:8:o;3705:153:6:-;3391:18:2;:16;:18::i;:::-;3806:45:6::1;3834:16;3806:27;:45::i;2284:169:40:-:0;2397:7;2427:19;1289:12:7;;;;;1202:106;3453:198:40;3585:13;3621:23;3633:10;3621:11;:23::i;2521:284:8:-;2643:31;2677:28;;;:16;:28;;;;;;;;;2715:83;;;;;;;;;;;;;;;;;2677:28;;2715:83;;;;2677:28;;2715:83;;2677:28;2715:83;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2715:83:8;;;;;;;;;;;;;;;;;;;;;2739:7;:14;;2715:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2755:7;:17;;2715:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2774:7;:23;;;2715:6;:83::i;:::-;;2572:233;2521:284;:::o;16920:977:2:-;17100:7;17450:18;17471:57;17484:7;17493:6;17501:9;17512:15;17471:12;:57::i;:::-;17450:78;;17620:75;17641:10;17653:41;17672:21;17653:18;:41::i;17620:75::-;-1:-1:-1;7846:7:2;7872:22;;;:10;:22;;;;;:31;-1:-1:-1;;;;;7872:31:2;735:10:23;17709:44:2;17705:116;;17776:34;;-1:-1:-1;;;17776:34:2;;735:10:23;17776:34:2;;;1766:74:41;1739:18;;17776:34:2;1620:226:41;17705:116:2;17838:52;17846:7;17855:6;17863:9;17874:15;17838:7;:52::i;:::-;17831:59;16920:977;-1:-1:-1;;;;;;16920:977:2:o;19443:189::-;19520:7;;735:10:23;19539:28:2;;19584:41;19594:10;19606:5;19613:7;19584:41;;;;;;;;;;;;:9;:41::i;:::-;19577:48;19443:189;-1:-1:-1;;;;19443:189:2:o;21036:950::-;21275:7;21294:10;21307:516;21357:5;21376:414;1570:138;21527:10;21563:7;21596:5;21627:16;21637:5;-1:-1:-1;;;;;1121:14:24;819:7;1121:14;;;:7;:14;;;;;:16;;;;;;;;;759:395;21627:16:2;21685:6;;21669:24;;;;;;;:::i;:::-;;;;;;;;21729:6;21719:17;;;;;;21441:317;;;;;;;;;;;;;24264:25:41;;;24320:2;24305:18;;24298:34;;;;24380:4;24368:17;;;;24363:2;24348:18;;24341:45;-1:-1:-1;;;;;24422:55:41;;;;24417:2;24402:18;;24395:83;24509:3;24494:19;;24487:35;24553:3;24538:19;;24531:35;24597:3;24582:19;;24575:35;24251:3;24236:19;;23953:663;21441:317:2;;;;;;;;;;;;;21410:366;;;;;;21376:16;:414::i;:::-;21804:9;21307:36;:516::i;:::-;21294:529;;21839:5;21834:75;;21867:31;;-1:-1:-1;;;21867:31:2;;-1:-1:-1;;;;;1784:55:41;;21867:31:2;;;1766:74:41;1739:18;;21867:31:2;1620:226:41;21834:75:2;21926:53;21936:10;21948:5;21955:7;21964:6;;21926:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21972:6:2;;-1:-1:-1;21926:9:2;;-1:-1:-1;;21926:53:2:i;:::-;21919:60;21036:950;-1:-1:-1;;;;;;;;;21036:950:2:o;20038:303::-;20217:7;;735:10:23;20236:28:2;;20281:53;20291:10;20303:5;20310:7;20319:6;;20281:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20327:6:2;;-1:-1:-1;20281:9:2;;-1:-1:-1;;20281:53:2:i;:::-;20274:60;20038:303;-1:-1:-1;;;;;;;20038:303:2:o;1738:616:11:-;1847:23;:43;;1811:7;;;;2039:10;2048:1;1847:43;2039:10;:::i;:::-;2002:48;;;;;;;;:::i;:::-;;;;;;;;;;2079:11;;2002:48;;-1:-1:-1;2079:11:11;;;;-1:-1:-1;;;2122:13:11;;-1:-1:-1;;;;;2122:13:11;2149:22;;;2145:71;;-1:-1:-1;;;;;2187:18:11;;1738:616;-1:-1:-1;;;;;1738:616:11:o;2145:71::-;2276;2318:28;2336:9;2318:17;:28::i;:::-;2276:23;;:41;:71::i;:::-;-1:-1:-1;;;;;2269:78:11;;1738:616;-1:-1:-1;;;;;;1738:616:11:o;1839:125:7:-;3391:18:2;:16;:18::i;:::-;1926:31:7::1;1942:14;1926:15;:31::i;19702:257:2:-:0;19843:7;;735:10:23;19862:28:2;;19907:45;19917:10;19929:5;19936:7;19945:6;;19907:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19907:9:2;;-1:-1:-1;;;19907:45:2:i;10540:803::-;10723:7;735:10:23;10830:53:2;735:10:23;10871:11:2;10830:30;:53::i;:::-;10825:128;;10906:36;;-1:-1:-1;;;10906:36:2;;-1:-1:-1;;;;;1784:55:41;;10906:36:2;;;1766:74:41;1739:18;;10906:36:2;1620:226:41;10825:128:2;10999:21;11023:31;11032:8;11042:11;11052:1;9197:15:40;11042:11:2;:::i;:::-;11023:31;;:8;:31::i;:::-;10999:55;;11064:22;11089:19;:17;:19::i;:::-;11064:44;;11138:14;11122:13;:30;11118:142;;;11175:74;;-1:-1:-1;;;11175:74:2;;-1:-1:-1;;;;;25158:55:41;;11175:74:2;;;25140::41;25230:18;;;25223:34;;;25273:18;;;25266:34;;;25113:18;;11175:74:2;24938:368:41;11118:142:2;11277:59;11286:7;11295:6;11303:9;11314:11;11327:8;11277;:59::i;:::-;11270:66;10540:803;-1:-1:-1;;;;;;;;10540:803:2:o;5144:557:29:-;5242:13;5269:18;5301:21;5336:15;5365:25;5404:12;5430:27;5533:13;:11;:13::i;:::-;5560:16;:14;:16::i;:::-;5668;;;5652:1;5668:16;;;;;;;;;-1:-1:-1;;;5482:212:29;;;-1:-1:-1;5482:212:29;;-1:-1:-1;5590:13:29;;-1:-1:-1;5625:4:29;;-1:-1:-1;5652:1:29;-1:-1:-1;5668:16:29;-1:-1:-1;5482:212:29;-1:-1:-1;5144:557:29:o;20406:546:2:-;20565:7;20584:10;20597:204;20647:5;20666:102;1424:81;20721:10;20733:7;20742:5;20749:16;20759:5;-1:-1:-1;;;;;1121:14:24;819:7;1121:14;;;:7;:14;;;;;:16;;;;;;;;;759:395;20749:16:2;20693:73;;;;;;25566:25:41;;;;25607:18;;25600:34;;;;25682:4;25670:17;;;25650:18;;;25643:45;-1:-1:-1;;;;;25724:55:41;25704:18;;;25697:83;25796:19;;;25789:35;25538:19;;20693:73:2;25311:519:41;20597:204:2;20584:217;;20817:5;20812:75;;20845:31;;-1:-1:-1;;;20845:31:2;;-1:-1:-1;;;;;1784:55:41;;20845:31:2;;;1766:74:41;1739:18;;20845:31:2;1620:226:41;20812:75:2;20904:41;20914:10;20926:5;20933:7;20904:41;;;;;;;;;;;;:9;:41::i;19169:214::-;19313:7;19339:37;19349:7;19358:9;19369:6;19339:9;:37::i;1504:121:11:-;1560:7;1586:32;:23;:30;:32::i;:::-;-1:-1:-1;;;;;1579:39:11;;;1504:121;:::o;6194:133:9:-;3391:18:2;:16;:18::i;:::-;6292:28:9::1;6308:11;6292:15;:28::i;3864:219:40:-:0;4011:4;3390::9;4038:38:40;3290:111:9;4251:181:40;4370:7;4400:25;1641:18:7;;;1548:118;25648:338:2;25818:6;25863:4;25840:11;:9;:11::i;:::-;-1:-1:-1;;;;;25840:28:2;;25836:91;;25891:25;;-1:-1:-1;;;25891:25:2;;;;;;;;;;;25836:91;-1:-1:-1;;;;25648:338:2;;;;;;;:::o;8396:215:40:-;8540:7;8570:34;8593:10;8570:22;:34::i;23969:252:2:-;3391:18;:16;:18::i;:::-;24087:12:::1;24101:23:::0;24128:6:::1;-1:-1:-1::0;;;;;24128:11:2::1;24147:5;24154:4;;24128:31;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24086:73;;;;24169:45;24194:7;24203:10;24169:24;:45::i;:::-;;24076:145;;23969:252:::0;;;;:::o;5484:299::-;5675:7;5730;5739:6;5747:9;5758:15;5719:55;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;5719:55:2;;;;;;;;;5709:66;;5719:55;5709:66;;;;;5484:299;-1:-1:-1;;;;;5484:299:2:o;1765:282:8:-;1886:31;1920:28;;;:16;:28;;;;;;;;;1958:82;;;;;;;;;;;;;;;;;1920:28;;1958:82;;;;1920:28;;1958:82;;1920:28;1958:82;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1958:82:8;;;;;;;;;;;;;;;;;;;;;1981:7;:14;;1958:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1997:7;:17;;1958:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2016:7;:23;;;1958:5;:82::i;2139:129:7:-;3391:18:2;:16;:18::i;:::-;2228:33:7::1;2245:15;2228:16;:33::i;18936:163:2:-:0;19019:7;19045:47;19055:7;19064:9;19075:16;10368:9;;;;;;;;;-1:-1:-1;10368:9:2;;;10287:97;19075:16;19045:9;:47::i;:::-;19038:54;18936:163;-1:-1:-1;;;18936:163:2:o;2453:150:7:-;3391:18:2;:16;:18::i;:::-;2553:43:7::1;2575:20;2553:21;:43::i;25172:264:2:-:0;25273:6;25318:4;25295:11;:9;:11::i;:::-;-1:-1:-1;;;;;25295:28:2;;25291:91;;25346:25;;-1:-1:-1;;;25346:25:2;;;;;;;;;;;25291:91;-1:-1:-1;;;;25172:264:2;;;;;;;:::o;2992:200:40:-;3130:7;3160:25;3173:11;3160:12;:25::i;2151:294:8:-;2282:31;2316:28;;;:16;:28;;;;;;;;;2354:84;;;;;;;;;;;;;;;;;2316:28;;2354:84;;;;2316:28;;2354:84;;2316:28;2354:84;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2354:84:8;;;;;;;;;;;;;;;;;;;;;2379:7;:14;;2354:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2395:7;:17;;2354:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2414:7;:23;;;2354:7;:84::i;8546:446:2:-;735:10:23;8605:11:2;:9;:11::i;:::-;-1:-1:-1;;;;;8605:27:2;;8601:99;;8655:34;;-1:-1:-1;;;8655:34:2;;735:10:23;8655:34:2;;;1766:74:41;1739:18;;8655:34:2;1620:226:41;8601:99:2;8736:4;8713:11;:9;:11::i;:::-;-1:-1:-1;;;;;8713:28:2;;8709:277;;8757:19;;809:14:23;8779:21:2;;;;;;;:::i;:::-;;;;;;;;8757:43;;8924:52;8961:11;8931:26;:15;:24;:26::i;:::-;:41;8924:52;;8743:243;8709:277;8546:446::o;3532:498:11:-;2544:3;3674:32;;;3670:132;;;3729:62;;-1:-1:-1;;;3729:62:11;;;;;26009:25:41;;;26050:18;;;26043:34;;;25982:18;;3729:62:11;25835:248:41;3670:132:11;3812:26;3841:17;:15;:17::i;:::-;3812:46;-1:-1:-1;3868:77:11;9197:15:40;3906:38:11;3925:18;3906;:38::i;:::-;3868:23;;:77;:28;:77::i;:::-;-1:-1:-1;;3961:62:11;;;26009:25:41;;;26065:2;26050:18;;26043:34;;;3961:62:11;;25982:18:41;3961:62:11;;;;;;;3609:421;;3532:498;:::o;26396:147:2:-;26476:7;26521:13;26515:20;;;;;;;;:::i;:::-;26510:1;:25;;;;;;;26396:147;-1:-1:-1;;26396:147:2:o;26848:383::-;26943:13;26968:26;26997:17;27003:10;26997:5;:17::i;:::-;26968:46;-1:-1:-1;27088:1:2;27063:13;27028:32;26968:46;27028:18;:32::i;:::-;:48;:62;27024:172;;27145:10;27157:12;27171:13;27113:72;;-1:-1:-1;;;27113:72:2;;;;;;;;;;:::i;5653:349:40:-;5887:6;5916:79;5939:10;5951:7;5960:6;5968:9;5979:15;5916:22;:79::i;1985:302:38:-;2109:10;;;-1:-1:-1;;;2109:10:38;;;;;2154:12;;;2137:13;;:29;;;;2133:53;;2175:11;;-1:-1:-1;;;2175:11:38;;;;;;;;;;;2133:53;2200:22;;;;;;;;:11;;;;:22;;;;;;:30;;;;2244:26;;2257:13;;;;2244:26;;-1:-1:-1;;;2244:26:38;;;;;;1985:302::o;6419:321:40:-;6652:81;6677:10;6689:7;6698:6;6706:9;6717:15;6652:24;:81::i;:::-;6419:321;;;;;:::o;4147:204:6:-;4268:14;;4241:60;;;4268:14;;;;26654:34:41;;26724:15;;;26719:2;26704:18;;26697:43;4241:60:6;;26594:18:41;4241:60:6;;;;;;;4311:14;:33;;-1:-1:-1;;4311:33:6;;;;;;;;;;;;4147:204::o;2291:740:9:-;2364:13;2389:26;2418:23;2430:10;2418:11;:23::i;:::-;2389:52;-1:-1:-1;2472:20:9;2456:12;:36;;;;;;;;:::i;:::-;;2452:86;;2515:12;2291:740;-1:-1:-1;;2291:740:9:o;2452:86::-;2548:15;2566:24;;;:12;:24;;;;;;;;2604:9;;:37;;-1:-1:-1;;;2604:37:9;;;;;643:25:41;;;2566:24:9;;-1:-1:-1;;;;;2604:9:9;;:28;;616:18:41;;2604:37:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2600:425;;;-1:-1:-1;2664:20:9;;2291:740;-1:-1:-1;;;2291:740:9:o;2600:425::-;2705:9;;:34;;-1:-1:-1;;;2705:34:9;;;;;643:25:41;;;-1:-1:-1;;;;;2705:9:9;;;;:25;;616:18:41;;2705:34:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2701:324;;;-1:-1:-1;2847:22:9;;2291:740;-1:-1:-1;;;2291:740:9:o;2701:324::-;-1:-1:-1;2992:22:9;;2291:740;-1:-1:-1;;;2291:740:9:o;7129:300:40:-;7334:7;7364:58;7378:7;7387:6;7395:9;7406:15;7364:13;:58::i;:::-;7357:65;7129:300;-1:-1:-1;;;;;7129:300:40:o;22295:255:2:-;22452:7;22478:65;22488:10;22500:7;22509;22518:6;22526:16;10368:9;;;;;;;;;-1:-1:-1;10368:9:2;;;10287:97;22526:16;22478:9;:65::i;4917:176:29:-;4994:7;5020:66;5053:20;:18;:20::i;:::-;5075:10;3555:4:30;3549:11;-1:-1:-1;;;3573:23:30;;3625:4;3616:14;;3609:39;;;;3677:4;3668:14;;3661:34;3733:4;3718:20;;;3353:401;1039:368:31;1145:4;1162:17;1181:24;1211:33;1228:4;1234:9;1211:16;:33::i;:::-;-1:-1:-1;1161:83:31;;-1:-1:-1;1161:83:31;-1:-1:-1;1283:26:31;1274:5;:35;;;;;;;;:::i;:::-;;:58;;;;;1326:6;-1:-1:-1;;;;;1313:19:31;:9;-1:-1:-1;;;;;1313:19:31;;1274:58;1273:127;;;;1349:51;1376:6;1384:4;1390:9;1349:26;:51::i;7824:366:40:-;8097:7;8123:60;8139:10;8151:7;8160;8169:6;8176;8123:15;:60::i;14291:213:35:-;14347:6;14377:16;14369:24;;14365:103;;;14416:41;;-1:-1:-1;;;14416:41:35;;14447:2;14416:41;;;27214:36:41;27266:18;;;27259:34;;;27187:18;;14416:41:35;27033:266:41;14365:103:35;-1:-1:-1;14491:5:35;14291:213::o;9441:606:37:-;9559:24;;9526:7;;;9559:24;9658:1;9652:7;;9648:234;;;9675:11;9695:14;9705:3;9695:9;:14::i;:::-;9689:20;;:3;:20;:::i;:::-;14209:28;14272:20;;;14337:4;14324:18;;9675:34;;-1:-1:-1;14320:28:37;;9733:42;;;;;9727:48;;;;9723:149;;;9802:3;9795:10;;9723:149;;;9850:7;:3;9856:1;9850:7;:::i;:::-;9844:13;;9723:149;9661:221;9648:234;9892:11;9906:53;9925:4;9944:3;9949;9954:4;9906:18;:53::i;:::-;9892:67;-1:-1:-1;9977:8:37;;:63;;9992:41;10006:4;10025:7;10031:1;10025:3;:7;:::i;:::-;14209:28;14272:20;;;14337:4;14324:18;;;14320:28;;14099:265;9992:41;:48;-1:-1:-1;;;9992:48:37;;-1:-1:-1;;;;;9992:48:37;9977:63;;;9988:1;9970:70;9441:606;-1:-1:-1;;;;;;;9441:606:37:o;2721:170:7:-;2816:12;;2801:44;;;2816:12;;;;26654:34:41;;26724:15;;;26719:2;26704:18;;26697:43;2801:44:7;;26594:18:41;2801:44:7;;;;;;;2855:12;:29;;-1:-1:-1;;2855:29:7;;;;;;;;;;;;2721:170::o;28357:1638:2:-;28525:25;;28495:4;;28637:2;28631:8;;28627:50;;;28662:4;28655:11;;;;;28627:50;29295:30;;;-1:-1:-1;;29295:30:2;29289:37;-1:-1:-1;;;;;;29426:33:2;;29436:23;29426:33;29422:75;;29482:4;29475:11;;;;;;29422:75;29574:17;;29622:8;29628:2;29622:3;:8;:::i;:::-;29610:20;;29605:336;29636:3;29632:1;:7;29605:336;;;29661:10;29673:11;29688:36;29708:11;29721:1;29702:21;;;;;;;;:::i;:::-;;;;;;;29688:13;:36::i;:::-;29660:64;;;;29830:5;29825:56;;29862:4;29855:11;;;;;;;;;;29825:56;29925:5;29906:24;;29920:1;29907:9;-1:-1:-1;;;;;29907:14:2;;;29906:24;29894:36;;29646:295;;29641:3;;;;:::i;:::-;;;29605:336;;;;29979:8;-1:-1:-1;;;;;29958:30:2;:9;-1:-1:-1;;;;;29958:30:2;;29951:37;;;;;28357:1638;;;;:::o;4869:320:40:-;5087:7;5117:65;5132:7;5141:6;5149:9;5160:11;5173:8;5117:14;:65::i;6021:126:29:-;6067:13;6099:41;:5;6126:13;6099:26;:41::i;6473:135::-;6522:13;6554:47;:8;6584:16;6554:29;:47::i;1822:223:10:-;1972:7;867:6;1998:40;;-1:-1:-1;;;1998:40:10;;-1:-1:-1;;;;;27928:55:41;;;1998:40:10;;;27910:74:41;28000:18;;;27993:34;;;1998:20:10;;;;;;;27883:18:41;;1998:40:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;10167:206:37:-;10262:24;;10229:7;;10303:8;;:63;;10318:41;10332:4;10351:7;10357:1;10351:3;:7;:::i;10318:41::-;:48;-1:-1:-1;;;10318:48:37;;-1:-1:-1;;;;;10318:48:37;10303:63;;;10314:1;10296:70;10167:206;-1:-1:-1;;;10167:206:37:o;6333:176:9:-;6436:9;;6413:56;;;-1:-1:-1;;;;;6436:9:9;;;28462:34:41;;28532:15;;;28527:2;28512:18;;28505:43;6413:56:9;;28374:18:41;6413:56:9;;;;;;;6479:9;:23;;-1:-1:-1;;;;;;6479:23:9;-1:-1:-1;;;;;6479:23:9;;;;;;;;;;6333:176::o;2017:193:6:-;2101:7;2127:76;2136:34;2159:10;2136:22;:34::i;:::-;2172:30;;;;:18;:30;;;;;;;;2127:8;:76::i;5407:224:22:-;5495:12;5524:7;5519:106;;5547:19;5555:10;5547:7;:19::i;:::-;5519:106;;;-1:-1:-1;5604:10:22;5597:17;;3011:274:7;3092:15;:20;;3111:1;3092:20;3088:88;;3135:30;;-1:-1:-1;;;3135:30:7;;3163:1;3135:30;;;643:25:41;616:18;;3135:30:7;497:177:41;3088:88:7;3206:13;;3190:47;;;3206:13;-1:-1:-1;;;3206:13:7;;;;;28950:34:41;;29020:15;;;29015:2;29000:18;;28993:43;3190:47:7;;28894:18:41;3190:47:7;;;;;;;3247:13;:31;;;;;;-1:-1:-1;;;3247:31:7;-1:-1:-1;;3247:31:7;;;;;;;;;3011:274::o;3415:213::-;3529:18;;3508:62;;;26009:25:41;;;26065:2;26050:18;;26043:34;;;3508:62:7;;25982:18:41;3508:62:7;;;;;;;3580:18;:41;3415:213::o;2689:196:11:-;2762:7;2544:3;2829:26;2845:9;2829:15;:26::i;:::-;2789:37;;-1:-1:-1;;;2789:37:11;;;;;643:25:41;;;-1:-1:-1;;;;;867:6:10;2789:26:11;;;;616:18:41;;2789:37:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:66;;;;:::i;:::-;2788:90;;;;:::i;3419:358:38:-;3553:12;;3483:13;;3553:12;;;;;-1:-1:-1;;;3597:10:38;;;3583:24;;3579:49;;3616:12;;-1:-1:-1;;;3616:12:38;;;;;;;;;;;3579:49;3650:23;;;;;;;;:11;;;;:23;;;;;;;3687:30;;;3731:29;;-1:-1:-1;;3731:29:38;3746:14;;3731:29;;;;;;;;;;-1:-1:-1;3650:23:38;3419:358::o;4169:218:35:-;4226:7;-1:-1:-1;;;;;4249:25:35;;4245:105;;;4297:42;;-1:-1:-1;;;4297:42:35;;4328:3;4297:42;;;27214:36:41;27266:18;;;27259:34;;;27187:18;;4297:42:35;27033:266:41;8050:162:37;8132:7;;8167:38;8175:4;8194:3;8199:5;8167:7;:38::i;:::-;8160:45;;;;8050:162;;;;;;;:::o;3481:588:9:-;3710:6;3728:13;3744:9;;;;;;;;;-1:-1:-1;;;;;3744:9:9;-1:-1:-1;;;;;3744:21:9;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3728:39;-1:-1:-1;3778:12:9;6845:4;6829:22;;-1:-1:-1;;6829:40:9;;;3860:9;;:65;;-1:-1:-1;;;3860:65:9;;3778:45;;-1:-1:-1;;;;;;3860:9:9;;:28;;:65;;3889:7;;3898:6;;3906:9;;3860;;3778:45;;3860:65;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3833:24;;;;:12;:24;;;;;;:92;;;;3935:9;;:67;;-1:-1:-1;;;3935:67:9;;-1:-1:-1;;;;;3935:9:9;;;;:23;;:67;;3959:7;;3968:6;;3976:9;;3833:24;3990:4;;3996:5;;3935:67;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4020:42;4056:5;4038:15;:23;;;;:::i;:::-;4020:17;:42::i;4235:432::-;4486:9;;-1:-1:-1;;;;;4486:9:9;:22;4516:9;4527:7;4536:6;4544:9;4486;6845:4;6829:22;;-1:-1:-1;;6829:40:9;;;4486:103;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;4636:24:9;;;;-1:-1:-1;;4636:12:9;:24;;-1:-1:-1;;4636:24:9;;;4629:31;;;;-1:-1:-1;;4235:432:9:o;5840:1248:2:-;5904:13;6054:22;;;:10;:22;;;;;6110:17;;;-1:-1:-1;;;6110:17:2;;;;;-1:-1:-1;;;6161:17:2;;;6189:76;;;;-1:-1:-1;6232:22:2;;5840:1248;-1:-1:-1;;;;5840:1248:2:o;6189:76::-;6279:16;6275:76;;;-1:-1:-1;6318:22:2;;5840:1248;-1:-1:-1;;;;5840:1248:2:o;6275:76::-;6361:16;7418:22;;;:10;:22;;;;;:32;-1:-1:-1;;;7418:32:2;;;;6361:47;;6423:8;6435:1;6423:13;6419:90;;6459:39;;-1:-1:-1;;;6459:39:2;;;;;643:25:41;;;616:18;;6459:39:2;497:177:41;6419:90:2;6519:34;9197:15:40;6519:34:2;6568:28;;;6564:87;;-1:-1:-1;6619:21:2;;5840:1248;-1:-1:-1;;;;;;5840:1248:2:o;6564:87::-;6661:16;6680:28;6697:10;6680:16;:28::i;:::-;6661:47;;6735:16;6723:8;:28;6719:363;;-1:-1:-1;6774:20:2;;5840:1248;-1:-1:-1;;;;;;;5840:1248:2:o;6719:363::-;6816:26;6831:10;6816:14;:26::i;:::-;6815:27;:58;;;-1:-1:-1;2162:4:5;2214:26;;;:14;:26;;;;;2282:25;;2258:21;;;;;:49;6846:27:2;6815:58;6811:271;;;-1:-1:-1;6896:22:2;;5840:1248;-1:-1:-1;;;;;;;5840:1248:2:o;6811:271::-;8043:7;8069:22;;;:10;:22;;;;;:33;;;;;6966:1;6939:28;6935:147;;-1:-1:-1;6990:23:2;;5840:1248;-1:-1:-1;;;;;;;5840:1248:2:o;6935:147::-;-1:-1:-1;7051:20:2;;5840:1248;-1:-1:-1;;;;;;;5840:1248:2:o;5076:554:9:-;5268:7;5287:18;5308:58;5322:7;5331:6;5339:9;5350:15;5308:13;:58::i;:::-;5377:18;5398:24;;;:12;:24;;;;;;5287:79;;-1:-1:-1;5436:15:9;;5432:164;;5489:9;;:28;;-1:-1:-1;;;5489:28:9;;;;;643:25:41;;;-1:-1:-1;;;;;5489:9:9;;;;:16;;616:18:41;;5489:28:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5561:24:9;;;;:12;:24;;;;;5554:31;-1:-1:-1;;5613:10:9;-1:-1:-1;5076:554:9;;;;;;:::o;3845:262:29:-;3898:7;3929:4;-1:-1:-1;;;;;3938:11:29;3921:28;;:63;;;;;3970:14;3953:13;:31;3921:63;3917:184;;;-1:-1:-1;4007:22:29;;3845:262::o;3917:184::-;4067:23;4204:80;;;2079:95;4204:80;;;34556:25:41;4226:11:29;34597:18:41;;;34590:34;;;;4239:14:29;34640:18:41;;;34633:34;4255:13:29;34683:18:41;;;34676:34;4278:4:29;34726:19:41;;;34719:84;4168:7:29;;34528:19:41;;4204:80:29;;;;;;;;;;;;4194:91;;;;;;4187:98;;4113:179;;2129:766:28;2210:7;2219:12;2233:7;2256:9;:16;2276:2;2256:22;2252:637;;2592:4;2577:20;;2571:27;2641:4;2626:20;;2620:27;2698:4;2683:20;;2677:27;2294:9;2669:36;2739:25;2750:4;2669:36;2571:27;2620;2739:10;:25::i;:::-;2732:32;;;;;;;;;;;2252:637;-1:-1:-1;;2860:16:28;;2811:1;;-1:-1:-1;2815:35:28;;2252:637;2129:766;;;;;:::o;1813:458:31:-;1956:4;1973:12;1987:19;2010:6;-1:-1:-1;;;;;2010:17:31;2084:4;2090:9;2041:60;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;2041:60:31;;;;;;;;;;;;;;;;-1:-1:-1;;;2041:60:31;;;2010:101;;;2041:60;2010:101;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1972:139;;;;2129:7;:42;;;;;2169:2;2152:6;:13;:19;;2129:42;:134;;;;-1:-1:-1;2187:29:31;;-1:-1:-1;;;2228:34:31;2187:29;;;;;;;;;;;;:::i;:::-;:76;;1813:458;-1:-1:-1;;;;;;1813:458:31:o;2429:705:6:-;2624:7;2643:14;2660:61;2676:10;2688:7;2697;2706:6;2714;2660:15;:61::i;:::-;2736:30;;;;:18;:30;;;;;;2643:78;;-1:-1:-1;2736:30:6;;:35;:65;;;;;2775:26;2790:10;2775:14;:26::i;:::-;2732:372;;;2817:23;2853:25;3440:14;;;;;3351:110;2853:25;2843:35;;9197:15:40;2843:35:6;:::i;:::-;2817:61;;2916:28;2933:10;2916:16;:28::i;:::-;2897:16;:47;;;2893:137;;;2969:46;;10804:14:41;10792:27;;10774:46;;2986:10:6;;2969:46;;10762:2:41;10747:18;2969:46:6;;;;;;;2893:137;3044:30;;;;:18;:30;;;;;:49;;-1:-1:-1;;3044:49:6;;;;;;;;;;;;3121:6;2429:705;-1:-1:-1;;;;;;2429:705:6:o;8587:1642:34:-;8635:7;8658:1;8663;8658:6;8654:45;;-1:-1:-1;8687:1:34;;8587:1642;-1:-1:-1;8587:1642:34:o;8654:45::-;9378:14;9412:1;9401:7;9406:1;9401:4;:7::i;:::-;:12;;9395:1;:19;;9378:36;;9873:1;9862:6;9858:1;:10;;;;;:::i;:::-;;9849:6;:19;9848:26;;9839:35;;9922:1;9911:6;9907:1;:10;;;;;:::i;:::-;;9898:6;:19;9897:26;;9888:35;;9971:1;9960:6;9956:1;:10;;;;;:::i;:::-;;9947:6;:19;9946:26;;9937:35;;10020:1;10009:6;10005:1;:10;;;;;:::i;:::-;;9996:6;:19;9995:26;;9986:35;;10069:1;10058:6;10054:1;:10;;;;;:::i;:::-;;10045:6;:19;10044:26;;10035:35;;10118:1;10107:6;10103:1;:10;;;;;:::i;:::-;;10094:6;:19;10093:26;;10084:35;;10167:1;10156:6;10152:1;:10;;;;;:::i;:::-;;10143:6;:19;10142:26;;10133:35;;10189:23;10193:6;10205;10201:1;:10;;;;;:::i;:::-;;10189:3;:23::i;12736:433:37:-;12893:7;12912:230;12925:4;12919:3;:10;12912:230;;;12945:11;12959:23;12972:3;12977:4;12959:12;:23::i;:::-;14209:28;14272:20;;;14337:4;14324:18;;12945:37;;-1:-1:-1;13000:35:37;;;;14320:28;;13000:29;;;:35;12996:136;;;13062:3;13055:10;;12996:136;;;13110:7;:3;13116:1;13110:7;:::i;:::-;13104:13;;12996:136;12931:211;12912:230;;;-1:-1:-1;13158:4:37;12736:433;-1:-1:-1;;;12736:433:37:o;30232:593:2:-;30290:4;;30323:11;;;;30396:2;:6;-1:-1:-1;30396:16:2;;;;;30410:2;30406:1;:6;;;30396:16;30392:417;;;30440:4;;-1:-1:-1;;30446:6:2;;;;-1:-1:-1;30232:593:2;-1:-1:-1;;30232:593:2:o;30392:417::-;30519:1;30514:6;;:2;:6;:16;;;;;30528:2;30524:1;:6;;;30514:16;30510:299;;;30558:4;;-1:-1:-1;;30564:6:2;;;;-1:-1:-1;30232:593:2;-1:-1:-1;;30232:593:2:o;30510:299::-;30637:1;30632:6;;:2;:6;:17;;;;;30646:3;30642:1;:7;;;30632:17;30628:181;;;30677:4;;-1:-1:-1;;30683:6:2;;;;-1:-1:-1;30232:593:2;-1:-1:-1;;30232:593:2:o;30628:181::-;-1:-1:-1;30785:5:2;;;;-1:-1:-1;30232:593:2;-1:-1:-1;;30232:593:2:o;1017:638:8:-;1238:7;1257:18;1278:65;1293:7;1302:6;1310:9;1321:11;1334:8;1278:14;:65::i;:::-;1371:12;:29;;;;;;;-1:-1:-1;1371:29:8;;;;;;;;1441:179;;;;;;;;;;;1371:29;1441:179;;;;;;;;;;;;1580:29;;;;;;1441:179;;;;1410:28;;;:16;:28;;;;;;:210;;;;1257:86;;-1:-1:-1;1441:179:8;;1410:28;;:210;;:28;;:210;;;;:::i;:::-;-1:-1:-1;1410:210:8;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;1410:210:8;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;1410:210:8;;;;;;;;;;;1638:10;1017:638;-1:-1:-1;;;;;;1017:638:8:o;3385:267:25:-;3479:13;1390:66;3508:46;;3504:142;;3577:15;3586:5;3577:8;:15::i;:::-;3570:22;;;;3504:142;3630:5;3623:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7525:178:2;7600:7;7661:22;;;:10;:22;;;;;:35;7626:70;;-1:-1:-1;;;7661:35:2;;;;;-1:-1:-1;;;7626:32:2;;;;:70;:::i;:::-;7619:77;;;7525:178;-1:-1:-1;;7525:178:2:o;2382:104:34:-;2440:7;2470:1;2466;:5;:13;;2478:1;2466:13;;;-1:-1:-1;2474:1:34;;2382:104;-1:-1:-1;2382:104:34:o;5743:516:22:-;5874:17;;:21;5870:383;;6102:10;6096:17;6158:15;6145:10;6141:2;6137:19;6130:44;5870:383;6225:17;;-1:-1:-1;;;6225:17:22;;;;;;;;;;;11513:870:37;11646:11;;11604:7;;;;11672;;11668:709;;11747:25;11775:28;11789:4;11795:7;11801:1;11795:3;:7;:::i;11775:28::-;11747:56;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11747:56:37;;;-1:-1:-1;;;;;11747:56:37;;;;;;;-1:-1:-1;11877:15:37;;;-1:-1:-1;11873:91:37;;;11919:30;;-1:-1:-1;;;11919:30:37;;;;;;;;;;;11873:91;12027:9;;:16;;;;;;;12023:189;;12101:5;12063:28;12077:4;12083:7;12089:1;12083:3;:7;:::i;12063:28::-;:43;;-1:-1:-1;;;;;12063:43:37;;;;-1:-1:-1;;;12063:43:37;;;;;;;;;;;12023:189;;;12155:41;;;;;;;;;;;;;;;-1:-1:-1;;;;;12155:41:37;;;;;;;;;;12145:52;;;;;;;-1:-1:-1;12145:52:37;;;;;;;;;;;;;;-1:-1:-1;;;12145:52:37;;;;;;;;;;12023:189;12233:11;;;;-1:-1:-1;12246:5:37;;-1:-1:-1;12225:27:37;;-1:-1:-1;12225:27:37;11668:709;-1:-1:-1;;12293:41:37;;;;;;;;;;;;;;;-1:-1:-1;;;;;12293:41:37;;;;;;;;;;12283:52;;;;;;;-1:-1:-1;12283:52:37;;;;;;;;;;;;;-1:-1:-1;;;12283:52:37;;;;;;;;;;;;-1:-1:-1;;12327:5:37;12349:17;;1668:276:5;1752:4;1804:26;;;:14;:26;;;;;1912:25;;;;1888:21;;;;:49;;1912:25;1888:49;:::i;:::-;7392:7:2;7418:22;;;:10;:22;;;;;:32;1848:36:5;;-1:-1:-1;;;7418:32:2;;;;2992:200:40;:::i;1848:36:5:-;:89;;;1668:276;-1:-1:-1;;;1668:276:5:o;18182:694:2:-;18365:7;18384:18;18405:57;18418:7;18427:6;18435:9;18446:15;18405:12;:57::i;:::-;18384:78;;18473:276;18507:10;18697:42;18716:22;18697:18;:42::i;:::-;18637:41;18656:21;18637:18;:41::i;:::-;18576:42;18595:22;18576:18;:42::i;:::-;2010:1;1971:34;1977:23;2010:1;1971:34;:::i;:::-;1965:41;;:1;:41;:::i;:::-;1964:47;;;;:::i;:::-;18531:87;:147;:208;18473:20;:276::i;:::-;-1:-1:-1;18760:22:2;;;;:10;:22;;;;;;;:38;;;;-1:-1:-1;;;18760:38:2;;;18813:28;;;;;18771:10;643:25:41;;631:2;616:18;;497:177;5140:1530:28;5266:7;;;6199:66;6186:79;;6182:164;;;-1:-1:-1;6297:1:28;;-1:-1:-1;6301:30:28;;-1:-1:-1;6333:1:28;6281:54;;6182:164;6457:24;;;6440:14;6457:24;;;;;;;;;35041:25:41;;;35114:4;35102:17;;35082:18;;;35075:45;;;;35136:18;;;35129:34;;;35179:18;;;35172:34;;;6457:24:28;;35013:19:41;;6457:24:28;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6457:24:28;;-1:-1:-1;;6457:24:28;;;-1:-1:-1;;;;;;;6495:20:28;;6491:113;;-1:-1:-1;6547:1:28;;-1:-1:-1;6551:29:28;;-1:-1:-1;6547:1:28;;-1:-1:-1;6531:62:28;;6491:113;6622:6;-1:-1:-1;6630:20:28;;-1:-1:-1;6630:20:28;;-1:-1:-1;5140:1530:28;;;;;;;;;:::o;22832:686:2:-;23018:7;23037:74;23058:10;23070:40;23089:20;23070:18;:40::i;23037:74::-;-1:-1:-1;23122:14:2;7418:22;;;:10;:22;;;;;:32;23139:56;;23149:7;;-1:-1:-1;;;7418:32:2;;;;23188:6;23139:9;:56::i;:::-;23122:73;;23205:56;23216:10;23228:7;23237;23246:6;23254;23205:10;:56::i;:::-;23276:6;:13;23293:1;23276:18;23272:216;;23324:7;-1:-1:-1;;;;;23315:54:2;;23333:10;23345:7;23354:6;23362;23315:54;;;;;;;;;:::i;:::-;;;;;;;;23272:216;;;23424:7;-1:-1:-1;;;;;23405:72:2;;23433:10;23445:7;23454:6;23462;23470;23405:72;;;;;;;;;;:::i;:::-;;;;;;;;23505:6;22832:686;-1:-1:-1;;;;;;22832:686:2:o;10699:983:34:-;10751:7;;10835:3;10826:12;;;:16;10822:99;;10872:3;10862:13;;;;10893;10822:99;10947:2;10938:11;;;:15;10934:96;;10983:2;10973:12;;;;11003;10934:96;11056:2;11047:11;;;:15;11043:96;;11092:2;11082:12;;;;11112;11043:96;11165:2;11156:11;;;:15;11152:96;;11201:2;11191:12;;;;11221;11152:96;11274:1;11265:10;;;:14;11261:93;;11309:1;11299:11;;;;11328;11261:93;11380:1;11371:10;;;:14;11367:93;;11415:1;11405:11;;;;11434;11367:93;11486:1;11477:10;;;:14;11473:93;;11521:1;11511:11;;;;11540;11473:93;11592:1;11583:10;;;:14;11579:64;;11627:1;11617:11;11669:6;10699:983;-1:-1:-1;;10699:983:34:o;2557:104::-;2615:7;2645:1;2641;:5;:13;;2653:1;2641:13;;2774:153;2836:7;2909:11;2919:1;2910:5;;;2909:11;:::i;:::-;2899:21;;2900:5;;;2899:21;:::i;11520:1373:2:-;11732:18;11775:71;11788:7;11797:6;11805:9;11832:11;11816:29;;;;;;11775:12;:71::i;:::-;11762:84;;11879:6;:13;11861:7;:14;:31;;:69;;;;11914:9;:16;11896:7;:14;:34;;11861:69;:92;;;-1:-1:-1;11934:14:2;;:19;11861:92;11857:208;;;12006:14;;12022:16;;12040:13;;11976:78;;-1:-1:-1;;;11976:78:2;;;;;12237:25:41;;;;12278:18;;;12271:34;;;;12321:18;;;12314:34;12210:18;;11976:78:2;12035:319:41;11857:208:2;12078:22;;;;:10;:22;;;;;:32;-1:-1:-1;;;12078:32:2;;;;:37;12074:149;;12170:10;12182:17;12188:10;12182:5;:17::i;:::-;12138:74;;-1:-1:-1;;;12138:74:2;;;;;;12209:1;;12138:74;;;:::i;12074:149::-;12233:16;12262:13;:11;:13::i;:::-;12252:23;;;9197:15:40;12252:23:2;;:::i;:::-;12233:42;;12285:16;12304:14;1460:13:7;;;-1:-1:-1;;;1460:13:7;;;;;8766:174:40;12304:14:2;12329:29;12361:22;;;:10;:22;;;;;12393:28;;-1:-1:-1;;;;;;12393:28:2;-1:-1:-1;;;;;12393:28:2;;;;;12285:33;;-1:-1:-1;12452:27:2;12470:8;12452:17;:27::i;:::-;12431:48;;;;;;;-1:-1:-1;;;12431:48:2;;;;;;;;12513:27;12531:8;12513:17;:27::i;:::-;12489:51;;;;;;;-1:-1:-1;;;12489:51:2;;;;;;;;12685:14;;12556:257;;12585:10;;12609:8;;12631:7;;12652:6;;12672:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12714:9:2;12737:8;12759:19;12770:8;12737;12759:19;:::i;:::-;12792:11;12556:257;;;;;;;;;;;;;;:::i;:::-;;;;;;;;11752:1141;;;11520:1373;;;;;;;:::o;2078:405:25:-;2137:13;2162:11;2176:16;2187:4;2176:10;:16::i;:::-;2300:14;;;2311:2;2300:14;;;;;;;;;2162:30;;-1:-1:-1;2280:17:25;;2300:14;;;;;;;;;-1:-1:-1;;;2390:16:25;;;-1:-1:-1;2435:4:25;2426:14;;2419:28;;;;-1:-1:-1;2390:16:25;2078:405::o;2454:797:5:-;2648:33;2684:26;;;:14;:26;;;;;;;;-1:-1:-1;;;;;2725:30:5;;;;:21;;;:30;;;;;;;;;2721:100;;;2778:32;;-1:-1:-1;;;2778:32:5;;-1:-1:-1;;;;;1784:55:41;;2778:32:5;;;1766:74:41;1739:18;;2778:32:5;1620:226:41;2721:100:5;-1:-1:-1;;;;;2830:30:5;;;;;;:21;;;:30;;;;;:37;;-1:-1:-1;;2830:37:5;2863:4;2830:37;;;2882:34;;;2878:367;;2961:6;2932:12;:25;;;:35;;;;;;;:::i;:::-;;;;-1:-1:-1;2878:367:5;;-1:-1:-1;2878:367:5;;-1:-1:-1;;2988:30:5;;;;2984:261;;3059:6;3034:12;:21;;;:31;;;;;;;:::i;2984:261::-;-1:-1:-1;;3086:34:5;;;;3082:163;;3165:6;3136:12;:25;;;:35;;;;;;;:::i;3082:163::-;3209:25;;-1:-1:-1;;;3209:25:5;;;;;;;;;;;3082:163;2638:613;2454:797;;;;;:::o;15291:213:35:-;15347:6;15377:16;15369:24;;15365:103;;;15416:41;;-1:-1:-1;;;15416:41:35;;15447:2;15416:41;;;27214:36:41;27266:18;;;27259:34;;;27187:18;;15416:41:35;27033:266:41;2555:245:25;2616:7;2688:4;2652:40;;2715:2;2706:11;;2702:69;;;2740:20;;-1:-1:-1;;;2740:20:25;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::i;14:286:41:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:41;;209:43;;199:71;;266:1;263;256:12;679:180;738:6;791:2;779:9;770:7;766:23;762:32;759:52;;;807:1;804;797:12;759:52;-1:-1:-1;830:23:41;;679:180;-1:-1:-1;679:180:41:o;864:250::-;949:1;959:113;973:6;970:1;967:13;959:113;;;1049:11;;;1043:18;1030:11;;;1023:39;995:2;988:10;959:113;;;-1:-1:-1;;1106:1:41;1088:16;;1081:27;864:250::o;1119:271::-;1161:3;1199:5;1193:12;1226:6;1221:3;1214:19;1242:76;1311:6;1304:4;1299:3;1295:14;1288:4;1281:5;1277:16;1242:76;:::i;:::-;1372:2;1351:15;-1:-1:-1;;1347:29:41;1338:39;;;;1379:4;1334:50;;1119:271;-1:-1:-1;;1119:271:41:o;1395:220::-;1544:2;1533:9;1526:21;1507:4;1564:45;1605:2;1594:9;1590:18;1582:6;1564:45;:::i;1851:154::-;-1:-1:-1;;;;;1930:5:41;1926:54;1919:5;1916:65;1906:93;;1995:1;1992;1985:12;2010:127;2071:10;2066:3;2062:20;2059:1;2052:31;2102:4;2099:1;2092:15;2126:4;2123:1;2116:15;2142:275;2213:2;2207:9;2278:2;2259:13;;-1:-1:-1;;2255:27:41;2243:40;;2313:18;2298:34;;2334:22;;;2295:62;2292:88;;;2360:18;;:::i;:::-;2396:2;2389:22;2142:275;;-1:-1:-1;2142:275:41:o;2422:406::-;2486:5;2520:18;2512:6;2509:30;2506:56;;;2542:18;;:::i;:::-;2580:57;2625:2;2604:15;;-1:-1:-1;;2600:29:41;2631:4;2596:40;2580:57;:::i;:::-;2571:66;;2660:6;2653:5;2646:21;2700:3;2691:6;2686:3;2682:16;2679:25;2676:45;;;2717:1;2714;2707:12;2676:45;2766:6;2761:3;2754:4;2747:5;2743:16;2730:43;2820:1;2813:4;2804:6;2797:5;2793:18;2789:29;2782:40;2422:406;;;;;:::o;2833:220::-;2875:5;2928:3;2921:4;2913:6;2909:17;2905:27;2895:55;;2946:1;2943;2936:12;2895:55;2968:79;3043:3;3034:6;3021:20;3014:4;3006:6;3002:17;2968:79;:::i;3058:665::-;3153:6;3161;3169;3177;3230:3;3218:9;3209:7;3205:23;3201:33;3198:53;;;3247:1;3244;3237:12;3198:53;3286:9;3273:23;3305:31;3330:5;3305:31;:::i;:::-;3355:5;-1:-1:-1;3412:2:41;3397:18;;3384:32;3425:33;3384:32;3425:33;:::i;:::-;3477:7;-1:-1:-1;3531:2:41;3516:18;;3503:32;;-1:-1:-1;3586:2:41;3571:18;;3558:32;3613:18;3602:30;;3599:50;;;3645:1;3642;3635:12;3599:50;3668:49;3709:7;3700:6;3689:9;3685:22;3668:49;:::i;:::-;3658:59;;;3058:665;;;;;;;:::o;3935:183::-;3995:4;4028:18;4020:6;4017:30;4014:56;;;4050:18;;:::i;:::-;-1:-1:-1;4095:1:41;4091:14;4107:4;4087:25;;3935:183::o;4123:737::-;4177:5;4230:3;4223:4;4215:6;4211:17;4207:27;4197:55;;4248:1;4245;4238:12;4197:55;4284:6;4271:20;4310:4;4334:60;4350:43;4390:2;4350:43;:::i;:::-;4334:60;:::i;:::-;4428:15;;;4514:1;4510:10;;;;4498:23;;4494:32;;;4459:12;;;;4538:15;;;4535:35;;;4566:1;4563;4556:12;4535:35;4602:2;4594:6;4590:15;4614:217;4630:6;4625:3;4622:15;4614:217;;;4710:3;4697:17;4727:31;4752:5;4727:31;:::i;:::-;4771:18;;4809:12;;;;4647;;4614:217;;;-1:-1:-1;4849:5:41;4123:737;-1:-1:-1;;;;;;4123:737:41:o;4865:662::-;4919:5;4972:3;4965:4;4957:6;4953:17;4949:27;4939:55;;4990:1;4987;4980:12;4939:55;5026:6;5013:20;5052:4;5076:60;5092:43;5132:2;5092:43;:::i;5076:60::-;5170:15;;;5256:1;5252:10;;;;5240:23;;5236:32;;;5201:12;;;;5280:15;;;5277:35;;;5308:1;5305;5298:12;5277:35;5344:2;5336:6;5332:15;5356:142;5372:6;5367:3;5364:15;5356:142;;;5438:17;;5426:30;;5476:12;;;;5389;;5356:142;;5532:886;5584:5;5637:3;5630:4;5622:6;5618:17;5614:27;5604:55;;5655:1;5652;5645:12;5604:55;5691:6;5678:20;5717:4;5741:60;5757:43;5797:2;5757:43;:::i;5741:60::-;5835:15;;;5921:1;5917:10;;;;5905:23;;5901:32;;;5866:12;;;;5945:15;;;5942:35;;;5973:1;5970;5963:12;5942:35;6009:2;6001:6;5997:15;6021:368;6037:6;6032:3;6029:15;6021:368;;;6123:3;6110:17;6159:18;6146:11;6143:35;6140:125;;;6219:1;6248:2;6244;6237:14;6140:125;6290:56;6342:3;6337:2;6323:11;6315:6;6311:24;6307:33;6290:56;:::i;:::-;6278:69;;-1:-1:-1;6367:12:41;;;;6054;;6021:368;;6423:897;6593:6;6601;6609;6617;6670:3;6658:9;6649:7;6645:23;6641:33;6638:53;;;6687:1;6684;6677:12;6638:53;6727:9;6714:23;6756:18;6797:2;6789:6;6786:14;6783:34;;;6813:1;6810;6803:12;6783:34;6836:61;6889:7;6880:6;6869:9;6865:22;6836:61;:::i;:::-;6826:71;;6950:2;6939:9;6935:18;6922:32;6906:48;;6979:2;6969:8;6966:16;6963:36;;;6995:1;6992;6985:12;6963:36;7018:63;7073:7;7062:8;7051:9;7047:24;7018:63;:::i;:::-;7008:73;;7134:2;7123:9;7119:18;7106:32;7090:48;;7163:2;7153:8;7150:16;7147:36;;;7179:1;7176;7169:12;7147:36;;7202:61;7255:7;7244:8;7233:9;7229:24;7202:61;:::i;:::-;6423:897;;;;-1:-1:-1;7192:71:41;;7310:2;7295:18;7282:32;;-1:-1:-1;;;6423:897:41:o;7325:484::-;7378:3;7416:5;7410:12;7443:6;7438:3;7431:19;7469:4;7498:2;7493:3;7489:12;7482:19;;7535:2;7528:5;7524:14;7556:1;7566:218;7580:6;7577:1;7574:13;7566:218;;;7645:13;;-1:-1:-1;;;;;7641:62:41;7629:75;;7724:12;;;;7759:15;;;;7602:1;7595:9;7566:218;;;-1:-1:-1;7800:3:41;;7325:484;-1:-1:-1;;;;;7325:484:41:o;7814:435::-;7867:3;7905:5;7899:12;7932:6;7927:3;7920:19;7958:4;7987:2;7982:3;7978:12;7971:19;;8024:2;8017:5;8013:14;8045:1;8055:169;8069:6;8066:1;8063:13;8055:169;;;8130:13;;8118:26;;8164:12;;;;8199:15;;;;8091:1;8084:9;8055:169;;8254:591;8305:3;8336;8368:5;8362:12;8395:6;8390:3;8383:19;8421:4;8450:2;8445:3;8441:12;8434:19;;8506:2;8496:6;8493:1;8489:14;8482:5;8478:26;8474:35;8543:2;8536:5;8532:14;8564:1;8574:245;8588:6;8585:1;8582:13;8574:245;;;8675:2;8671:7;8663:5;8657:4;8653:16;8649:30;8644:3;8637:43;8701:38;8734:4;8725:6;8719:13;8701:38;:::i;:::-;8797:12;;;;8693:46;-1:-1:-1;8762:15:41;;;;8610:1;8603:9;8574:245;;;-1:-1:-1;8835:4:41;;8254:591;-1:-1:-1;;;;;;;8254:591:41:o;8850:758::-;9231:3;9220:9;9213:22;9194:4;9258:57;9310:3;9299:9;9295:19;9287:6;9258:57;:::i;:::-;9363:9;9355:6;9351:22;9346:2;9335:9;9331:18;9324:50;9397:44;9434:6;9426;9397:44;:::i;:::-;9383:58;;9489:9;9481:6;9477:22;9472:2;9461:9;9457:18;9450:50;9517:42;9552:6;9544;9517:42;:::i;:::-;9509:50;;;9595:6;9590:2;9579:9;9575:18;9568:34;8850:758;;;;;;;:::o;9613:830::-;10022:6;10011:9;10004:25;10065:3;10060:2;10049:9;10045:18;10038:31;9985:4;10092:57;10144:3;10133:9;10129:19;10121:6;10092:57;:::i;:::-;10197:9;10189:6;10185:22;10180:2;10169:9;10165:18;10158:50;10231:44;10268:6;10260;10231:44;:::i;:::-;10217:58;;10323:9;10315:6;10311:22;10306:2;10295:9;10291:18;10284:50;10351:42;10386:6;10378;10351:42;:::i;:::-;10343:50;;;10430:6;10424:3;10413:9;10409:19;10402:35;9613:830;;;;;;;;:::o;10831:280::-;10889:6;10942:2;10930:9;10921:7;10917:23;10913:32;10910:52;;;10958:1;10955;10948:12;10910:52;10997:9;10984:23;11047:14;11040:5;11036:26;11029:5;11026:37;11016:65;;11077:1;11074;11067:12;11116:127;11177:10;11172:3;11168:20;11165:1;11158:31;11208:4;11205:1;11198:15;11232:4;11229:1;11222:15;11248:241;11333:1;11326:5;11323:12;11313:143;;11378:10;11373:3;11369:20;11366:1;11359:31;11413:4;11410:1;11403:15;11441:4;11438:1;11431:15;11313:143;11465:18;;11248:241::o;11494:216::-;11644:2;11629:18;;11656:48;11633:9;11686:6;11656:48;:::i;11715:315::-;11783:6;11791;11844:2;11832:9;11823:7;11819:23;11815:32;11812:52;;;11860:1;11857;11850:12;11812:52;11896:9;11883:23;11873:33;;11956:2;11945:9;11941:18;11928:32;11969:31;11994:5;11969:31;:::i;:::-;12019:5;12009:15;;;11715:315;;;;;:::o;12359:156::-;12425:20;;12485:4;12474:16;;12464:27;;12454:55;;12505:1;12502;12495:12;12454:55;12359:156;;;:::o;12520:250::-;12586:6;12594;12647:2;12635:9;12626:7;12622:23;12618:32;12615:52;;;12663:1;12660;12653:12;12615:52;12699:9;12686:23;12676:33;;12728:36;12760:2;12749:9;12745:18;12728:36;:::i;:::-;12718:46;;12520:250;;;;;:::o;12775:348::-;12827:8;12837:6;12891:3;12884:4;12876:6;12872:17;12868:27;12858:55;;12909:1;12906;12899:12;12858:55;-1:-1:-1;12932:20:41;;12975:18;12964:30;;12961:50;;;13007:1;13004;12997:12;12961:50;13044:4;13036:6;13032:17;13020:29;;13096:3;13089:4;13080:6;13072;13068:19;13064:30;13061:39;13058:59;;;13113:1;13110;13103:12;13058:59;12775:348;;;;;:::o;13128:1104::-;13260:6;13268;13276;13284;13292;13300;13308;13361:3;13349:9;13340:7;13336:23;13332:33;13329:53;;;13378:1;13375;13368:12;13329:53;13414:9;13401:23;13391:33;;13443:36;13475:2;13464:9;13460:18;13443:36;:::i;:::-;13433:46;;13529:2;13518:9;13514:18;13501:32;13542:31;13567:5;13542:31;:::i;:::-;13592:5;-1:-1:-1;13648:2:41;13633:18;;13620:32;13671:18;13701:14;;;13698:34;;;13728:1;13725;13718:12;13698:34;13767:59;13818:7;13809:6;13798:9;13794:22;13767:59;:::i;:::-;13845:8;;-1:-1:-1;13741:85:41;-1:-1:-1;13933:3:41;13918:19;;13905:33;;-1:-1:-1;13950:16:41;;;13947:36;;;13979:1;13976;13969:12;13947:36;14002:51;14045:7;14034:8;14023:9;14019:24;14002:51;:::i;:::-;13992:61;;14106:3;14095:9;14091:19;14078:33;14062:49;;14136:2;14126:8;14123:16;14120:36;;;14152:1;14149;14142:12;14120:36;;14175:51;14218:7;14207:8;14196:9;14192:24;14175:51;:::i;:::-;14165:61;;;13128:1104;;;;;;;;;;:::o;14237:769::-;14342:6;14350;14358;14366;14374;14427:3;14415:9;14406:7;14402:23;14398:33;14395:53;;;14444:1;14441;14434:12;14395:53;14480:9;14467:23;14457:33;;14509:36;14541:2;14530:9;14526:18;14509:36;:::i;:::-;14499:46;;14596:2;14585:9;14581:18;14568:32;14619:18;14660:2;14652:6;14649:14;14646:34;;;14676:1;14673;14666:12;14646:34;14715:59;14766:7;14757:6;14746:9;14742:22;14715:59;:::i;:::-;14793:8;;-1:-1:-1;14689:85:41;-1:-1:-1;14881:2:41;14866:18;;14853:32;;-1:-1:-1;14897:16:41;;;14894:36;;;14926:1;14923;14916:12;14894:36;;14949:51;14992:7;14981:8;14970:9;14966:24;14949:51;:::i;:::-;14939:61;;;14237:769;;;;;;;;:::o;15011:549::-;15098:6;15106;15114;15122;15175:2;15163:9;15154:7;15150:23;15146:32;15143:52;;;15191:1;15188;15181:12;15143:52;15227:9;15214:23;15204:33;;15256:36;15288:2;15277:9;15273:18;15256:36;:::i;:::-;15246:46;;15343:2;15332:9;15328:18;15315:32;15370:18;15362:6;15359:30;15356:50;;;15402:1;15399;15392:12;15356:50;15441:59;15492:7;15483:6;15472:9;15468:22;15441:59;:::i;:::-;15011:549;;;;-1:-1:-1;15519:8:41;-1:-1:-1;;;;15011:549:41:o;15565:1157::-;15745:6;15753;15761;15769;15822:3;15810:9;15801:7;15797:23;15793:33;15790:53;;;15839:1;15836;15829:12;15790:53;15879:9;15866:23;15908:18;15949:2;15941:6;15938:14;15935:34;;;15965:1;15962;15955:12;15935:34;15988:61;16041:7;16032:6;16021:9;16017:22;15988:61;:::i;:::-;15978:71;;16102:2;16091:9;16087:18;16074:32;16058:48;;16131:2;16121:8;16118:16;16115:36;;;16147:1;16144;16137:12;16115:36;16170:63;16225:7;16214:8;16203:9;16199:24;16170:63;:::i;:::-;16160:73;;16286:2;16275:9;16271:18;16258:32;16242:48;;16315:2;16305:8;16302:16;16299:36;;;16331:1;16328;16321:12;16299:36;16354:61;16407:7;16396:8;16385:9;16381:24;16354:61;:::i;:::-;16344:71;;16468:2;16457:9;16453:18;16440:32;16424:48;;16497:2;16487:8;16484:16;16481:36;;;16513:1;16510;16503:12;16481:36;-1:-1:-1;16536:24:41;;16591:4;16583:13;;16579:27;-1:-1:-1;16569:55:41;;16620:1;16617;16610:12;16569:55;16643:73;16708:7;16703:2;16690:16;16685:2;16681;16677:11;16643:73;:::i;16727:247::-;16786:6;16839:2;16827:9;16818:7;16814:23;16810:32;16807:52;;;16855:1;16852;16845:12;16807:52;16894:9;16881:23;16913:31;16938:5;16913:31;:::i;16979:943::-;17385:3;17380;17376:13;17368:6;17364:26;17353:9;17346:45;17427:3;17422:2;17411:9;17407:18;17400:31;17327:4;17454:46;17495:3;17484:9;17480:19;17472:6;17454:46;:::i;:::-;17548:9;17540:6;17536:22;17531:2;17520:9;17516:18;17509:50;17582:33;17608:6;17600;17582:33;:::i;:::-;17568:47;;17651:6;17646:2;17635:9;17631:18;17624:34;-1:-1:-1;;;;;17699:6:41;17695:55;17689:3;17678:9;17674:19;17667:84;17788:6;17782:3;17771:9;17767:19;17760:35;17844:9;17836:6;17832:22;17826:3;17815:9;17811:19;17804:51;17872:44;17909:6;17901;17872:44;:::i;:::-;17864:52;16979:943;-1:-1:-1;;;;;;;;;;16979:943:41:o;17927:594::-;18020:6;18028;18036;18044;18097:3;18085:9;18076:7;18072:23;18068:33;18065:53;;;18114:1;18111;18104:12;18065:53;18150:9;18137:23;18127:33;;18179:36;18211:2;18200:9;18196:18;18179:36;:::i;:::-;18169:46;;18265:2;18254:9;18250:18;18237:32;18278:31;18303:5;18278:31;:::i;:::-;18328:5;-1:-1:-1;18384:2:41;18369:18;;18356:32;18411:18;18400:30;;18397:50;;;18443:1;18440;18433:12;18526:523;18612:6;18620;18628;18681:2;18669:9;18660:7;18656:23;18652:32;18649:52;;;18697:1;18694;18687:12;18649:52;18736:9;18723:23;18755:31;18780:5;18755:31;:::i;:::-;18805:5;-1:-1:-1;18857:2:41;18842:18;;18829:32;;-1:-1:-1;18912:2:41;18897:18;;18884:32;18939:18;18928:30;;18925:50;;;18971:1;18968;18961:12;18925:50;18994:49;19035:7;19026:6;19015:9;19011:22;18994:49;:::i;:::-;18984:59;;;18526:523;;;;;:::o;19333:1071::-;19487:6;19495;19503;19511;19519;19572:3;19560:9;19551:7;19547:23;19543:33;19540:53;;;19589:1;19586;19579:12;19540:53;19628:9;19615:23;19647:31;19672:5;19647:31;:::i;:::-;19697:5;-1:-1:-1;19754:2:41;19739:18;;19726:32;19767:33;19726:32;19767:33;:::i;:::-;19819:7;-1:-1:-1;19877:2:41;19862:18;;19849:32;19900:18;19930:14;;;19927:34;;;19957:1;19954;19947:12;19927:34;19980:61;20033:7;20024:6;20013:9;20009:22;19980:61;:::i;:::-;19970:71;;20094:2;20083:9;20079:18;20066:32;20050:48;;20123:2;20113:8;20110:16;20107:36;;;20139:1;20136;20129:12;20107:36;20162:63;20217:7;20206:8;20195:9;20191:24;20162:63;:::i;:::-;20152:73;;20278:3;20267:9;20263:19;20250:33;20234:49;;20308:2;20298:8;20295:16;20292:36;;;20324:1;20321;20314:12;20409:613;20497:6;20505;20513;20521;20574:2;20562:9;20553:7;20549:23;20545:32;20542:52;;;20590:1;20587;20580:12;20542:52;20629:9;20616:23;20648:31;20673:5;20648:31;:::i;:::-;20698:5;-1:-1:-1;20750:2:41;20735:18;;20722:32;;-1:-1:-1;20805:2:41;20790:18;;20777:32;20832:18;20821:30;;20818:50;;;20864:1;20861;20854:12;21027:276;21085:6;21138:2;21126:9;21117:7;21113:23;21109:32;21106:52;;;21154:1;21151;21144:12;21106:52;21193:9;21180:23;21243:10;21236:5;21232:22;21225:5;21222:33;21212:61;;21269:1;21266;21259:12;21308:315;21376:6;21384;21437:2;21425:9;21416:7;21412:23;21408:32;21405:52;;;21453:1;21450;21443:12;21405:52;21492:9;21479:23;21511:31;21536:5;21511:31;:::i;:::-;21561:5;21613:2;21598:18;;;;21585:32;;-1:-1:-1;;;21308:315:41:o;21628:734::-;21732:6;21740;21748;21756;21764;21817:3;21805:9;21796:7;21792:23;21788:33;21785:53;;;21834:1;21831;21824:12;21785:53;21873:9;21860:23;21892:31;21917:5;21892:31;:::i;:::-;21942:5;-1:-1:-1;21999:2:41;21984:18;;21971:32;22012:33;21971:32;22012:33;:::i;:::-;22064:7;-1:-1:-1;22118:2:41;22103:18;;22090:32;;-1:-1:-1;22169:2:41;22154:18;;22141:32;;-1:-1:-1;22224:3:41;22209:19;;22196:33;22252:18;22241:30;;22238:50;;;22284:1;22281;22274:12;22238:50;22307:49;22348:7;22339:6;22328:9;22324:22;22307:49;:::i;22615:380::-;22694:1;22690:12;;;;22737;;;22758:61;;22812:4;22804:6;22800:17;22790:27;;22758:61;22865:2;22857:6;22854:14;22834:18;22831:38;22828:161;;22911:10;22906:3;22902:20;22899:1;22892:31;22946:4;22943:1;22936:15;22974:4;22971:1;22964:15;22828:161;;22615:380;;;:::o;23273:127::-;23334:10;23329:3;23325:20;23322:1;23315:31;23365:4;23362:1;23355:15;23389:4;23386:1;23379:15;23405:127;23466:10;23461:3;23457:20;23454:1;23447:31;23497:4;23494:1;23487:15;23521:4;23518:1;23511:15;23537:135;23576:3;23597:17;;;23594:43;;23617:18;;:::i;:::-;-1:-1:-1;23664:1:41;23653:13;;23537:135::o;23677:271::-;23860:6;23852;23847:3;23834:33;23816:3;23886:16;;23911:13;;;23886:16;23677:271;-1:-1:-1;23677:271:41:o;24621:128::-;24688:9;;;24709:11;;;24706:37;;;24723:18;;:::i;24754:179::-;24822:14;24869:10;;;24857;;;24853:27;;24892:12;;;24889:38;;;24907:18;;:::i;:::-;24889:38;24754:179;;;;:::o;26088:358::-;26306:25;;;26294:2;26279:18;;26340:57;26393:2;26378:18;;26370:6;26340:57;:::i;:::-;26433:6;26428:2;26417:9;26413:18;26406:34;26088:358;;;;;;:::o;26751:277::-;26818:6;26871:2;26859:9;26850:7;26846:23;26842:32;26839:52;;;26887:1;26884;26877:12;26839:52;26919:9;26913:16;26972:5;26965:13;26958:21;26951:5;26948:32;26938:60;;26994:1;26991;26984:12;27304:125;27369:9;;;27390:10;;;27387:36;;;27403:18;;:::i;28038:184::-;28108:6;28161:2;28149:9;28140:7;28136:23;28132:32;28129:52;;;28177:1;28174;28167:12;28129:52;-1:-1:-1;28200:16:41;;28038:184;-1:-1:-1;28038:184:41:o;29047:168::-;29120:9;;;29151;;29168:15;;;29162:22;;29148:37;29138:71;;29189:18;;:::i;29220:127::-;29281:10;29276:3;29272:20;29269:1;29262:31;29312:4;29309:1;29302:15;29336:4;29333:1;29326:15;29352:217;29392:1;29418;29408:132;;29462:10;29457:3;29453:20;29450:1;29443:31;29497:4;29494:1;29487:15;29525:4;29522:1;29515:15;29408:132;-1:-1:-1;29554:9:41;;29352:217::o;29846:838::-;30263:3;30252:9;30245:22;30226:4;30290:57;30342:3;30331:9;30327:19;30319:6;30290:57;:::i;:::-;30395:9;30387:6;30383:22;30378:2;30367:9;30363:18;30356:50;30429:44;30466:6;30458;30429:44;:::i;:::-;30415:58;;30521:9;30513:6;30509:22;30504:2;30493:9;30489:18;30482:50;30549:42;30584:6;30576;30549:42;:::i;:::-;30622:2;30607:18;;30600:34;;;;-1:-1:-1;;30665:3:41;30650:19;30643:35;30541:50;29846:838;-1:-1:-1;;;29846:838:41:o;30878:910::-;31323:3;31312:9;31305:22;31286:4;31350:57;31402:3;31391:9;31387:19;31379:6;31350:57;:::i;:::-;31455:9;31447:6;31443:22;31438:2;31427:9;31423:18;31416:50;31489:44;31526:6;31518;31489:44;:::i;:::-;31475:58;;31581:9;31573:6;31569:22;31564:2;31553:9;31549:18;31542:50;31609:42;31644:6;31636;31609:42;:::i;:::-;31682:2;31667:18;;31660:34;;;;-1:-1:-1;;31725:3:41;31710:19;;31703:35;;;;31769:3;31754:19;;;31747:35;31601:50;30878:910;-1:-1:-1;;;30878:910:41:o;31793:289::-;31968:6;31957:9;31950:25;32011:2;32006;31995:9;31991:18;31984:30;31931:4;32031:45;32072:2;32061:9;32057:18;32049:6;32031:45;:::i;32087:287::-;32216:3;32254:6;32248:13;32270:66;32329:6;32324:3;32317:4;32309:6;32305:17;32270:66;:::i;:::-;32352:16;;;;;32087:287;-1:-1:-1;;32087:287:41:o;32379:176::-;32446:14;32480:10;;;32492;;;32476:27;;32515:11;;;32512:37;;;32529:18;;:::i;32761:148::-;32849:4;32828:12;;;32842;;;32824:31;;32867:13;;32864:39;;;32883:18;;:::i;32914:422::-;33003:1;33046:5;33003:1;33060:270;33081:7;33071:8;33068:21;33060:270;;;33140:4;33136:1;33132:6;33128:17;33122:4;33119:27;33116:53;;;33149:18;;:::i;:::-;33199:7;33189:8;33185:22;33182:55;;;33219:16;;;;33182:55;33298:22;;;;33258:15;;;;33060:270;;;33064:3;32914:422;;;;;:::o;33341:806::-;33390:5;33420:8;33410:80;;-1:-1:-1;33461:1:41;33475:5;;33410:80;33509:4;33499:76;;-1:-1:-1;33546:1:41;33560:5;;33499:76;33591:4;33609:1;33604:59;;;;33677:1;33672:130;;;;33584:218;;33604:59;33634:1;33625:10;;33648:5;;;33672:130;33709:3;33699:8;33696:17;33693:43;;;33716:18;;:::i;:::-;-1:-1:-1;;33772:1:41;33758:16;;33787:5;;33584:218;;33886:2;33876:8;33873:16;33867:3;33861:4;33858:13;33854:36;33848:2;33838:8;33835:16;33830:2;33824:4;33821:12;33817:35;33814:77;33811:159;;;-1:-1:-1;33923:19:41;;;33955:5;;33811:159;34002:34;34027:8;34021:4;34002:34;:::i;:::-;34072:6;34068:1;34064:6;34060:19;34051:7;34048:32;34045:58;;;34083:18;;:::i;:::-;34121:20;;33341:806;-1:-1:-1;;;33341:806:41:o;34152:140::-;34210:5;34239:47;34280:4;34270:8;34266:19;34260:4;34239:47;:::i;35217:442::-;35446:6;35435:9;35428:25;35501:4;35493:6;35489:17;35484:2;35473:9;35469:18;35462:45;35543:6;35538:2;35527:9;35523:18;35516:34;35586:3;35581:2;35570:9;35566:18;35559:31;35409:4;35607:46;35648:3;35637:9;35633:19;35625:6;35607:46;:::i;35664:604::-;35939:6;35928:9;35921:25;35994:4;35986:6;35982:17;35977:2;35966:9;35962:18;35955:45;36036:6;36031:2;36020:9;36016:18;36009:34;36079:3;36074:2;36063:9;36059:18;36052:31;35902:4;36106:46;36147:3;36136:9;36132:19;36124:6;36106:46;:::i;:::-;36201:9;36193:6;36189:22;36183:3;36172:9;36168:19;36161:51;36229:33;36255:6;36247;36229:33;:::i;36273:1887::-;36847:4;36876:3;36906:6;36895:9;36888:25;36932:2;-1:-1:-1;;;;;36974:6:41;36970:55;36965:2;36954:9;36950:18;36943:83;37062:2;37057;37046:9;37042:18;37035:30;37088:56;37140:2;37129:9;37125:18;37117:6;37088:56;:::i;:::-;37074:70;;37192:9;37184:6;37180:22;37175:2;37164:9;37160:18;37153:50;37226:44;37263:6;37255;37226:44;:::i;:::-;37212:58;;37319:9;37311:6;37307:22;37301:3;37290:9;37286:19;37279:51;37350:6;37385;37379:13;37416:6;37408;37401:22;37451:2;37443:6;37439:15;37432:22;;37510:2;37500:6;37497:1;37493:14;37485:6;37481:27;37477:36;37548:2;37540:6;37536:15;37569:1;37579:252;37593:6;37590:1;37587:13;37579:252;;;37683:2;37679:7;37670:6;37662;37658:19;37654:33;37649:3;37642:46;37711:40;37744:6;37735;37729:13;37711:40;:::i;:::-;37809:12;;;;37701:50;-1:-1:-1;37774:15:41;;;;37615:1;37608:9;37579:252;;;37583:3;;37880:9;37872:6;37868:22;37862:3;37851:9;37847:19;37840:51;37914:42;37949:6;37941;37914:42;:::i;:::-;37900:56;;;;;;37993:6;37987:3;37976:9;37972:19;37965:35;38037:6;38031:3;38020:9;38016:19;38009:35;38093:9;38085:6;38081:22;38075:3;38064:9;38060:19;38053:51;38121:33;38147:6;38139;38121:33;:::i;:::-;38113:41;36273:1887;-1:-1:-1;;;;;;;;;;;;36273:1887:41:o;38561:544::-;38662:2;38657:3;38654:11;38651:448;;;38698:1;38723:5;38719:2;38712:17;38768:4;38764:2;38754:19;38838:2;38826:10;38822:19;38819:1;38815:27;38809:4;38805:38;38874:4;38862:10;38859:20;38856:47;;;-1:-1:-1;38897:4:41;38856:47;38952:2;38947:3;38943:12;38940:1;38936:20;38930:4;38926:31;38916:41;;39007:82;39025:2;39018:5;39015:13;39007:82;;;39070:17;;;39051:1;39040:13;39007:82;;39281:1348;39405:3;39399:10;39432:18;39424:6;39421:30;39418:56;;;39454:18;;:::i;:::-;39483:96;39572:6;39532:38;39564:4;39558:11;39532:38;:::i;:::-;39526:4;39483:96;:::i;:::-;39634:4;;39698:2;39687:14;;39715:1;39710:662;;;;40416:1;40433:6;40430:89;;;-1:-1:-1;40485:19:41;;;40479:26;40430:89;-1:-1:-1;;39238:1:41;39234:11;;;39230:24;39226:29;39216:40;39262:1;39258:11;;;39213:57;40532:81;;39680:943;;39710:662;38508:1;38501:14;;;38545:4;38532:18;;-1:-1:-1;;39746:20:41;;;39863:236;39877:7;39874:1;39871:14;39863:236;;;39966:19;;;39960:26;39945:42;;40058:27;;;;40026:1;40014:14;;;;39893:19;;39863:236;;;39867:3;40127:6;40118:7;40115:19;40112:201;;;40188:19;;;40182:26;-1:-1:-1;;40271:1:41;40267:14;;;40283:3;40263:24;40259:37;40255:42;40240:58;40225:74;;40112:201;-1:-1:-1;;;;;40359:1:41;40343:14;;;40339:22;40326:36;;-1:-1:-1;39281:1348:41:o
Swarm Source
none
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.