Overview
POL Balance
0 POL
POL Value
$0.00More Info
Private Name Tags
ContractCreator
Sponsored
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60e06040 | 40830476 | 559 days ago | IN | 0 POL | 3.61316861 |
Latest 25 internal transactions (View All)
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
TokenVotingSetup
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 2000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; import {IDAO} from "../../../../core/dao/IDAO.sol"; import {DAO} from "../../../../core/dao/DAO.sol"; import {PermissionLib} from "../../../../core/permission/PermissionLib.sol"; import {PluginSetup, IPluginSetup} from "../../../../framework/plugin/setup/PluginSetup.sol"; import {GovernanceERC20} from "../../../../token/ERC20/governance/GovernanceERC20.sol"; import {GovernanceWrappedERC20} from "../../../../token/ERC20/governance/GovernanceWrappedERC20.sol"; import {IGovernanceWrappedERC20} from "../../../../token/ERC20/governance/IGovernanceWrappedERC20.sol"; import {MajorityVotingBase} from "../MajorityVotingBase.sol"; import {TokenVoting} from "./TokenVoting.sol"; /// @title TokenVotingSetup /// @author Aragon Association - 2022-2023 /// @notice The setup contract of the `TokenVoting` plugin. contract TokenVotingSetup is PluginSetup { using Address for address; using Clones for address; using ERC165Checker for address; /// @notice The address of the `TokenVoting` base contract. TokenVoting private immutable tokenVotingBase; /// @notice The address of the `GovernanceERC20` base contract. address public immutable governanceERC20Base; /// @notice The address of the `GovernanceWrappedERC20` base contract. address public immutable governanceWrappedERC20Base; /// @notice The token settings struct. /// @param addr The token address. If this is `address(0)`, a new `GovernanceERC20` token is deployed. If not, the existing token is wrapped as an `GovernanceWrappedERC20`. /// @param name The token name. This parameter is only relevant if the token address is `address(0)`. /// @param name The token symbol. This parameter is only relevant if the token address is `address(0)`. struct TokenSettings { address addr; string name; string symbol; } /// @notice Thrown if token address is passed which is not a token. /// @param token The token address error TokenNotContract(address token); /// @notice Thrown if token address is not ERC20. /// @param token The token address error TokenNotERC20(address token); /// @notice Thrown if passed helpers array is of worng length. /// @param length The array length of passed helpers. error WrongHelpersArrayLength(uint256 length); /// @notice The contract constructor, that deployes the bases. constructor() { governanceERC20Base = address( new GovernanceERC20( IDAO(address(0)), "", "", GovernanceERC20.MintSettings(new address[](0), new uint256[](0)) ) ); governanceWrappedERC20Base = address( new GovernanceWrappedERC20(IERC20Upgradeable(address(0)), "", "") ); tokenVotingBase = new TokenVoting(); } /// @inheritdoc IPluginSetup function prepareInstallation( address _dao, bytes calldata _data ) external returns (address plugin, PreparedSetupData memory preparedSetupData) { // Decode `_data` to extract the params needed for deploying and initializing `TokenVoting` plugin, // and the required helpers ( MajorityVotingBase.VotingSettings memory votingSettings, TokenSettings memory tokenSettings, // only used for GovernanceERC20(token is not passed) GovernanceERC20.MintSettings memory mintSettings ) = abi.decode( _data, (MajorityVotingBase.VotingSettings, TokenSettings, GovernanceERC20.MintSettings) ); address token = tokenSettings.addr; // Prepare helpers. address[] memory helpers = new address[](1); if (token != address(0)) { if (!token.isContract()) { revert TokenNotContract(token); } if (!_isERC20(token)) { revert TokenNotERC20(token); } // [0] = IERC20Upgradeable, [1] = IVotesUpgradeable, [2] = IGovernanceWrappedERC20 bool[] memory supportedIds = _getTokenInterfaceIds(token); if ( // If token supports none of them // it's simply ERC20 which gets checked by _isERC20 // Currently, not a satisfiable check. (!supportedIds[0] && !supportedIds[1] && !supportedIds[2]) || // If token supports IERC20, but neither // IVotes nor IGovernanceWrappedERC20, it needs wrapping. (supportedIds[0] && !supportedIds[1] && !supportedIds[2]) ) { token = governanceWrappedERC20Base.clone(); // User already has a token. We need to wrap it in // GovernanceWrappedERC20 in order to make the token // include governance functionality. GovernanceWrappedERC20(token).initialize( IERC20Upgradeable(tokenSettings.addr), tokenSettings.name, tokenSettings.symbol ); } } else { // Clone a `GovernanceERC20`. token = governanceERC20Base.clone(); GovernanceERC20(token).initialize( IDAO(_dao), tokenSettings.name, tokenSettings.symbol, mintSettings ); } helpers[0] = token; // Prepare and deploy plugin proxy. plugin = createERC1967Proxy( address(tokenVotingBase), abi.encodeWithSelector(TokenVoting.initialize.selector, _dao, votingSettings, token) ); // Prepare permissions PermissionLib.MultiTargetPermission[] memory permissions = new PermissionLib.MultiTargetPermission[]( tokenSettings.addr != address(0) ? 3 : 4 ); // Set plugin permissions to be granted. // Grant the list of prmissions of the plugin to the DAO. permissions[0] = PermissionLib.MultiTargetPermission( PermissionLib.Operation.Grant, plugin, _dao, PermissionLib.NO_CONDITION, tokenVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() ); permissions[1] = PermissionLib.MultiTargetPermission( PermissionLib.Operation.Grant, plugin, _dao, PermissionLib.NO_CONDITION, tokenVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() ); // Grant `EXECUTE_PERMISSION` of the DAO to the plugin. permissions[2] = PermissionLib.MultiTargetPermission( PermissionLib.Operation.Grant, _dao, plugin, PermissionLib.NO_CONDITION, DAO(payable(_dao)).EXECUTE_PERMISSION_ID() ); if (tokenSettings.addr == address(0)) { bytes32 tokenMintPermission = GovernanceERC20(token).MINT_PERMISSION_ID(); permissions[3] = PermissionLib.MultiTargetPermission( PermissionLib.Operation.Grant, token, _dao, PermissionLib.NO_CONDITION, tokenMintPermission ); } preparedSetupData.helpers = helpers; preparedSetupData.permissions = permissions; } /// @inheritdoc IPluginSetup function prepareUninstallation( address _dao, SetupPayload calldata _payload ) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) { // Prepare permissions. uint256 helperLength = _payload.currentHelpers.length; if (helperLength != 1) { revert WrongHelpersArrayLength({length: helperLength}); } // token can be either GovernanceERC20, GovernanceWrappedERC20, or IVotesUpgradeable, which // does not follow the GovernanceERC20 and GovernanceWrappedERC20 standard. address token = _payload.currentHelpers[0]; bool[] memory supportedIds = _getTokenInterfaceIds(token); bool isGovernanceERC20 = supportedIds[0] && supportedIds[1] && !supportedIds[2]; permissions = new PermissionLib.MultiTargetPermission[](isGovernanceERC20 ? 4 : 3); // Set permissions to be Revoked. permissions[0] = PermissionLib.MultiTargetPermission( PermissionLib.Operation.Revoke, _payload.plugin, _dao, PermissionLib.NO_CONDITION, tokenVotingBase.UPDATE_VOTING_SETTINGS_PERMISSION_ID() ); permissions[1] = PermissionLib.MultiTargetPermission( PermissionLib.Operation.Revoke, _payload.plugin, _dao, PermissionLib.NO_CONDITION, tokenVotingBase.UPGRADE_PLUGIN_PERMISSION_ID() ); permissions[2] = PermissionLib.MultiTargetPermission( PermissionLib.Operation.Revoke, _dao, _payload.plugin, PermissionLib.NO_CONDITION, DAO(payable(_dao)).EXECUTE_PERMISSION_ID() ); // Revocation of permission is necessary only if the deployed token is GovernanceERC20, // as GovernanceWrapped does not possess this permission. Only return the following // if it's type of GovernanceERC20, otherwise revoking this permission wouldn't have any effect. if (isGovernanceERC20) { permissions[3] = PermissionLib.MultiTargetPermission( PermissionLib.Operation.Revoke, token, _dao, PermissionLib.NO_CONDITION, GovernanceERC20(token).MINT_PERMISSION_ID() ); } } /// @inheritdoc IPluginSetup function implementation() external view virtual override returns (address) { return address(tokenVotingBase); } /// @notice Retrieves the interface identifiers supported by the token contract. /// @dev It is crucial to verify if the provided token address represents a valid contract before using the below. /// @param token The token address function _getTokenInterfaceIds(address token) private view returns (bool[] memory) { bytes4[] memory interfaceIds = new bytes4[](3); interfaceIds[0] = type(IERC20Upgradeable).interfaceId; interfaceIds[1] = type(IVotesUpgradeable).interfaceId; interfaceIds[2] = type(IGovernanceWrappedERC20).interfaceId; return token.getSupportedInterfaces(interfaceIds); } /// @notice Unsatisfiably determines if the contract is an ERC20 token. /// @dev It's important to first check whether token is a contract prior to this call. /// @param token The token address function _isERC20(address token) private view returns (bool) { (bool success, bytes memory data) = token.staticcall( abi.encodeWithSelector(IERC20Upgradeable.balanceOf.selector, address(this)) ); return success && data.length == 0x20; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol) pragma solidity ^0.8.0; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * * _Available since v4.5._ */ interface IVotesUpgradeable { /** * @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 votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @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 the end of a past block (`blockNumber`). */ function getPastVotes(address account, uint256 blockNumber) external view returns (uint256); /** * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`). * * 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 blockNumber) 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 v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { /** * @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 v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20Upgradeable.sol"; import "./extensions/IERC20MetadataUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[45] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/draft-ERC20Permit.sol) pragma solidity ^0.8.0; import "./draft-IERC20PermitUpgradeable.sol"; import "../ERC20Upgradeable.sol"; import "../../../utils/cryptography/ECDSAUpgradeable.sol"; import "../../../utils/cryptography/EIP712Upgradeable.sol"; import "../../../utils/CountersUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * _Available since v3.4._ * * @custom:storage-size 51 */ abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable { using CountersUpgradeable for CountersUpgradeable.Counter; mapping(address => CountersUpgradeable.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private constant _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. * However, to ensure consistency with the upgradeable transpiler, we will continue * to reserve a slot. * @custom:oz-renamed-from _PERMIT_TYPEHASH */ // solhint-disable-next-line var-name-mixedcase bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ function __ERC20Permit_init(string memory name) internal onlyInitializing { __EIP712_init_unchained(name, "1"); } function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {} /** * @dev See {IERC20Permit-permit}. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSAUpgradeable.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { CountersUpgradeable.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.1) (token/ERC20/extensions/ERC20Votes.sol) pragma solidity ^0.8.0; import "./draft-ERC20PermitUpgradeable.sol"; import "../../../utils/math/MathUpgradeable.sol"; import "../../../governance/utils/IVotesUpgradeable.sol"; import "../../../utils/math/SafeCastUpgradeable.sol"; import "../../../utils/cryptography/ECDSAUpgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's, * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1. * * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module. * * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting * power can be queried through the public accessors {getVotes} and {getPastVotes}. * * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. * * _Available since v4.2._ */ abstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable { function __ERC20Votes_init() internal onlyInitializing { } function __ERC20Votes_init_unchained() internal onlyInitializing { } struct Checkpoint { uint32 fromBlock; uint224 votes; } bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); mapping(address => address) private _delegates; mapping(address => Checkpoint[]) private _checkpoints; Checkpoint[] private _totalSupplyCheckpoints; /** * @dev Get the `pos`-th checkpoint for `account`. */ function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) { return _checkpoints[account][pos]; } /** * @dev Get number of checkpoints for `account`. */ function numCheckpoints(address account) public view virtual returns (uint32) { return SafeCastUpgradeable.toUint32(_checkpoints[account].length); } /** * @dev Get the address `account` is currently delegating to. */ function delegates(address account) public view virtual override returns (address) { return _delegates[account]; } /** * @dev Gets the current votes balance for `account` */ function getVotes(address account) public view virtual override returns (uint256) { uint256 pos = _checkpoints[account].length; return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes; } /** * @dev Retrieve the number of votes for `account` at the end of `blockNumber`. * * Requirements: * * - `blockNumber` must have been already mined */ function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) { require(blockNumber < block.number, "ERC20Votes: block not yet mined"); return _checkpointsLookup(_checkpoints[account], blockNumber); } /** * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. * It is but NOT the sum of all the delegated votes! * * Requirements: * * - `blockNumber` must have been already mined */ function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) { require(blockNumber < block.number, "ERC20Votes: block not yet mined"); return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber); } /** * @dev Lookup a value in a list of (sorted) checkpoints. */ function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) { // We run a binary search to look for the earliest checkpoint taken after `blockNumber`. // // Initially we check if the block is recent to narrow the search range. // During the loop, the index of the wanted checkpoint remains in the range [low-1, high). // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant. // - If the middle checkpoint is after `blockNumber`, we look in [low, mid) // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high) // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not // out of bounds (in which case we're looking too far in the past and the result is 0). // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out // the same. uint256 length = ckpts.length; uint256 low = 0; uint256 high = length; if (length > 5) { uint256 mid = length - MathUpgradeable.sqrt(length); if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) { high = mid; } else { low = mid + 1; } } while (low < high) { uint256 mid = MathUpgradeable.average(low, high); if (_unsafeAccess(ckpts, mid).fromBlock > blockNumber) { high = mid; } else { low = mid + 1; } } return high == 0 ? 0 : _unsafeAccess(ckpts, high - 1).votes; } /** * @dev Delegate votes from the sender to `delegatee`. */ function delegate(address delegatee) public virtual override { _delegate(_msgSender(), delegatee); } /** * @dev Delegates votes from signer to `delegatee` */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= expiry, "ERC20Votes: signature expired"); address signer = ECDSAUpgradeable.recover( _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s ); require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce"); _delegate(signer, delegatee); } /** * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1). */ function _maxSupply() internal view virtual returns (uint224) { return type(uint224).max; } /** * @dev Snapshots the totalSupply after it has been increased. */ function _mint(address account, uint256 amount) internal virtual override { super._mint(account, amount); require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes"); _writeCheckpoint(_totalSupplyCheckpoints, _add, amount); } /** * @dev Snapshots the totalSupply after it has been decreased. */ function _burn(address account, uint256 amount) internal virtual override { super._burn(account, amount); _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount); } /** * @dev Move voting power when tokens are transferred. * * Emits a {IVotes-DelegateVotesChanged} event. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._afterTokenTransfer(from, to, amount); _moveVotingPower(delegates(from), delegates(to), amount); } /** * @dev Change delegation for `delegator` to `delegatee`. * * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}. */ function _delegate(address delegator, address delegatee) internal virtual { address currentDelegate = delegates(delegator); uint256 delegatorBalance = balanceOf(delegator); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveVotingPower(currentDelegate, delegatee, delegatorBalance); } function _moveVotingPower( address src, address dst, uint256 amount ) private { if (src != dst && amount > 0) { if (src != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount); emit DelegateVotesChanged(src, oldWeight, newWeight); } if (dst != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount); emit DelegateVotesChanged(dst, oldWeight, newWeight); } } } function _writeCheckpoint( Checkpoint[] storage ckpts, function(uint256, uint256) view returns (uint256) op, uint256 delta ) private returns (uint256 oldWeight, uint256 newWeight) { uint256 pos = ckpts.length; Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1); oldWeight = oldCkpt.votes; newWeight = op(oldWeight, delta); if (pos > 0 && oldCkpt.fromBlock == block.number) { _unsafeAccess(ckpts, pos - 1).votes = SafeCastUpgradeable.toUint224(newWeight); } else { ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)})); } } function _add(uint256 a, uint256 b) private pure returns (uint256) { return a + b; } function _subtract(uint256 a, uint256 b) private pure returns (uint256) { return a - b; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess(Checkpoint[] storage ckpts, uint256 pos) private pure returns (Checkpoint storage result) { assembly { mstore(0, ckpts.slot) result.slot := add(keccak256(0, 0x20), pos) } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[47] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/ERC20Wrapper.sol) pragma solidity ^0.8.0; import "../ERC20Upgradeable.sol"; import "../utils/SafeERC20Upgradeable.sol"; import "../../../proxy/utils/Initializable.sol"; /** * @dev Extension of the ERC20 token contract to support token wrapping. * * Users can deposit and withdraw "underlying tokens" and receive a matching number of "wrapped tokens". This is useful * in conjunction with other modules. For example, combining this wrapping mechanism with {ERC20Votes} will allow the * wrapping of an existing "basic" ERC20 into a governance token. * * _Available since v4.2._ * * @custom:storage-size 51 */ abstract contract ERC20WrapperUpgradeable is Initializable, ERC20Upgradeable { IERC20Upgradeable public underlying; function __ERC20Wrapper_init(IERC20Upgradeable underlyingToken) internal onlyInitializing { __ERC20Wrapper_init_unchained(underlyingToken); } function __ERC20Wrapper_init_unchained(IERC20Upgradeable underlyingToken) internal onlyInitializing { underlying = underlyingToken; } /** * @dev See {ERC20-decimals}. */ function decimals() public view virtual override returns (uint8) { try IERC20MetadataUpgradeable(address(underlying)).decimals() returns (uint8 value) { return value; } catch { return super.decimals(); } } /** * @dev Allow a user to deposit underlying tokens and mint the corresponding number of wrapped tokens. */ function depositFor(address account, uint256 amount) public virtual returns (bool) { SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount); _mint(account, amount); return true; } /** * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens. */ function withdrawTo(address account, uint256 amount) public virtual returns (bool) { _burn(_msgSender(), amount); SafeERC20Upgradeable.safeTransfer(underlying, account, amount); return true; } /** * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal * function that can be exposed with access control if desired. */ function _recover(address account) internal virtual returns (uint256) { uint256 value = underlying.balanceOf(address(this)) - totalSupply(); _mint(account, value); return value; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; import "../extensions/draft-IERC20PermitUpgradeable.sol"; import "../../../utils/AddressUpgradeable.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using AddressUpgradeable for address; function safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20Upgradeable token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20Upgradeable token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20PermitUpgradeable token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721ReceiverUpgradeable { /** * @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 v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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://diligence.consensys.net/posts/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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @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, it is bubbled up by this * function (like regular Solidity function calls). * * 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. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @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`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library CountersUpgradeable { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../StringsUpgradeable.sol"; /** * @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 ECDSAUpgradeable { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode 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 {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] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { 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); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode 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 {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); 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] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); 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. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // 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); } // 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); } return (signer, RecoverError.NoError); } /** * @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) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.0; import "./ECDSAUpgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic 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 their contracts 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]. * * _Available since v3.4._ * * @custom:storage-size 52 */ abstract contract EIP712Upgradeable is Initializable { /* solhint-disable var-name-mixedcase */ bytes32 private _HASHED_NAME; bytes32 private _HASHED_VERSION; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); /* solhint-enable var-name-mixedcase */ /** * @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]. */ function __EIP712_init(string memory name, string memory version) internal onlyInitializing { __EIP712_init_unchained(name, version); } function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash()); } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, 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 ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev The hash of the name parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712NameHash() internal virtual view returns (bytes32) { return _HASHED_NAME; } /** * @dev The hash of the version parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712VersionHash() internal virtual view returns (bytes32) { return _HASHED_VERSION; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol) pragma solidity ^0.8.0; import "./ERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Storage based implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165StorageUpgradeable is Initializable, ERC165Upgradeable { function __ERC165Storage_init() internal onlyInitializing { } function __ERC165Storage_init_unchained() internal onlyInitializing { } /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.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); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @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 IERC165Upgradeable { /** * @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 v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @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 up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (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; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 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. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); 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 (rounding == Rounding.Up && 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 down. * * 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 + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * 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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * 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 + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * 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 10, 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 + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @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. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCastUpgradeable { /** * @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 * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); 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 * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); 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 * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); 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 * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); 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 * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); 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 * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); 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 * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); 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 * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); 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 * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); 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 * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); 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 * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); 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 * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); 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 * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); 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 * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); 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 * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); 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 * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); 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 * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); 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 * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); 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 * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); 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 * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); 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 * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); 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 * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); 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 * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); 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 * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); 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 * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); 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 * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); 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 * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); 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 * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); 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 * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); 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 * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); 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 * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); 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 * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @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 * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @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 * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @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 * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @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 * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @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 * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @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 * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @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: * ``` * 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(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 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 } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.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), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.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) { 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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC1271 standard signature validation method for * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. * * _Available since v4.1._ */ 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 v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/Clones.sol) pragma solidity ^0.8.0; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for * deploying minimal proxy contracts, also known as "clones". * * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies * > a minimal bytecode implementation that delegates all calls to a known, fixed address. * * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the * deterministic method. * * _Available since v3.4._ */ library Clones { /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create opcode, which should never revert. */ function clone(address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create(0, 0x09, 0x37) } require(instance != address(0), "ERC1167: create failed"); } /** * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`. * * This function uses the create2 opcode and a `salt` to deterministically deploy * the clone. Using the same `implementation` and `salt` multiple time will revert, since * the clones cannot be deployed twice at the same address. */ function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes // of the `implementation` address with the bytecode before the address. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000)) // Packs the remaining 17 bytes of `implementation` with the bytecode after the address. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3)) instance := create2(0, 0x09, 0x37, salt) } require(instance != address(0), "ERC1167: create2 failed"); } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(add(ptr, 0x38), deployer) mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff) mstore(add(ptr, 0x14), implementation) mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73) mstore(add(ptr, 0x58), salt) mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37)) predicted := keccak256(add(ptr, 0x43), 0x55) } } /** * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}. */ function predictDeterministicAddress(address implementation, bytes32 salt) internal view returns (address predicted) { return predictDeterministicAddress(implementation, salt, address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.0; import "../Proxy.sol"; import "./ERC1967Upgrade.sol"; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. * * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * function call, and allows initializing the storage of the proxy like a Solidity constructor. */ constructor(address _logic, bytes memory _data) payable { _upgradeToAndCall(_logic, _data, false); } /** * @dev Returns the current implementation address. */ function _implementation() internal view virtual override returns (address impl) { return ERC1967Upgrade._getImplementation(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967Upgrade { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overridden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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://diligence.consensys.net/posts/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.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @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, it is bubbled up by this * function (like regular Solidity function calls). * * 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. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @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`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./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); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface. */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. * * _Available since v3.4._ */ function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * Interface identification is specified in ERC-165. */ function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @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 v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @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: * ``` * 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(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 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 } } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165StorageUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts/interfaces/IERC1271.sol"; import {PermissionManager} from "../permission/PermissionManager.sol"; import {CallbackHandler} from "../utils/CallbackHandler.sol"; import {hasBit, flipBit} from "../utils/BitMap.sol"; import {IEIP4824} from "./IEIP4824.sol"; import {IDAO} from "./IDAO.sol"; /// @title DAO /// @author Aragon Association - 2021-2023 /// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface. /// @dev Public API of the Aragon DAO framework. contract DAO is IEIP4824, Initializable, IERC1271, ERC165StorageUpgradeable, IDAO, UUPSUpgradeable, PermissionManager, CallbackHandler { using SafeERC20Upgradeable for IERC20Upgradeable; using AddressUpgradeable for address; /// @notice The ID of the permission required to call the `execute` function. bytes32 public constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION"); /// @notice The ID of the permission required to call the `_authorizeUpgrade` function. bytes32 public constant UPGRADE_DAO_PERMISSION_ID = keccak256("UPGRADE_DAO_PERMISSION"); /// @notice The ID of the permission required to call the `setMetadata` function. bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION"); /// @notice The ID of the permission required to call the `setTrustedForwarder` function. bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID = keccak256("SET_TRUSTED_FORWARDER_PERMISSION"); /// @notice The ID of the permission required to call the `setSignatureValidator` function. bytes32 public constant SET_SIGNATURE_VALIDATOR_PERMISSION_ID = keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION"); /// @notice The ID of the permission required to call the `registerStandardCallback` function. bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID = keccak256("REGISTER_STANDARD_CALLBACK_PERMISSION"); /// @notice The internal constant storing the maximal action array length. uint256 internal constant MAX_ACTIONS = 256; /// @notice The [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. IERC1271 public signatureValidator; /// @notice The address of the trusted forwarder verifying meta transactions. address private trustedForwarder; /// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO uri. string private _daoURI; /// @notice Thrown if the action array length is larger than `MAX_ACTIONS`. error TooManyActions(); /// @notice Thrown if action execution has failed. /// @param index The index of the action in the action array that failed. error ActionFailed(uint256 index); /// @notice Thrown if an action has insufficent gas left. error InsufficientGas(); /// @notice Thrown if the deposit amount is zero. error ZeroAmount(); /// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens. /// @param expected The expected native token amount. /// @param actual The actual native token amount deposited. error NativeTokenDepositAmountMismatch(uint256 expected, uint256 actual); /// @notice Emitted when a new DAO uri is set. /// @param daoURI The new uri. event NewURI(string daoURI); /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. constructor() { _disableInitializers(); } /// @notice Initializes the DAO by /// - registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID /// - setting the trusted forwarder for meta transactions /// - giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup). /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). /// @param _metadata IPFS hash that points to all the metadata (logo, description, tags, etc.) of a DAO. /// @param _initialOwner The initial owner of the DAO having the `ROOT_PERMISSION_ID` permission. /// @param _trustedForwarder The trusted forwarder responsible for verifying meta transactions. function initialize( bytes calldata _metadata, address _initialOwner, address _trustedForwarder, string calldata daoURI_ ) external initializer { _registerInterface(type(IDAO).interfaceId); _registerInterface(type(IERC1271).interfaceId); _registerInterface(type(IEIP4824).interfaceId); _registerTokenInterfaces(); _setMetadata(_metadata); _setTrustedForwarder(_trustedForwarder); _setDaoURI(daoURI_); __PermissionManager_init(_initialOwner); } /// @inheritdoc PermissionManager function isPermissionRestrictedForAnyAddr( bytes32 _permissionId ) internal pure override returns (bool) { return _permissionId == EXECUTE_PERMISSION_ID || _permissionId == UPGRADE_DAO_PERMISSION_ID || _permissionId == SET_METADATA_PERMISSION_ID || _permissionId == SET_TRUSTED_FORWARDER_PERMISSION_ID || _permissionId == SET_SIGNATURE_VALIDATOR_PERMISSION_ID || _permissionId == REGISTER_STANDARD_CALLBACK_PERMISSION_ID; } /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). /// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission. function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {} /// @inheritdoc IDAO function setTrustedForwarder( address _newTrustedForwarder ) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) { _setTrustedForwarder(_newTrustedForwarder); } /// @inheritdoc IDAO function getTrustedForwarder() external view virtual override returns (address) { return trustedForwarder; } /// @inheritdoc IDAO function hasPermission( address _where, address _who, bytes32 _permissionId, bytes memory _data ) external view override returns (bool) { return isGranted(_where, _who, _permissionId, _data); } /// @inheritdoc IDAO function setMetadata( bytes calldata _metadata ) external override auth(SET_METADATA_PERMISSION_ID) { _setMetadata(_metadata); } /// @inheritdoc IDAO function execute( bytes32 _callId, Action[] calldata _actions, uint256 _allowFailureMap ) external override auth(EXECUTE_PERMISSION_ID) returns (bytes[] memory execResults, uint256 failureMap) { if (_actions.length > MAX_ACTIONS) { revert TooManyActions(); } execResults = new bytes[](_actions.length); uint256 gasBefore; uint256 gasAfter; for (uint256 i = 0; i < _actions.length; ) { gasBefore = gasleft(); (bool success, bytes memory result) = _actions[i].to.call{value: _actions[i].value}( _actions[i].data ); gasAfter = gasleft(); // Check if failure is allowed if (!hasBit(_allowFailureMap, uint8(i))) { // Check if the call failed. if (!success) { revert ActionFailed(i); } } else { // Check if the call failed. if (!success) { // Make sure that the action call did not fail because 63/64 of `gasleft()` was insufficient to execute the external call `.to.call` (see https://eips.ethereum.org/EIPS/eip-150). // In specific scenarios, i.e. proposal execution where the last action in the action array is allowed to fail, the account calling `execute` could force-fail this action by setting a gas limit // where 63/64 is insufficient causing the `.to.call` to fail, but where the remaining 1/64 gas are sufficient to successfully finish the `execute` call. if (gasAfter < gasBefore / 64) { revert InsufficientGas(); } // Store that this action failed. failureMap = flipBit(failureMap, uint8(i)); } } execResults[i] = result; unchecked { ++i; } } emit Executed({ actor: msg.sender, callId: _callId, actions: _actions, failureMap: failureMap, execResults: execResults }); } /// @inheritdoc IDAO function deposit( address _token, uint256 _amount, string calldata _reference ) external payable override { if (_amount == 0) revert ZeroAmount(); if (_token == address(0)) { if (msg.value != _amount) revert NativeTokenDepositAmountMismatch({expected: _amount, actual: msg.value}); } else { if (msg.value != 0) revert NativeTokenDepositAmountMismatch({expected: 0, actual: msg.value}); IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount); } emit Deposited(msg.sender, _token, _amount, _reference); } /// @inheritdoc IDAO function setSignatureValidator( address _signatureValidator ) external override auth(SET_SIGNATURE_VALIDATOR_PERMISSION_ID) { signatureValidator = IERC1271(_signatureValidator); emit SignatureValidatorSet({signatureValidator: _signatureValidator}); } /// @inheritdoc IDAO function isValidSignature( bytes32 _hash, bytes memory _signature ) external view override(IDAO, IERC1271) returns (bytes4) { if (address(signatureValidator) == address(0)) { // Return the invalid magic number return bytes4(0); } // Forward the call to the set signature validator contract return signatureValidator.isValidSignature(_hash, _signature); } /// @notice Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method. /// @dev This call is bound by the gas limitations for `send`/`transfer` calls introduced by EIP-2929. /// Gas cost increases in future hard forks might break this function. As an alternative, EIP-2930-type transactions using access lists can be employed. receive() external payable { emit NativeTokenDeposited(msg.sender, msg.value); } /// @notice Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard. /// @param _input An alias being equivalent to `msg.data`. This feature of the fallback function was introduced with the [solidity compiler version 0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6) /// @return The magic number registered for the function selector triggering the fallback. fallback(bytes calldata _input) external returns (bytes memory) { bytes4 magicNumber = _handleCallback(msg.sig, _input); return abi.encode(magicNumber); } /// @notice Emits the MetadataSet event if new metadata is set. /// @param _metadata Hash of the IPFS metadata object. function _setMetadata(bytes calldata _metadata) internal { emit MetadataSet(_metadata); } /// @notice Sets the trusted forwarder on the DAO and emits the associated event. /// @param _trustedForwarder The trusted forwarder address. function _setTrustedForwarder(address _trustedForwarder) internal { trustedForwarder = _trustedForwarder; emit TrustedForwarderSet(_trustedForwarder); } /// @notice Registers the ERC721/ERC1155 interfaces and callbacks. function _registerTokenInterfaces() private { _registerInterface(type(IERC721ReceiverUpgradeable).interfaceId); _registerInterface(type(IERC1155ReceiverUpgradeable).interfaceId); _registerCallback( IERC721ReceiverUpgradeable.onERC721Received.selector, IERC721ReceiverUpgradeable.onERC721Received.selector ); _registerCallback( IERC1155ReceiverUpgradeable.onERC1155Received.selector, IERC1155ReceiverUpgradeable.onERC1155Received.selector ); _registerCallback( IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector, IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector ); } /// @inheritdoc IDAO function registerStandardCallback( bytes4 _interfaceId, bytes4 _callbackSelector, bytes4 _magicNumber ) external override auth(REGISTER_STANDARD_CALLBACK_PERMISSION_ID) { _registerInterface(_interfaceId); _registerCallback(_callbackSelector, _magicNumber); emit StandardCallbackRegistered(_interfaceId, _callbackSelector, _magicNumber); } /// @inheritdoc IEIP4824 function daoURI() external view returns (string memory) { return _daoURI; } /// @notice Updates the set DAO uri to a new value. /// @param newDaoURI The new DAO uri to be set. function setDaoURI(string calldata newDaoURI) external auth(SET_METADATA_PERMISSION_ID) { _setDaoURI(newDaoURI); } /// @notice Sets the new DAO uri and emits the associated event. /// @param daoURI_ The new DAO uri. function _setDaoURI(string calldata daoURI_) internal { _daoURI = daoURI_; emit NewURI(daoURI_); } /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). uint256[47] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; /// @title IDAO /// @author Aragon Association - 2022-2023 /// @notice The interface required for DAOs within the Aragon App DAO framework. interface IDAO { /// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call. /// @param to The address to call. /// @param value The native token value to be sent with the call. /// @param data The bytes-encoded function selector and calldata for the call. struct Action { address to; uint256 value; bytes data; } /// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. /// @param _where The address of the contract. /// @param _who The address of a EOA or contract to give the permissions. /// @param _permissionId The permission identifier. /// @param _data The optional data passed to the `PermissionCondition` registered. /// @return Returns true if the address has permission, false if not. function hasPermission( address _where, address _who, bytes32 _permissionId, bytes memory _data ) external view returns (bool); /// @notice Updates the DAO metadata (e.g., an IPFS hash). /// @param _metadata The IPFS hash of the new metadata object. function setMetadata(bytes calldata _metadata) external; /// @notice Emitted when the DAO metadata is updated. /// @param metadata The IPFS hash of the new metadata object. event MetadataSet(bytes metadata); /// @notice Executes a list of actions. If a zero allow-failure map is provided, a failing action reverts the entire excution. If a non-zero allow-failure map is provided, allowed actions can fail without the entire call being reverted. /// @param _callId The ID of the call. The definition of the value of `callId` is up to the calling contract and can be used, e.g., as a nonce. /// @param _actions The array of actions. /// @param _allowFailureMap A bitmap allowing execution to succeed, even if individual actions might revert. If the bit at index `i` is 1, the execution succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. /// @return The array of results obtained from the executed actions in `bytes`. /// @return The resulting failure map containing the actions have actually failed. function execute( bytes32 _callId, Action[] memory _actions, uint256 _allowFailureMap ) external returns (bytes[] memory, uint256); /// @notice Emitted when a proposal is executed. /// @param actor The address of the caller. /// @param callId The ID of the call. /// @param actions The array of actions executed. /// @param failureMap The failure map encoding which actions have failed. /// @param execResults The array with the results of the executed actions. /// @dev The value of `callId` is defined by the component/contract calling the execute function. A `Plugin` implementation can use it, for example, as a nonce. event Executed( address indexed actor, bytes32 callId, Action[] actions, uint256 failureMap, bytes[] execResults ); /// @notice Emitted when a standard callback is registered. /// @param interfaceId The ID of the interface. /// @param callbackSelector The selector of the callback function. /// @param magicNumber The magic number to be registered for the callback function selector. event StandardCallbackRegistered( bytes4 interfaceId, bytes4 callbackSelector, bytes4 magicNumber ); /// @notice Deposits (native) tokens to the DAO contract with a reference string. /// @param _token The address of the token or address(0) in case of the native token. /// @param _amount The amount of tokens to deposit. /// @param _reference The reference describing the deposit reason. function deposit(address _token, uint256 _amount, string calldata _reference) external payable; /// @notice Emitted when a token deposit has been made to the DAO. /// @param sender The address of the sender. /// @param token The address of the deposited token. /// @param amount The amount of tokens deposited. /// @param _reference The reference describing the deposit reason. event Deposited( address indexed sender, address indexed token, uint256 amount, string _reference ); /// @notice Emitted when a native token deposit has been made to the DAO. /// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). /// @param sender The address of the sender. /// @param amount The amount of native tokens deposited. event NativeTokenDeposited(address sender, uint256 amount); /// @notice Setter for the trusted forwarder verifying the meta transaction. /// @param _trustedForwarder The trusted forwarder address. function setTrustedForwarder(address _trustedForwarder) external; /// @notice Getter for the trusted forwarder verifying the meta transaction. /// @return The trusted forwarder address. function getTrustedForwarder() external view returns (address); /// @notice Emitted when a new TrustedForwarder is set on the DAO. /// @param forwarder the new forwarder address. event TrustedForwarderSet(address forwarder); /// @notice Setter for the [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. /// @param _signatureValidator The address of the signature validator. function setSignatureValidator(address _signatureValidator) external; /// @notice Emitted when the signature validator address is updated. /// @param signatureValidator The address of the signature validator. event SignatureValidatorSet(address signatureValidator); /// @notice Checks whether a signature is valid for the provided hash by forwarding the call to the set [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature validator contract. /// @param _hash The hash of the data to be signed. /// @param _signature The signature byte array associated with `_hash`. /// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid. function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4); /// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. /// @param _interfaceId The ID of the interface. /// @param _callbackSelector The selector of the callback function. /// @param _magicNumber The magic number to be registered for the function signature. function registerStandardCallback( bytes4 _interfaceId, bytes4 _callbackSelector, bytes4 _magicNumber ) external; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; /// @title EIP-4824 Common Interfaces for DAOs /// @dev See https://eips.ethereum.org/EIPS/eip-4824 /// @author Aragon Association - 2021-2023 interface IEIP4824 { /// @notice A distinct Uniform Resource Identifier (URI) pointing to a JSON object following the "EIP-4824 DAO JSON-LD Schema". This JSON file splits into four URIs: membersURI, proposalsURI, activityLogURI, and governanceURI. The membersURI should point to a JSON file that conforms to the "EIP-4824 Members JSON-LD Schema". The proposalsURI should point to a JSON file that conforms to the "EIP-4824 Proposals JSON-LD Schema". The activityLogURI should point to a JSON file that conforms to the "EIP-4824 Activity Log JSON-LD Schema". The governanceURI should point to a flatfile, normatively a .md file. Each of the JSON files named above can be statically-hosted or dynamically-generated. function daoURI() external view returns (string memory _daoURI); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; /// @title IPermissionCondition /// @author Aragon Association - 2021-2023 /// @notice This interface can be implemented to support more customary permissions depending on on- or off-chain state, e.g., by querying token ownershop or a secondary condition, respectively. interface IPermissionCondition { /// @notice This method is used to check if a call is permitted. /// @param _where The address of the target contract. /// @param _who The address (EOA or contract) for which the permission are checked. /// @param _permissionId The permission identifier. /// @param _data Optional data passed to the `PermissionCondition` implementation. /// @return allowed Returns true if the call is permitted. function isGranted( address _where, address _who, bytes32 _permissionId, bytes calldata _data ) external view returns (bool allowed); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; /// @title PermissionLib /// @author Aragon Association - 2021-2023 /// @notice A library containing objects for permission processing. library PermissionLib { /// @notice A constant expressing that no condition is applied to a permission. address public constant NO_CONDITION = address(0); /// @notice The types of permission operations available in the `PermissionManager`. /// @param Grant The grant operation setting a permission without a condition. /// @param Revoke The revoke operation removing a permission (that was granted with or without a condition). /// @param GrantWithCondition The grant operation setting a permission with a condition. enum Operation { Grant, Revoke, GrantWithCondition } /// @notice A struct containing the information for a permission to be applied on a single target contract without a condition. /// @param operation The permission operation type. /// @param who The address (EOA or contract) receiving the permission. /// @param permissionId The permission identifier. struct SingleTargetPermission { Operation operation; address who; bytes32 permissionId; } /// @notice A struct containing the information for a permission to be applied on multiple target contracts, optionally, with a conditon. /// @param operation The permission operation type. /// @param where The address of the target contract for which `who` recieves permission. /// @param who The address (EOA or contract) receiving the permission. /// @param condition The `PermissionCondition` that will be asked for authorization on calls connected to the specified permission identifier. /// @param permissionId The permission identifier. struct MultiTargetPermission { Operation operation; address where; address who; address condition; bytes32 permissionId; } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./IPermissionCondition.sol"; import "./PermissionLib.sol"; /// @title PermissionManager /// @author Aragon Association - 2021-2023 /// @notice The abstract permission manager used in a DAO, its associated plugins, and other framework-related components. abstract contract PermissionManager is Initializable { /// @notice The ID of the permission required to call the `grant`, `grantWithCondition`, `revoke`, and `bulk` function. bytes32 public constant ROOT_PERMISSION_ID = keccak256("ROOT_PERMISSION"); /// @notice A special address encoding permissions that are valid for any address `who` or `where`. address internal constant ANY_ADDR = address(type(uint160).max); /// @notice A special address encoding if a permissions is not set and therefore not allowed. address internal constant UNSET_FLAG = address(0); /// @notice A special address encoding if a permission is allowed. address internal constant ALLOW_FLAG = address(2); /// @notice A mapping storing permissions as hashes (i.e., `permissionHash(where, who, permissionId)`) and their status encoded by an address (unset, allowed, or redirecting to a `PermissionCondition`). mapping(bytes32 => address) internal permissionsHashed; /// @notice Thrown if a call is unauthorized. /// @param where The context in which the authorization reverted. /// @param who The address (EOA or contract) missing the permission. /// @param permissionId The permission identifier. error Unauthorized(address where, address who, bytes32 permissionId); /// @notice Thrown if a permission has been already granted with a different condition. /// @dev This makes sure that condition on the same permission can not be overwriten by a different condition. /// @param where The address of the target contract to grant `_who` permission to. /// @param who The address (EOA or contract) to which the permission has already been granted. /// @param permissionId The permission identifier. /// @param currentCondition The current condition set for permissionId. /// @param newCondition The new condition it tries to set for permissionId. error PermissionAlreadyGrantedForDifferentCondition( address where, address who, bytes32 permissionId, address currentCondition, address newCondition ); /// @notice Thrown for permission grants where `who` or `where` is `ANY_ADDR`, but no condition is present. error ConditionNotPresentForAnyAddress(); /// @notice Thrown for `ROOT_PERMISSION_ID` or `EXECUTE_PERMISSION_ID` permission grants where `who` or `where` is `ANY_ADDR`. error PermissionsForAnyAddressDisallowed(); /// @notice Thrown for permission grants where `who` and `where` are both `ANY_ADDR`. error AnyAddressDisallowedForWhoAndWhere(); /// @notice Emitted when a permission `permission` is granted in the context `here` to the address `_who` for the contract `_where`. /// @param permissionId The permission identifier. /// @param here The address of the context in which the permission is granted. /// @param where The address of the target contract for which `_who` receives permission. /// @param who The address (EOA or contract) receiving the permission. /// @param condition The address `ALLOW_FLAG` for regular permissions or, alternatively, the `PermissionCondition` to be used. event Granted( bytes32 indexed permissionId, address indexed here, address where, address indexed who, IPermissionCondition condition ); /// @notice Emitted when a permission `permission` is revoked in the context `here` from the address `_who` for the contract `_where`. /// @param permissionId The permission identifier. /// @param here The address of the context in which the permission is revoked. /// @param where The address of the target contract for which `_who` loses permission. /// @param who The address (EOA or contract) losing the permission. event Revoked( bytes32 indexed permissionId, address indexed here, address where, address indexed who ); /// @notice A modifier to make functions on inheriting contracts authorized. Permissions to call the function are checked through this permission manager. /// @param _permissionId The permission identifier required to call the method this modifier is applied to. modifier auth(bytes32 _permissionId) { _auth(_permissionId); _; } /// @notice Initialization method to set the initial owner of the permission manager. /// @dev The initial owner is granted the `ROOT_PERMISSION_ID` permission. /// @param _initialOwner The initial owner of the permission manager. function __PermissionManager_init(address _initialOwner) internal onlyInitializing { _initializePermissionManager(_initialOwner); } /// @notice Grants permission to an address to call methods in a contract guarded by an auth modifier with the specified permission identifier. /// @dev Requires the `ROOT_PERMISSION_ID` permission. /// @param _where The address of the target contract for which `_who` recieves permission. /// @param _who The address (EOA or contract) receiving the permission. /// @param _permissionId The permission identifier. /// @dev Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. function grant( address _where, address _who, bytes32 _permissionId ) external virtual auth(ROOT_PERMISSION_ID) { _grant(_where, _who, _permissionId); } /// @notice Grants permission to an address to call methods in a target contract guarded by an auth modifier with the specified permission identifier if the referenced condition permits it. /// @dev Requires the `ROOT_PERMISSION_ID` permission /// @param _where The address of the target contract for which `_who` recieves permission. /// @param _who The address (EOA or contract) receiving the permission. /// @param _permissionId The permission identifier. /// @param _condition The `PermissionCondition` that will be asked for authorization on calls connected to the specified permission identifier. /// @dev Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. function grantWithCondition( address _where, address _who, bytes32 _permissionId, IPermissionCondition _condition ) external virtual auth(ROOT_PERMISSION_ID) { _grantWithCondition(_where, _who, _permissionId, _condition); } /// @notice Revokes permission from an address to call methods in a target contract guarded by an auth modifier with the specified permission identifier. /// @dev Requires the `ROOT_PERMISSION_ID` permission. /// @param _where The address of the target contract for which `_who` loses permission. /// @param _who The address (EOA or contract) losing the permission. /// @param _permissionId The permission identifier. /// @dev Note, that revoking permissions with `_who` or `_where` equal to `ANY_ADDR` does not revoke other permissions with specific `_who` and `_where` addresses that exist in parallel. function revoke( address _where, address _who, bytes32 _permissionId ) external virtual auth(ROOT_PERMISSION_ID) { _revoke(_where, _who, _permissionId); } /// @notice Applies an array of permission operations on a single target contracts `_where`. /// @param _where The address of the single target contract. /// @param items The array of single-targeted permission operations to apply. function applySingleTargetPermissions( address _where, PermissionLib.SingleTargetPermission[] calldata items ) external virtual auth(ROOT_PERMISSION_ID) { for (uint256 i; i < items.length; ) { PermissionLib.SingleTargetPermission memory item = items[i]; if (item.operation == PermissionLib.Operation.Grant) { _grant(_where, item.who, item.permissionId); } else if (item.operation == PermissionLib.Operation.Revoke) { _revoke(_where, item.who, item.permissionId); } unchecked { ++i; } } } /// @notice Applies an array of permission operations on multiple target contracts `items[i].where`. /// @param _items The array of multi-targeted permission operations to apply. function applyMultiTargetPermissions( PermissionLib.MultiTargetPermission[] calldata _items ) external virtual auth(ROOT_PERMISSION_ID) { for (uint256 i; i < _items.length; ) { PermissionLib.MultiTargetPermission memory item = _items[i]; if (item.operation == PermissionLib.Operation.Grant) { _grant(item.where, item.who, item.permissionId); } else if (item.operation == PermissionLib.Operation.Revoke) { _revoke(item.where, item.who, item.permissionId); } else if (item.operation == PermissionLib.Operation.GrantWithCondition) { _grantWithCondition( item.where, item.who, item.permissionId, IPermissionCondition(item.condition) ); } unchecked { ++i; } } } /// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. /// @param _where The address of the target contract for which `_who` recieves permission. /// @param _who The address (EOA or contract) for which the permission is checked. /// @param _permissionId The permission identifier. /// @param _data The optional data passed to the `PermissionCondition` registered. /// @return Returns true if `_who` has the permissions on the target contract via the specified permission identifier. function isGranted( address _where, address _who, bytes32 _permissionId, bytes memory _data ) public view virtual returns (bool) { return _isGranted(_where, _who, _permissionId, _data) || // check if `_who` has permission for `_permissionId` on `_where` _isGranted(_where, ANY_ADDR, _permissionId, _data) || // check if anyone has permission for `_permissionId` on `_where` _isGranted(ANY_ADDR, _who, _permissionId, _data); // check if `_who` has permission for `_permissionI` on any contract } /// @notice Grants the `ROOT_PERMISSION_ID` permission to the initial owner during initialization of the permission manager. /// @param _initialOwner The initial owner of the permission manager. function _initializePermissionManager(address _initialOwner) internal { _grant(address(this), _initialOwner, ROOT_PERMISSION_ID); } /// @notice This method is used in the public `grant` method of the permission manager. /// @param _where The address of the target contract for which `_who` recieves permission. /// @param _who The address (EOA or contract) owning the permission. /// @param _permissionId The permission identifier. function _grant(address _where, address _who, bytes32 _permissionId) internal virtual { _grantWithCondition(_where, _who, _permissionId, IPermissionCondition(ALLOW_FLAG)); } /// @notice This method is used in the internal `_grant` method of the permission manager. /// @param _where The address of the target contract for which `_who` recieves permission. /// @param _who The address (EOA or contract) owning the permission. /// @param _permissionId The permission identifier. /// @param _condition An address either resolving to a `PermissionCondition` contract address or being the `ALLOW_FLAG` address (`address(2)`). /// @dev Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel. function _grantWithCondition( address _where, address _who, bytes32 _permissionId, IPermissionCondition _condition ) internal virtual { if (_where == ANY_ADDR && _who == ANY_ADDR) { revert AnyAddressDisallowedForWhoAndWhere(); } if (_where == ANY_ADDR || _who == ANY_ADDR) { bool isRestricted = isPermissionRestrictedForAnyAddr(_permissionId); if (_permissionId == ROOT_PERMISSION_ID || isRestricted) { revert PermissionsForAnyAddressDisallowed(); } if (address(_condition) == ALLOW_FLAG) { revert ConditionNotPresentForAnyAddress(); } } bytes32 permHash = permissionHash(_where, _who, _permissionId); address currentCondition = permissionsHashed[permHash]; address newCondition = address(_condition); // Means permHash is not currently set. if (currentCondition == UNSET_FLAG) { permissionsHashed[permHash] = newCondition; emit Granted(_permissionId, msg.sender, _where, _who, _condition); } else if (currentCondition != newCondition) { // Revert if `permHash` is already granted, but uses a different condition. // If we don't revert, we either should: // - allow overriding the condition on the same permission // which could be confusing whoever granted the same permission first // - or do nothing and succeed silently which could be confusing for the caller. revert PermissionAlreadyGrantedForDifferentCondition({ where: _where, who: _who, permissionId: _permissionId, currentCondition: currentCondition, newCondition: newCondition }); } } /// @notice This method is used in the public `revoke` method of the permission manager. /// @param _where The address of the target contract for which `_who` recieves permission. /// @param _who The address (EOA or contract) owning the permission. /// @param _permissionId The permission identifier. /// @dev Note, that revoking permissions with `_who` or `_where` equal to `ANY_ADDR` does not revoke other permissions with specific `_who` and `_where` addresses that might have been granted in parallel. function _revoke(address _where, address _who, bytes32 _permissionId) internal virtual { bytes32 permHash = permissionHash(_where, _who, _permissionId); if (permissionsHashed[permHash] != UNSET_FLAG) { permissionsHashed[permHash] = UNSET_FLAG; emit Revoked(_permissionId, msg.sender, _where, _who); } } /// @notice Checks if a caller is granted permissions on a target contract via a permission identifier and redirects the approval to a `PermissionCondition` if this was specified in the setup. /// @param _where The address of the target contract for which `_who` recieves permission. /// @param _who The address (EOA or contract) owning the permission. /// @param _permissionId The permission identifier. /// @param _data The optional data passed to the `PermissionCondition` registered. /// @return Returns true if `_who` has the permissions on the contract via the specified permissionId identifier. function _isGranted( address _where, address _who, bytes32 _permissionId, bytes memory _data ) internal view virtual returns (bool) { address accessFlagOrCondition = permissionsHashed[ permissionHash(_where, _who, _permissionId) ]; if (accessFlagOrCondition == UNSET_FLAG) return false; if (accessFlagOrCondition == ALLOW_FLAG) return true; // Since it's not a flag, assume it's a PermissionCondition and try-catch to skip failures try IPermissionCondition(accessFlagOrCondition).isGranted( _where, _who, _permissionId, _data ) returns (bool allowed) { if (allowed) return true; } catch {} return false; } /// @notice A private function to be used to check permissions on the permission manager contract (`address(this)`) itself. /// @param _permissionId The permission identifier required to call the method this modifier is applied to. function _auth(bytes32 _permissionId) internal view virtual { if (!isGranted(address(this), msg.sender, _permissionId, msg.data)) { revert Unauthorized({ where: address(this), who: msg.sender, permissionId: _permissionId }); } } /// @notice Generates the hash for the `permissionsHashed` mapping obtained from the word "PERMISSION", the contract address, the address owning the permission, and the permission identifier. /// @param _where The address of the target contract for which `_who` recieves permission. /// @param _who The address (EOA or contract) owning the permission. /// @param _permissionId The permission identifier. /// @return The permission hash. function permissionHash( address _where, address _who, bytes32 _permissionId ) internal pure virtual returns (bytes32) { return keccak256(abi.encodePacked("PERMISSION", _who, _where, _permissionId)); } /// @notice Decides if the granting permissionId is restricted when `_who = ANY_ADDR` or `_where = ANY_ADDR`. /// @param _permissionId The permission identifier. /// @return Whether or not the permission is restricted. /// @dev By default, every permission is unrestricted and it is the derived contract's responsibility to override it. Note, that the `ROOT_PERMISSION_ID` is included not required to be set it again. function isPermissionRestrictedForAnyAddr( bytes32 _permissionId ) internal view virtual returns (bool) { (_permissionId); // silence the warning. return false; } /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). uint256[49] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import {IDAO} from "../../dao/IDAO.sol"; import {_auth} from "../../utils/auth.sol"; /// @title DaoAuthorizableUpgradeable /// @author Aragon Association - 2022-2023 /// @notice An abstract contract providing a meta-transaction compatible modifier for upgradeable or cloneable contracts to authorize function calls through an associated DAO. /// @dev Make sure to call `__DaoAuthorizableUpgradeable_init` during initialization of the inheriting contract. abstract contract DaoAuthorizableUpgradeable is ContextUpgradeable { /// @notice The associated DAO managing the permissions of inheriting contracts. IDAO private dao_; /// @notice Initializes the contract by setting the associated DAO. /// @param _dao The associated DAO address. function __DaoAuthorizableUpgradeable_init(IDAO _dao) internal onlyInitializing { dao_ = _dao; } /// @notice Returns the DAO contract. /// @return The DAO contract. function dao() public view returns (IDAO) { return dao_; } /// @notice A modifier to make functions on inheriting contracts authorized. Permissions to call the function are checked through the associated DAO's permission manager. /// @param _permissionId The permission identifier required to call the method this modifier is applied to. modifier auth(bytes32 _permissionId) { _auth(dao_, address(this), _msgSender(), _permissionId, _msgData()); _; } /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). uint256[49] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; /// @title IPlugin /// @author Aragon Association - 2022-2023 /// @notice An interface defining the traits of a plugin. interface IPlugin { enum PluginType { UUPS, Cloneable, Constructable } /// @notice returns the plugin's type function pluginType() external view returns (PluginType); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {IDAO} from "../../dao/IDAO.sol"; /// @title IProposal /// @author Aragon Association - 2022-2023 /// @notice An interface to be implemented by DAO plugins that define membership. interface IMembership { /// @notice Emitted when members are added to the DAO plugin. /// @param members The list of new members being added. event MembersAdded(address[] members); /// @notice Emitted when members are removed from the DAO plugin. /// @param members The list of existing members being removed. event MembersRemoved(address[] members); /// @notice Emitted to announce the membership being defined by a contract. /// @param definingContract The contract defining the membership. event MembershipContractAnnounced(address indexed definingContract); /// @notice Checks if an account is a member of the DAO. /// @param _account The address of the account to be checked. /// @return Whether the account is a member or not. /// @dev This function must be implemented in the plugin contract that introduces the members to the DAO. function isMember(address _account) external view returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import {IERC1822ProxiableUpgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol"; import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; import {IDAO} from "../dao/IDAO.sol"; import {DaoAuthorizableUpgradeable} from "./dao-authorizable/DaoAuthorizableUpgradeable.sol"; import {IPlugin} from "./IPlugin.sol"; /// @title PluginUUPSUpgradeable /// @author Aragon Association - 2022-2023 /// @notice An abstract, upgradeable contract to inherit from when creating a plugin being deployed via the UUPS pattern (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). abstract contract PluginUUPSUpgradeable is IPlugin, ERC165Upgradeable, UUPSUpgradeable, DaoAuthorizableUpgradeable { // NOTE: When adding new state variables to the contract, the size of `_gap` has to be adapted below as well. /// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized. constructor() { _disableInitializers(); } /// @inheritdoc IPlugin function pluginType() public pure override returns (PluginType) { return PluginType.UUPS; } /// @notice The ID of the permission required to call the `_authorizeUpgrade` function. bytes32 public constant UPGRADE_PLUGIN_PERMISSION_ID = keccak256("UPGRADE_PLUGIN_PERMISSION"); /// @notice Initializes the plugin by storing the associated DAO. /// @param _dao The DAO contract. function __PluginUUPSUpgradeable_init(IDAO _dao) internal virtual onlyInitializing { __DaoAuthorizableUpgradeable_init(_dao); } /// @notice Checks if an interface is supported by this or its parent contract. /// @param _interfaceId The ID of the interface. /// @return Returns `true` if the interface is supported. function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { return _interfaceId == type(IPlugin).interfaceId || _interfaceId == type(IERC1822ProxiableUpgradeable).interfaceId || super.supportsInterface(_interfaceId); } /// @notice Returns the address of the implementation contract in the [proxy storage slot](https://eips.ethereum.org/EIPS/eip-1967) slot the [UUPS proxy](https://eips.ethereum.org/EIPS/eip-1822) is pointing to. /// @return The address of the implementation contract. function implementation() public view returns (address) { return _getImplementation(); } /// @notice Internal method authorizing the upgrade of the contract via the [upgradeabilty mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). /// @dev The caller must have the `UPGRADE_PLUGIN_PERMISSION_ID` permission. function _authorizeUpgrade( address ) internal virtual override auth(UPGRADE_PLUGIN_PERMISSION_ID) {} /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). uint256[50] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {IDAO} from "../../dao/IDAO.sol"; /// @title IProposal /// @author Aragon Association - 2022-2023 /// @notice An interface to be implemented by DAO plugins that create and execute proposals. interface IProposal { /// @notice Emitted when a proposal is created. /// @param proposalId The ID of the proposal. /// @param creator The creator of the proposal. /// @param startDate The start date of the proposal in seconds. /// @param endDate The end date of the proposal in seconds. /// @param metadata The metadata of the proposal. /// @param actions The actions that will be executed if the proposal passes. /// @param allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. event ProposalCreated( uint256 indexed proposalId, address indexed creator, uint64 startDate, uint64 endDate, bytes metadata, IDAO.Action[] actions, uint256 allowFailureMap ); /// @notice Emitted when a proposal is executed. /// @param proposalId The ID of the proposal. event ProposalExecuted(uint256 indexed proposalId); /// @notice Returns the proposal count determining the next proposal ID. /// @return The proposal count. function proposalCount() external view returns (uint256); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {CountersUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol"; import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; import "./IProposal.sol"; /// @title ProposalUgradeable /// @author Aragon Association - 2022-2023 /// @notice An abstract contract containing the traits and internal functionality to create and execute proposals that can be inherited by upgradeable DAO plugins. abstract contract ProposalUpgradeable is IProposal, ERC165Upgradeable { using CountersUpgradeable for CountersUpgradeable.Counter; /// @notice The incremental ID for proposals and executions. CountersUpgradeable.Counter private proposalCounter; /// @inheritdoc IProposal function proposalCount() public view override returns (uint256) { return proposalCounter.current(); } /// @notice Checks if this or the parent contract supports an interface by its ID. /// @param _interfaceId The ID of the interface. /// @return Returns `true` if the interface is supported. function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { return _interfaceId == type(IProposal).interfaceId || super.supportsInterface(_interfaceId); } /// @notice Creates a proposal ID. /// @return proposalId The proposal ID. function _createProposalId() internal returns (uint256 proposalId) { proposalId = proposalCount(); proposalCounter.increment(); } /// @notice Internal function to create a proposal. /// @param _metadata The the proposal metadata. /// @param _startDate The start date of the proposal in seconds. /// @param _endDate The end date of the proposal in seconds. /// @param _allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. /// @param _actions The actions that will be executed after the proposal passes. /// @return proposalId The ID of the proposal. function _createProposal( address _creator, bytes calldata _metadata, uint64 _startDate, uint64 _endDate, IDAO.Action[] calldata _actions, uint256 _allowFailureMap ) internal virtual returns (uint256 proposalId) { proposalId = _createProposalId(); emit ProposalCreated({ proposalId: proposalId, creator: _creator, metadata: _metadata, startDate: _startDate, endDate: _endDate, actions: _actions, allowFailureMap: _allowFailureMap }); } /// @notice Internal function to execute a proposal. /// @param _proposalId The ID of the proposal to be executed. /// @param _actions The array of actions to be executed. /// @param _allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. /// @return execResults The array with the results of the executed actions. /// @return failureMap The failure map encoding which actions have failed. function _executeProposal( IDAO _dao, uint256 _proposalId, IDAO.Action[] memory _actions, uint256 _allowFailureMap ) internal virtual returns (bytes[] memory execResults, uint256 failureMap) { (execResults, failureMap) = _dao.execute(bytes32(_proposalId), _actions, _allowFailureMap); emit ProposalExecuted({proposalId: _proposalId}); } /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). uint256[49] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {IDAO} from "../dao/IDAO.sol"; /// @notice Thrown if a call is unauthorized in the associated DAO. /// @param dao The associated DAO. /// @param where The context in which the authorization reverted. /// @param who The address (EOA or contract) missing the permission. /// @param permissionId The permission identifier. error DaoUnauthorized(address dao, address where, address who, bytes32 permissionId); /// @notice A free function checking if a caller is granted permissions on a target contract via a permission identifier that redirects the approval to a `PermissionCondition` if this was specified in the setup. /// @param _where The address of the target contract for which `who` recieves permission. /// @param _who The address (EOA or contract) owning the permission. /// @param _permissionId The permission identifier. /// @param _data The optional data passed to the `PermissionCondition` registered. function _auth( IDAO _dao, address _where, address _who, bytes32 _permissionId, bytes calldata _data ) view { if (!_dao.hasPermission(_where, _who, _permissionId, _data)) revert DaoUnauthorized({ dao: address(_dao), where: _where, who: _who, permissionId: _permissionId }); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; /// @param bitmap The `uint256` representation of bits. /// @param index The index number to check whether 1 or 0 is set. /// @return Returns `true` whether the bit is set at `index` on `bitmap`. function hasBit(uint256 bitmap, uint8 index) pure returns (bool) { uint256 bitValue = bitmap & (1 << index); return bitValue > 0; } /// @param bitmap The `uint256` representation of bits. /// @param index The index number to set the bit. /// @return Returns a new number on which the bit is set at `index`. function flipBit(uint256 bitmap, uint8 index) pure returns (uint256) { return bitmap ^ (1 << index); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; /// @title CallbackHandler /// @author Aragon Association - 2022-2023 /// @notice This contract handles callbacks by registering a magic number together with the callback function's selector. It provides the `_handleCallback` function that inherting have to call inside their `fallback()` function (`_handleCallback(msg.callbackSelector, msg.data)`). This allows to adaptively register ERC standards (e.g., [ERC-721](https://eips.ethereum.org/EIPS/eip-721), [ERC-1115](https://eips.ethereum.org/EIPS/eip-1155), or future versions of [ERC-165](https://eips.ethereum.org/EIPS/eip-165)) and returning the required magic numbers for the associated callback functions for the inheriting contract so that it doesn't need to be upgraded. /// @dev This callback handling functionality is intented to be used by executor contracts (i.e., `DAO.sol`). abstract contract CallbackHandler { /// @notice A mapping between callback function selectors and magic return numbers. mapping(bytes4 => bytes4) internal callbackMagicNumbers; /// @notice The magic number refering to unregistered callbacks. bytes4 internal constant UNREGISTERED_CALLBACK = bytes4(0); /// @notice Thrown if the callback function is not registered. /// @param callbackSelector The selector of the callback function. /// @param magicNumber The magic number to be registered for the callback function selector. error UnkownCallback(bytes4 callbackSelector, bytes4 magicNumber); /// @notice Emitted when `_handleCallback` is called. /// @param sender Who called the callback. /// @param sig The function signature. /// @param data The calldata for the function signature. event CallbackReceived(address sender, bytes4 indexed sig, bytes data); /// @notice Handles callbacks to adaptively support ERC standards. /// @dev This function is supposed to be called via `_handleCallback(msg.sig, msg.data)` in the `fallback()` function of the inheriting contract. /// @param _callbackSelector The function selector of the callback function. /// @return The magic number registered for the function selector triggering the fallback. function _handleCallback( bytes4 _callbackSelector, bytes memory _data ) internal virtual returns (bytes4) { bytes4 magicNumber = callbackMagicNumbers[_callbackSelector]; if (magicNumber == UNREGISTERED_CALLBACK) { revert UnkownCallback({callbackSelector: _callbackSelector, magicNumber: magicNumber}); } emit CallbackReceived({sender: msg.sender, sig: _callbackSelector, data: _data}); return magicNumber; } /// @notice Registers a magic number for a callback function selector. /// @param _callbackSelector The selector of the callback function. /// @param _magicNumber The magic number to be registered for the callback function selector. function _registerCallback(bytes4 _callbackSelector, bytes4 _magicNumber) internal virtual { callbackMagicNumbers[_callbackSelector] = _magicNumber; } /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). uint256[49] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {PermissionLib} from "../../../core/permission/PermissionLib.sol"; import {IDAO} from "../../../core/dao/IDAO.sol"; /// @title IPluginSetup /// @author Aragon Association - 2022-2023 /// @notice The interface required for a plugin setup contract to be consumed by the `PluginSetupProcessor` for plugin installations, updates, and uninstallations. interface IPluginSetup { /// @notice The data associated with a prepared setup. /// @param helpers The address array of helpers (contracts or EOAs) associated with this plugin version after the installation or update. /// @param permissions The array of multi-targeted permission operations to be applied by the `PluginSetupProcessor` to the installing or updating DAO. struct PreparedSetupData { address[] helpers; PermissionLib.MultiTargetPermission[] permissions; } /// @notice The payload for plugin updates and uninstallations containing the existing contracts as well as optional data to be consumed by the plugin setup. /// @param plugin The address of the `Plugin`. /// @param currentHelpers The address array of all current helpers (contracts or EOAs) associated with the plugin to update from. /// @param data The bytes-encoded data containing the input parameters for the preparation of update/uninstall as specified in the corresponding ABI on the version's metadata. struct SetupPayload { address plugin; address[] currentHelpers; bytes data; } /// @notice Prepares the installation of a plugin. /// @param _dao The address of the installing DAO. /// @param _data The bytes-encoded data containing the input parameters for the installation as specified in the plugin's build metadata JSON file. /// @return plugin The address of the `Plugin` contract being prepared for installation. /// @return preparedSetupData The deployed plugin's relevant data which consists of helpers and permissions. function prepareInstallation( address _dao, bytes calldata _data ) external returns (address plugin, PreparedSetupData memory preparedSetupData); /// @notice Prepares the update of a plugin. /// @param _dao The address of the updating DAO. /// @param _currentBuild The build number of the plugin to update from. /// @param _payload The relevant data necessary for the `prepareUpdate`. see above. /// @return initData The initialization data to be passed to upgradeable contracts when the update is applied in the `PluginSetupProcessor`. /// @return preparedSetupData The deployed plugin's relevant data which consists of helpers and permissions. function prepareUpdate( address _dao, uint16 _currentBuild, SetupPayload calldata _payload ) external returns (bytes memory initData, PreparedSetupData memory preparedSetupData); /// @notice Prepares the uninstallation of a plugin. /// @param _dao The address of the uninstalling DAO. /// @param _payload The relevant data necessary for the `prepareUninstallation`. see above. /// @return permissions The array of multi-targeted permission operations to be applied by the `PluginSetupProcessor` to the uninstalling DAO. function prepareUninstallation( address _dao, SetupPayload calldata _payload ) external returns (PermissionLib.MultiTargetPermission[] memory permissions); /// @notice Returns the plugin implementation address. /// @return The address of the plugin implementation contract. /// @dev The implementation can be instantiated via the `new` keyword, cloned via the minimal clones pattern (see [ERC-1167](https://eips.ethereum.org/EIPS/eip-1167)), or proxied via the UUPS pattern (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)). function implementation() external view returns (address); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {PermissionLib} from "../../../core/permission/PermissionLib.sol"; import {createERC1967Proxy as createERC1967} from "../../../utils/Proxy.sol"; import {IPluginSetup} from "./IPluginSetup.sol"; /// @title PluginSetup /// @author Aragon Association - 2022-2023 /// @notice An abstract contract that developers have to inherit from to write the setup of a plugin. abstract contract PluginSetup is ERC165, IPluginSetup { /// @inheritdoc IPluginSetup function prepareUpdate( address _dao, uint16 _currentBuild, SetupPayload calldata _payload ) external virtual override returns (bytes memory initData, PreparedSetupData memory preparedSetupData) {} /// @notice A convenience function to create an [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) proxy contract pointing to an implementation and being associated to a DAO. /// @param _implementation The address of the implementation contract to which the proxy is pointing to. /// @param _data The data to initialize the storage of the proxy contract. /// @return The address of the created proxy contract. function createERC1967Proxy( address _implementation, bytes memory _data ) internal returns (address) { return createERC1967(_implementation, _data); } /// @notice Checks if this or the parent contract supports an interface by its ID. /// @param _interfaceId The ID of the interface. /// @return Returns `true` if the interface is supported. function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { return _interfaceId == type(IPluginSetup).interfaceId || super.supportsInterface(_interfaceId); } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {IDAO} from "../../../core/dao/IDAO.sol"; /// @title IMajorityVoting /// @author Aragon Association - 2022-2023 /// @notice The interface of majority voting plugin. interface IMajorityVoting { /// @notice Vote options that a voter can chose from. /// @param None The default option state of a voter indicating the absence of from the vote. This option neither influences support nor participation. /// @param Abstain This option does not influence the support but counts towards participation. /// @param Yes This option increases the support and counts towards participation. /// @param No This option decreases the support and counts towards participation. enum VoteOption { None, Abstain, Yes, No } /// @notice Emitted when a vote is cast by a voter. /// @param proposalId The ID of the proposal. /// @param voter The voter casting the vote. /// @param voteOption The casted vote option. /// @param votingPower The voting power behind this vote. event VoteCast( uint256 indexed proposalId, address indexed voter, VoteOption voteOption, uint256 votingPower ); /// @notice Returns the support threshold parameter stored in the voting settings. /// @return The support threshold parameter. function supportThreshold() external view returns (uint32); /// @notice Returns the minimum participation parameter stored in the voting settings. /// @return The minimum participation parameter. function minParticipation() external view returns (uint32); /// @notice Checks if the support value defined as $$\texttt{support} = \frac{N_\text{yes}}{N_\text{yes}+N_\text{no}}$$ for a proposal vote is greater than the support threshold. /// @param _proposalId The ID of the proposal. /// @return Returns `true` if the support is greater than the support threshold and `false` otherwise. function isSupportThresholdReached(uint256 _proposalId) external view returns (bool); /// @notice Checks if the worst-case support value defined as $$\texttt{worstCaseSupport} = \frac{N_\text{yes}}{ N_\text{total}-N_\text{abstain}}$$ for a proposal vote is greater than the support threshold. /// @param _proposalId The ID of the proposal. /// @return Returns `true` if the worst-case support is greater than the support threshold and `false` otherwise. function isSupportThresholdReachedEarly(uint256 _proposalId) external view returns (bool); /// @notice Checks if the participation value defined as $$\texttt{participation} = \frac{N_\text{yes}+N_\text{no}+N_\text{abstain}}{N_\text{total}}$$ for a proposal vote is greater or equal than the minimum participation value. /// @param _proposalId The ID of the proposal. /// @return Returns `true` if the participation is greater than the minimum particpation and `false` otherwise. function isMinParticipationReached(uint256 _proposalId) external view returns (bool); /// @notice Checks if an account can participate on a proposal vote. This can be because the vote /// - has not started, /// - has ended, /// - was executed, or /// - the voter doesn't have voting powers. /// @param _proposalId The proposal Id. /// @param _account The account address to be checked. /// @param _voteOption Whether the voter abstains, supports or opposes the proposal. /// @return Returns true if the account is allowed to vote. /// @dev The function assumes the queried proposal exists. function canVote( uint256 _proposalId, address _account, VoteOption _voteOption ) external view returns (bool); /// @notice Checks if a proposal can be executed. /// @param _proposalId The ID of the proposal to be checked. /// @return True if the proposal can be executed, false otherwise. function canExecute(uint256 _proposalId) external view returns (bool); /// @notice Votes for a vote option and, optionally, executes the proposal. /// @dev `_voteOption`, 1 -> abstain, 2 -> yes, 3 -> no /// @param _proposalId The ID of the proposal. /// @param _voteOption The chosen vote option. /// @param _tryEarlyExecution If `true`, early execution is tried after the vote cast. The call does not revert if early execution is not possible. function vote(uint256 _proposalId, VoteOption _voteOption, bool _tryEarlyExecution) external; /// @notice Executes a proposal. /// @param _proposalId The ID of the proposal to be executed. function execute(uint256 _proposalId) external; /// @notice Returns whether the account has voted for the proposal. Note, that this does not check if the account has voting power. /// @param _proposalId The ID of the proposal. /// @param _account The account address to be checked. /// @return The vote option cast by a voter for a certain proposal. function getVoteOption( uint256 _proposalId, address _account ) external view returns (VoteOption); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; import {IProposal} from "../../../core/plugin/proposal/IProposal.sol"; import {ProposalUpgradeable} from "../../../core/plugin/proposal/ProposalUpgradeable.sol"; import {PluginUUPSUpgradeable} from "../../../core/plugin/PluginUUPSUpgradeable.sol"; import {IDAO} from "../../../core/dao/IDAO.sol"; import {RATIO_BASE, RatioOutOfBounds} from "../../utils/Ratio.sol"; import {IMajorityVoting} from "./IMajorityVoting.sol"; /// @title MajorityVotingBase /// @author Aragon Association - 2022-2023 /// @notice The abstract implementation of majority voting plugins. /// /// ### Parameterization /// /// We define two parameters /// $$\texttt{support} = \frac{N_\text{yes}}{N_\text{yes} + N_\text{no}} \in [0,1]$$ /// and /// $$\texttt{participation} = \frac{N_\text{yes} + N_\text{no} + N_\text{abstain}}{N_\text{total}} \in [0,1],$$ /// where $N_\text{yes}$, $N_\text{no}$, and $N_\text{abstain}$ are the yes, no, and abstain votes that have been cast and $N_\text{total}$ is the total voting power available at proposal creation time. /// /// #### Limit Values: Support Threshold & Minimum Participation /// /// Two limit values are associated with these parameters and decide if a proposal execution should be possible: $\texttt{supportThreshold} \in [0,1]$ and $\texttt{minParticipation} \in [0,1]$. /// /// For threshold values, $>$ comparison is used. This **does not** include the threshold value. E.g., for $\texttt{supportThreshold} = 50\%$, the criterion is fulfilled if there is at least one more yes than no votes ($N_\text{yes} = N_\text{no} + 1$). /// For minimum values, $\ge{}$ comparison is used. This **does** include the minimum participation value. E.g., for $\texttt{minParticipation} = 40\%$ and $N_\text{total} = 10$, the criterion is fulfilled if 4 out of 10 votes were casted. /// /// Majority voting implies that the support threshold is set with /// $$\texttt{supportThreshold} \ge 50\% .$$ /// However, this is not enforced by the contract code and developers can make unsafe parameters and only the frontend will warn about bad parameter settings. /// /// ### Execution Criteria /// /// After the vote is closed, two criteria decide if the proposal passes. /// /// #### The Support Criterion /// /// For a proposal to pass, the required ratio of yes and no votes must be met: /// $$(1- \texttt{supportThreshold}) \cdot N_\text{yes} > \texttt{supportThreshold} \cdot N_\text{no}.$$ /// Note, that the inequality yields the simple majority voting condition for $\texttt{supportThreshold}=\frac{1}{2}$. /// /// #### The Participation Criterion /// /// For a proposal to pass, the minimum voting power must have been cast: /// $$N_\text{yes} + N_\text{no} + N_\text{abstain} \ge \texttt{minVotingPower},$$ /// where $\texttt{minVotingPower} = \texttt{minParticipation} \cdot N_\text{total}$. /// /// ### Vote Replacement Execution /// /// The contract allows votes to be replaced. Voters can vote multiple times and only the latest voteOption is tallied. /// /// ### Early Execution /// /// This contract allows a proposal to be executed early, iff the vote outcome cannot change anymore by more people voting. Accordingly, vote replacement and early execution are /// mutually exclusive options. /// The outcome cannot change anymore iff the support threshold is met even if all remaining votes are no votes. We call this number the worst-case number of no votes and define it as /// /// $$N_\text{no, worst-case} = N_\text{no, worst-case} + \texttt{remainingVotes}$$ /// /// where /// /// $$\texttt{remainingVotes} = N_\text{total}-\underbrace{(N_\text{yes}+N_\text{no}+N_\text{abstain})}_{\text{turnout}}.$$ /// /// We can use this quantity to calculate the worst-case support that would be obtained if all remaining votes are casted with no: /// /// $$ /// \begin{align*} /// \texttt{worstCaseSupport} /// &= \frac{N_\text{yes}}{N_\text{yes} + (N_\text{no, worst-case})} \\[3mm] /// &= \frac{N_\text{yes}}{N_\text{yes} + (N_\text{no} + \texttt{remainingVotes})} \\[3mm] /// &= \frac{N_\text{yes}}{N_\text{yes} + N_\text{no} + N_\text{total} - (N_\text{yes} + N_\text{no} + N_\text{abstain})} \\[3mm] /// &= \frac{N_\text{yes}}{N_\text{total} - N_\text{abstain}} /// \end{align*} /// $$ /// /// In analogy, we can modify [the support criterion](#the-support-criterion) from above to allow for early execution: /// /// $$ /// \begin{align*} /// (1 - \texttt{supportThreshold}) \cdot N_\text{yes} /// &> \texttt{supportThreshold} \cdot N_\text{no, worst-case} \\[3mm] /// &> \texttt{supportThreshold} \cdot (N_\text{no} + \texttt{remainingVotes}) \\[3mm] /// &> \texttt{supportThreshold} \cdot (N_\text{no} + N_\text{total}-(N_\text{yes}+N_\text{no}+N_\text{abstain})) \\[3mm] /// &> \texttt{supportThreshold} \cdot (N_\text{total} - N_\text{yes} - N_\text{abstain}) /// \end{align*} /// $$ /// /// Accordingly, early execution is possible when the vote is open, the modified support criterion, and the particicpation criterion are met. /// @dev This contract implements the `IMajorityVoting` interface. abstract contract MajorityVotingBase is IMajorityVoting, Initializable, ERC165Upgradeable, PluginUUPSUpgradeable, ProposalUpgradeable { using SafeCastUpgradeable for uint256; /// @notice The different voting modes available. /// @param Standard In standard mode, early execution and vote replacement are disabled. /// @param EarlyExecution In early execution mode, a proposal can be executed early before the end date if the vote outcome cannot mathematically change by more voters voting. /// @param VoteReplacment In vote replacement mode, voters can change their vote multiple times and only the latest vote option is tallied. enum VotingMode { Standard, EarlyExecution, VoteReplacement } /// @notice A container for the majority voting settings that will be applied as parameters on proposal creation. /// @param votingMode A parameter to select the vote mode. /// @param supportThreshold The support threshold value. Its value has to be in the interval [0, 10^6] defined by `RATIO_BASE = 10**6`. /// @param minParticipation The minimum participation value. Its value has to be in the interval [0, 10^6] defined by `RATIO_BASE = 10**6`. /// @param minDuration The minimum duration of the proposal vote in seconds. /// @param minProposerVotingPower The minimum voting power required to create a proposal. struct VotingSettings { VotingMode votingMode; uint32 supportThreshold; uint32 minParticipation; uint64 minDuration; uint256 minProposerVotingPower; } /// @notice A container for proposal-related information. /// @param executed Whether the proposal is executed or not. /// @param parameters The proposal parameters at the time of the proposal creation. /// @param tally The vote tally of the proposal. /// @param voters The votes casted by the voters. /// @param actions The actions to be executed when the proposal passes. /// @param allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert. If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert. struct Proposal { bool executed; ProposalParameters parameters; Tally tally; mapping(address => IMajorityVoting.VoteOption) voters; IDAO.Action[] actions; uint256 allowFailureMap; } /// @notice A container for the proposal parameters at the time of proposal creation. /// @param votingMode A parameter to select the vote mode. /// @param supportThreshold The support threshold value. The value has to be in the interval [0, 10^6] defined by `RATIO_BASE = 10**6`. /// @param startDate The start date of the proposal vote. /// @param endDate The end date of the proposal vote. /// @param snapshotBlock The number of the block prior to the proposal creation. /// @param minVotingPower The minimum voting power needed. struct ProposalParameters { VotingMode votingMode; uint32 supportThreshold; uint64 startDate; uint64 endDate; uint64 snapshotBlock; uint256 minVotingPower; } /// @notice A container for the proposal vote tally. /// @param abstain The number of abstain votes casted. /// @param yes The number of yes votes casted. /// @param no The number of no votes casted. struct Tally { uint256 abstain; uint256 yes; uint256 no; } /// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract. bytes4 internal constant MAJORITY_VOTING_BASE_INTERFACE_ID = this.minDuration.selector ^ this.minProposerVotingPower.selector ^ this.votingMode.selector ^ this.totalVotingPower.selector ^ this.getProposal.selector ^ this.updateVotingSettings.selector ^ this.createProposal.selector; /// @notice The ID of the permission required to call the `updateVotingSettings` function. bytes32 public constant UPDATE_VOTING_SETTINGS_PERMISSION_ID = keccak256("UPDATE_VOTING_SETTINGS_PERMISSION"); /// @notice A mapping between proposal IDs and proposal information. mapping(uint256 => Proposal) internal proposals; /// @notice The struct storing the voting settings. VotingSettings private votingSettings; /// @notice Thrown if a date is out of bounds. /// @param limit The limit value. /// @param actual The actual value. error DateOutOfBounds(uint64 limit, uint64 actual); /// @notice Thrown if the minimal duration value is out of bounds (less than one hour or greater than 1 year). /// @param limit The limit value. /// @param actual The actual value. error MinDurationOutOfBounds(uint64 limit, uint64 actual); /// @notice Thrown when a sender is not allowed to create a proposal. /// @param sender The sender address. error ProposalCreationForbidden(address sender); /// @notice Thrown if an account is not allowed to cast a vote. This can be because the vote /// - has not started, /// - has ended, /// - was executed, or /// - the account doesn't have voting powers. /// @param proposalId The ID of the proposal. /// @param account The address of the _account. /// @param voteOption The chosen vote option. error VoteCastForbidden(uint256 proposalId, address account, VoteOption voteOption); /// @notice Thrown if the proposal execution is forbidden. /// @param proposalId The ID of the proposal. error ProposalExecutionForbidden(uint256 proposalId); /// @notice Emitted when the voting settings are updated. /// @param votingMode A parameter to select the vote mode. /// @param supportThreshold The support threshold value. /// @param minParticipation The minimum participation value. /// @param minDuration The minimum duration of the proposal vote in seconds. /// @param minProposerVotingPower The minimum voting power required to create a proposal. event VotingSettingsUpdated( VotingMode votingMode, uint32 supportThreshold, uint32 minParticipation, uint64 minDuration, uint256 minProposerVotingPower ); /// @notice Initializes the component to be used by inheriting contracts. /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). /// @param _dao The IDAO interface of the associated DAO. /// @param _votingSettings The voting settings. function __MajorityVotingBase_init( IDAO _dao, VotingSettings calldata _votingSettings ) internal onlyInitializing { __PluginUUPSUpgradeable_init(_dao); _updateVotingSettings(_votingSettings); } /// @notice Checks if this or the parent contract supports an interface by its ID. /// @param _interfaceId The ID of the interface. /// @return Returns `true` if the interface is supported. function supportsInterface( bytes4 _interfaceId ) public view virtual override(ERC165Upgradeable, PluginUUPSUpgradeable, ProposalUpgradeable) returns (bool) { return _interfaceId == MAJORITY_VOTING_BASE_INTERFACE_ID || _interfaceId == type(IMajorityVoting).interfaceId || super.supportsInterface(_interfaceId); } /// @inheritdoc IMajorityVoting function vote( uint256 _proposalId, VoteOption _voteOption, bool _tryEarlyExecution ) public virtual { address account = _msgSender(); if (!_canVote(_proposalId, account, _voteOption)) { revert VoteCastForbidden({ proposalId: _proposalId, account: account, voteOption: _voteOption }); } _vote(_proposalId, _voteOption, account, _tryEarlyExecution); } /// @inheritdoc IMajorityVoting function execute(uint256 _proposalId) public virtual { if (!_canExecute(_proposalId)) { revert ProposalExecutionForbidden(_proposalId); } _execute(_proposalId); } /// @inheritdoc IMajorityVoting function getVoteOption( uint256 _proposalId, address _voter ) public view virtual returns (VoteOption) { return proposals[_proposalId].voters[_voter]; } /// @inheritdoc IMajorityVoting function canVote( uint256 _proposalId, address _voter, VoteOption _voteOption ) public view virtual returns (bool) { return _canVote(_proposalId, _voter, _voteOption); } /// @inheritdoc IMajorityVoting function canExecute(uint256 _proposalId) public view virtual returns (bool) { return _canExecute(_proposalId); } /// @inheritdoc IMajorityVoting function isSupportThresholdReached(uint256 _proposalId) public view virtual returns (bool) { Proposal storage proposal_ = proposals[_proposalId]; // The code below implements the formula of the support criterion explained in the top of this file. // `(1 - supportThreshold) * N_yes > supportThreshold * N_no` return (RATIO_BASE - proposal_.parameters.supportThreshold) * proposal_.tally.yes > proposal_.parameters.supportThreshold * proposal_.tally.no; } /// @inheritdoc IMajorityVoting function isSupportThresholdReachedEarly( uint256 _proposalId ) public view virtual returns (bool) { Proposal storage proposal_ = proposals[_proposalId]; uint256 noVotesWorstCase = totalVotingPower(proposal_.parameters.snapshotBlock) - proposal_.tally.yes - proposal_.tally.abstain; // The code below implements the formula of the early execution support criterion explained in the top of this file. // `(1 - supportThreshold) * N_yes > supportThreshold * N_no,worst-case` return (RATIO_BASE - proposal_.parameters.supportThreshold) * proposal_.tally.yes > proposal_.parameters.supportThreshold * noVotesWorstCase; } /// @inheritdoc IMajorityVoting function isMinParticipationReached(uint256 _proposalId) public view virtual returns (bool) { Proposal storage proposal_ = proposals[_proposalId]; // The code below implements the formula of the participation criterion explained in the top of this file. // `N_yes + N_no + N_abstain >= minVotingPower = minParticipation * N_total` return proposal_.tally.yes + proposal_.tally.no + proposal_.tally.abstain >= proposal_.parameters.minVotingPower; } /// @inheritdoc IMajorityVoting function supportThreshold() public view virtual returns (uint32) { return votingSettings.supportThreshold; } /// @inheritdoc IMajorityVoting function minParticipation() public view virtual returns (uint32) { return votingSettings.minParticipation; } /// @notice Returns the minimum duration parameter stored in the voting settings. /// @return The minimum duration parameter. function minDuration() public view virtual returns (uint64) { return votingSettings.minDuration; } /// @notice Returns the minimum voting power required to create a proposa stored in the voting settings. /// @return The minimum voting power required to create a proposal. function minProposerVotingPower() public view virtual returns (uint256) { return votingSettings.minProposerVotingPower; } /// @notice Returns the vote mode stored in the voting settings. /// @return The vote mode parameter. function votingMode() public view virtual returns (VotingMode) { return votingSettings.votingMode; } /// @notice Returns the total voting power checkpointed for a specific block number. /// @param _blockNumber The block number. /// @return The total voting power. function totalVotingPower(uint256 _blockNumber) public view virtual returns (uint256); /// @notice Returns all information for a proposal vote by its ID. /// @param _proposalId The ID of the proposal. /// @return open Whether the proposal is open or not. /// @return executed Whether the proposal is executed or not. /// @return parameters The parameters of the proposal vote. /// @return tally The current tally of the proposal vote. /// @return actions The actions to be executed in the associated DAO after the proposal has passed. /// @return allowFailureMap The bit map representations of which actions are allowed to revert so tx still succeeds. function getProposal( uint256 _proposalId ) public view virtual returns ( bool open, bool executed, ProposalParameters memory parameters, Tally memory tally, IDAO.Action[] memory actions, uint256 allowFailureMap ) { Proposal storage proposal_ = proposals[_proposalId]; open = _isProposalOpen(proposal_); executed = proposal_.executed; parameters = proposal_.parameters; tally = proposal_.tally; actions = proposal_.actions; allowFailureMap = proposal_.allowFailureMap; } /// @notice Updates the voting settings. /// @param _votingSettings The new voting settings. function updateVotingSettings( VotingSettings calldata _votingSettings ) external virtual auth(UPDATE_VOTING_SETTINGS_PERMISSION_ID) { _updateVotingSettings(_votingSettings); } /// @notice Creates a new majority voting proposal. /// @param _metadata The metadata of the proposal. /// @param _actions The actions that will be executed after the proposal passes. /// @param _allowFailureMap Allows proposal to succeed even if an action reverts. Uses bitmap representation. If the bit at index `x` is 1, the tx succeeds even if the action at `x` failed. Passing 0 will be treated as atomic execution. /// @param _startDate The start date of the proposal vote. If 0, the current timestamp is used and the vote starts immediately. /// @param _endDate The end date of the proposal vote. If 0, `_startDate + minDuration` is used. /// @param _voteOption The chosen vote option to be casted on proposal creation. /// @param _tryEarlyExecution If `true`, early execution is tried after the vote cast. The call does not revert if early execution is not possible. /// @return proposalId The ID of the proposal. function createProposal( bytes calldata _metadata, IDAO.Action[] calldata _actions, uint256 _allowFailureMap, uint64 _startDate, uint64 _endDate, VoteOption _voteOption, bool _tryEarlyExecution ) external virtual returns (uint256 proposalId); /// @notice Internal function to cast a vote. It assumes the queried vote exists. /// @param _proposalId The ID of the proposal. /// @param _voteOption The chosen vote option to be casted on the proposal vote. /// @param _tryEarlyExecution If `true`, early execution is tried after the vote cast. The call does not revert if early execution is not possible. function _vote( uint256 _proposalId, VoteOption _voteOption, address _voter, bool _tryEarlyExecution ) internal virtual; /// @notice Internal function to execute a vote. It assumes the queried proposal exists. /// @param _proposalId The ID of the proposal. function _execute(uint256 _proposalId) internal virtual { proposals[_proposalId].executed = true; _executeProposal( dao(), _proposalId, proposals[_proposalId].actions, proposals[_proposalId].allowFailureMap ); } /// @notice Internal function to check if a voter can vote. It assumes the queried proposal exists. /// @param _proposalId The ID of the proposal. /// @param _voter The address of the voter to check. /// @param _voteOption Whether the voter abstains, supports or opposes the proposal. /// @return Returns `true` if the given voter can vote on a certain proposal and `false` otherwise. function _canVote( uint256 _proposalId, address _voter, VoteOption _voteOption ) internal view virtual returns (bool); /// @notice Internal function to check if a proposal can be executed. It assumes the queried proposal exists. /// @param _proposalId The ID of the proposal. /// @return True if the proposal can be executed, false otherwise. /// @dev Threshold and minimal values are compared with `>` and `>=` comparators, respectively. function _canExecute(uint256 _proposalId) internal view virtual returns (bool) { Proposal storage proposal_ = proposals[_proposalId]; // Verify that the vote has not been executed already. if (proposal_.executed) { return false; } if (_isProposalOpen(proposal_)) { // Early execution if (proposal_.parameters.votingMode != VotingMode.EarlyExecution) { return false; } if (!isSupportThresholdReachedEarly(_proposalId)) { return false; } } else { // Normal execution if (!isSupportThresholdReached(_proposalId)) { return false; } } if (!isMinParticipationReached(_proposalId)) { return false; } return true; } /// @notice Internal function to check if a proposal vote is still open. /// @param proposal_ The proposal struct. /// @return True if the proposal vote is open, false otherwise. function _isProposalOpen(Proposal storage proposal_) internal view virtual returns (bool) { uint64 currentTime = block.timestamp.toUint64(); return proposal_.parameters.startDate <= currentTime && currentTime < proposal_.parameters.endDate && !proposal_.executed; } /// @notice Internal function to update the plugin-wide proposal vote settings. /// @param _votingSettings The voting settings to be validated and updated. function _updateVotingSettings(VotingSettings calldata _votingSettings) internal virtual { // Require the support threshold value to be in the interval [0, 10^6-1], because `>` comparision is used in the support criterion and >100% could never be reached. if (_votingSettings.supportThreshold > RATIO_BASE - 1) { revert RatioOutOfBounds({ limit: RATIO_BASE - 1, actual: _votingSettings.supportThreshold }); } // Require the minimum participation value to be in the interval [0, 10^6], because `>=` comparision is used in the participation criterion. if (_votingSettings.minParticipation > RATIO_BASE) { revert RatioOutOfBounds({limit: RATIO_BASE, actual: _votingSettings.minParticipation}); } if (_votingSettings.minDuration < 60 minutes) { revert MinDurationOutOfBounds({limit: 60 minutes, actual: _votingSettings.minDuration}); } if (_votingSettings.minDuration > 365 days) { revert MinDurationOutOfBounds({limit: 365 days, actual: _votingSettings.minDuration}); } votingSettings = _votingSettings; emit VotingSettingsUpdated({ votingMode: _votingSettings.votingMode, supportThreshold: _votingSettings.supportThreshold, minParticipation: _votingSettings.minParticipation, minDuration: _votingSettings.minDuration, minProposerVotingPower: _votingSettings.minProposerVotingPower }); } /// @notice Validates and returns the proposal vote dates. /// @param _start The start date of the proposal vote. If 0, the current timestamp is used and the vote starts immediately. /// @param _end The end date of the proposal vote. If 0, `_start + minDuration` is used. /// @return startDate The validated start date of the proposal vote. /// @return endDate The validated end date of the proposal vote. function _validateProposalDates( uint64 _start, uint64 _end ) internal view virtual returns (uint64 startDate, uint64 endDate) { uint64 currentTimestamp = block.timestamp.toUint64(); if (_start == 0) { startDate = currentTimestamp; } else { startDate = _start; if (startDate < currentTimestamp) { revert DateOutOfBounds({limit: currentTimestamp, actual: startDate}); } } uint64 earliestEndDate = startDate + votingSettings.minDuration; // Since `minDuration` is limited to 1 year, `startDate + minDuration` can only overflow if the `startDate` is after `type(uint64).max - minDuration`. In this case, the proposal creation will revert and another date can be picked. if (_end == 0) { endDate = earliestEndDate; } else { endDate = _end; if (endDate < earliestEndDate) { revert DateOutOfBounds({limit: earliestEndDate, actual: endDate}); } } } /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZepplins guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). uint256[47] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; import {IMembership} from "../../../../core/plugin/membership/IMembership.sol"; import {IDAO} from "../../../../core/dao/IDAO.sol"; import {RATIO_BASE, _applyRatioCeiled} from "../../../utils/Ratio.sol"; import {MajorityVotingBase} from "../MajorityVotingBase.sol"; import {IMajorityVoting} from "../IMajorityVoting.sol"; /// @title TokenVoting /// @author Aragon Association - 2021-2023 /// @notice The majority voting implementation using an [OpenZepplin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible governance token. /// @dev This contract inherits from `MajorityVotingBase` and implements the `IMajorityVoting` interface. contract TokenVoting is IMembership, MajorityVotingBase { using SafeCastUpgradeable for uint256; /// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract. bytes4 internal constant TOKEN_VOTING_INTERFACE_ID = this.initialize.selector ^ this.getVotingToken.selector; /// @notice An [OpenZepplin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible contract referencing the token being used for voting. IVotesUpgradeable private votingToken; /// @notice Thrown if the voting power is zero error NoVotingPower(); /// @notice Initializes the component. /// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822). /// @param _dao The IDAO interface of the associated DAO. /// @param _votingSettings The voting settings. /// @param _token The [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token used for voting. function initialize( IDAO _dao, VotingSettings calldata _votingSettings, IVotesUpgradeable _token ) external initializer { __MajorityVotingBase_init(_dao, _votingSettings); votingToken = _token; emit MembershipContractAnnounced({definingContract: address(_token)}); } /// @notice Checks if this or the parent contract supports an interface by its ID. /// @param _interfaceId The ID of the interface. /// @return Returns `true` if the interface is supported. function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { return _interfaceId == TOKEN_VOTING_INTERFACE_ID || _interfaceId == type(IMembership).interfaceId || super.supportsInterface(_interfaceId); } /// @notice getter function for the voting token. /// @dev public function also useful for registering interfaceId and for distinguishing from majority voting interface. /// @return The token used for voting. function getVotingToken() public view returns (IVotesUpgradeable) { return votingToken; } /// @inheritdoc MajorityVotingBase function totalVotingPower(uint256 _blockNumber) public view override returns (uint256) { return votingToken.getPastTotalSupply(_blockNumber); } /// @inheritdoc MajorityVotingBase function createProposal( bytes calldata _metadata, IDAO.Action[] calldata _actions, uint256 _allowFailureMap, uint64 _startDate, uint64 _endDate, VoteOption _voteOption, bool _tryEarlyExecution ) external override returns (uint256 proposalId) { uint256 snapshotBlock; unchecked { snapshotBlock = block.number - 1; } uint256 totalVotingPower_ = totalVotingPower(snapshotBlock); if (totalVotingPower_ == 0) { revert NoVotingPower(); } if (votingToken.getPastVotes(_msgSender(), snapshotBlock) < minProposerVotingPower()) { revert ProposalCreationForbidden(_msgSender()); } proposalId = _createProposal({ _creator: _msgSender(), _metadata: _metadata, _startDate: _startDate, _endDate: _endDate, _actions: _actions, _allowFailureMap: _allowFailureMap }); // Store proposal related information Proposal storage proposal_ = proposals[proposalId]; (proposal_.parameters.startDate, proposal_.parameters.endDate) = _validateProposalDates( _startDate, _endDate ); proposal_.parameters.snapshotBlock = snapshotBlock.toUint64(); proposal_.parameters.votingMode = votingMode(); proposal_.parameters.supportThreshold = supportThreshold(); proposal_.parameters.minVotingPower = _applyRatioCeiled( totalVotingPower_, minParticipation() ); // Reduce costs if (_allowFailureMap != 0) { proposal_.allowFailureMap = _allowFailureMap; } for (uint256 i; i < _actions.length; ) { proposal_.actions.push(_actions[i]); unchecked { ++i; } } if (_voteOption != VoteOption.None) { vote(proposalId, _voteOption, _tryEarlyExecution); } } /// @inheritdoc IMembership function isMember(address _account) external view returns (bool) { /// whatever condition return votingToken.getVotes(_account) > 0; } /// @inheritdoc MajorityVotingBase function _vote( uint256 _proposalId, VoteOption _voteOption, address _voter, bool _tryEarlyExecution ) internal override { Proposal storage proposal_ = proposals[_proposalId]; // This could re-enter, though we can assume the governance token is not malicious uint256 votingPower = votingToken.getPastVotes(_voter, proposal_.parameters.snapshotBlock); VoteOption state = proposal_.voters[_voter]; // If voter had previously voted, decrease count if (state == VoteOption.Yes) { proposal_.tally.yes = proposal_.tally.yes - votingPower; } else if (state == VoteOption.No) { proposal_.tally.no = proposal_.tally.no - votingPower; } else if (state == VoteOption.Abstain) { proposal_.tally.abstain = proposal_.tally.abstain - votingPower; } // write the updated/new vote for the voter. if (_voteOption == VoteOption.Yes) { proposal_.tally.yes = proposal_.tally.yes + votingPower; } else if (_voteOption == VoteOption.No) { proposal_.tally.no = proposal_.tally.no + votingPower; } else if (_voteOption == VoteOption.Abstain) { proposal_.tally.abstain = proposal_.tally.abstain + votingPower; } proposal_.voters[_voter] = _voteOption; emit VoteCast({ proposalId: _proposalId, voter: _voter, voteOption: _voteOption, votingPower: votingPower }); if (_tryEarlyExecution && _canExecute(_proposalId)) { _execute(_proposalId); } } /// @inheritdoc MajorityVotingBase function _canVote( uint256 _proposalId, address _account, VoteOption _voteOption ) internal view override returns (bool) { Proposal storage proposal_ = proposals[_proposalId]; // The proposal vote hasn't started or has already ended. if (!_isProposalOpen(proposal_)) { return false; } // The voter votes `None` which is not allowed. if (_voteOption == VoteOption.None) { return false; } // The voter has no voting power. if (votingToken.getPastVotes(_account, proposal_.parameters.snapshotBlock) == 0) { return false; } // The voter has already voted but vote replacment is not allowed. if ( proposal_.voters[_account] != VoteOption.None && proposal_.parameters.votingMode != VotingMode.VoteReplacement ) { return false; } return true; } /// @dev This empty reserved space is put in place to allow future versions to add new /// variables without shifting down storage in the inheritance chain. /// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps uint256[49] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; // The base value to encode real-valued ratios on the interval `[0,1]` as integers on the interval `[0, 10**6]`. uint256 constant RATIO_BASE = 10 ** 6; /// @notice Thrown if a ratio value exceeds the maximal value of `10**6`. /// @param limit The maximal value. /// @param actual The actual value. error RatioOutOfBounds(uint256 limit, uint256 actual); /// @notice Applies a ratio to a value and ceils the remainder. /// @param _value The value to which the ratio is applied. /// @param _ratio The ratio that must be in the interval `[0, 10**6]`. /// @return result The resulting value. function _applyRatioCeiled(uint256 _value, uint256 _ratio) pure returns (uint256 result) { if (_ratio > RATIO_BASE) { revert RatioOutOfBounds({limit: RATIO_BASE, actual: _ratio}); } _value = _value * _ratio; uint256 remainder = _value % RATIO_BASE; result = _value / RATIO_BASE; // Check if ceiling is needed if (remainder != 0) { ++result; } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {IERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol"; import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; import {ERC20VotesUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; import {DaoAuthorizableUpgradeable} from "../../../core/plugin/dao-authorizable/DaoAuthorizableUpgradeable.sol"; import {IDAO} from "../../../core/dao/IDAO.sol"; import {IERC20MintableUpgradeable} from "../IERC20MintableUpgradeable.sol"; /// @title GovernanceERC20 /// @author Aragon Association /// @notice An [OpenZepplin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) compatible [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token that can be used for voting and is managed by a DAO. contract GovernanceERC20 is IERC20MintableUpgradeable, Initializable, ERC165Upgradeable, ERC20VotesUpgradeable, DaoAuthorizableUpgradeable { /// @notice The permission identifier to mint new tokens bytes32 public constant MINT_PERMISSION_ID = keccak256("MINT_PERMISSION"); /// @notice The settings for the initial mint of the token. /// @param receivers The receivers of the tokens. /// @param amounts The amounts of tokens to be minted for each receiver. /// @dev The lengths of `receivers` and `amounts` must match. struct MintSettings { address[] receivers; uint256[] amounts; } /// @notice Thrown if the number of receivers and amounts specified in the mint settings do not match. /// @param receiversArrayLength The length of the `receivers` array. /// @param amountsArrayLength The length of the `amounts` array. error MintSettingsArrayLengthMismatch(uint256 receiversArrayLength, uint256 amountsArrayLength); /// @notice Calls the initialize function. /// @param _dao The managing DAO. /// @param _name The name of the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) governance token. /// @param _symbol The symbol fo the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) governance token. /// @param _mintSettings The token mint settings struct containing the `receivers` and `amounts`. constructor( IDAO _dao, string memory _name, string memory _symbol, MintSettings memory _mintSettings ) { initialize(_dao, _name, _symbol, _mintSettings); } /// @notice Initializes the contract and mints tokens to a list of receivers. /// @param _dao The managing DAO. /// @param _name The name of the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) governance token. /// @param _symbol The symbol fo the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) governance token. /// @param _mintSettings The token mint settings struct containing the `receivers` and `amounts`. function initialize( IDAO _dao, string memory _name, string memory _symbol, MintSettings memory _mintSettings ) public initializer { // Check mint settings if (_mintSettings.receivers.length != _mintSettings.amounts.length) { revert MintSettingsArrayLengthMismatch({ receiversArrayLength: _mintSettings.receivers.length, amountsArrayLength: _mintSettings.amounts.length }); } __ERC20_init(_name, _symbol); __ERC20Permit_init(_name); __DaoAuthorizableUpgradeable_init(_dao); for (uint256 i; i < _mintSettings.receivers.length; ) { _mint(_mintSettings.receivers[i], _mintSettings.amounts[i]); unchecked { ++i; } } } /// @notice Checks if this or the parent contract supports an interface by its ID. /// @param _interfaceId The ID of the interface. /// @return Returns `true` if the interface is supported. function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { return _interfaceId == type(IERC20Upgradeable).interfaceId || _interfaceId == type(IERC20PermitUpgradeable).interfaceId || _interfaceId == type(IERC20MetadataUpgradeable).interfaceId || _interfaceId == type(IVotesUpgradeable).interfaceId || _interfaceId == type(IERC20MintableUpgradeable).interfaceId || super.supportsInterface(_interfaceId); } /// @notice Mints tokens to an address. /// @param to The address receiving the tokens. /// @param amount The amount of tokens to be minted. function mint(address to, uint256 amount) external override auth(MINT_PERMISSION_ID) { _mint(to, amount); } // https://forum.openzeppelin.com/t/self-delegation-in-erc20votes/17501/12?u=novaknole /// @inheritdoc ERC20VotesUpgradeable function _afterTokenTransfer(address from, address to, uint256 amount) internal override { super._afterTokenTransfer(from, to, amount); // Automatically turn on delegation on mint/transfer but only for the first time. if (to != address(0) && numCheckpoints(to) == 0 && delegates(to) == address(0)) { _delegate(to, to); } } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import {ERC20WrapperUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol"; import {IVotesUpgradeable} from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; import {IERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol"; import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; import {ERC20VotesUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; import {DaoAuthorizableUpgradeable} from "../../../core/plugin/dao-authorizable/DaoAuthorizableUpgradeable.sol"; import {IDAO} from "../../../core/dao/IDAO.sol"; import {IGovernanceWrappedERC20} from "./IGovernanceWrappedERC20.sol"; /// @title GovernanceWrappedERC20 /// @author Aragon Association /// @notice Wraps an existing [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token by inheriting from `ERC20WrapperUpgradeable` and allows to use it for voting by inheriting from `ERC20VotesUpgradeable`. The latter is compatible with [OpenZepplin `Votes`](https://docs.openzeppelin.com/contracts/4.x/api/governance#Votes) interface. /// The contract also supports meta transactions. To use an `amount` of underlying tokens for voting, the token owner has to /// 1. call `approve` for the tokens to be used by this contract /// 2. call `depositFor` to wrap them, which safely transfers the underlying [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens to the contract and mints wrapped [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens. /// To get the [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens back, the owner of the wrapped tokens can call `withdrawFor`, which burns the wrapped tokens [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens and safely transfers the underlying tokens back to the owner. /// @dev This contract intentionally has no public mint functionality because this is the responsibility of the underlying [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token contract. contract GovernanceWrappedERC20 is IGovernanceWrappedERC20, Initializable, ERC165Upgradeable, ERC20VotesUpgradeable, ERC20WrapperUpgradeable { /// @notice Calls the initialize function. /// @param _token The underlying [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token. /// @param _name The name of the wrapped token. /// @param _symbol The symbol fo the wrapped token. constructor(IERC20Upgradeable _token, string memory _name, string memory _symbol) { initialize(_token, _name, _symbol); } /// @notice Initializes the contract. /// @param _token The underlying [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token. /// @param _name The name of the wrapped token. /// @param _symbol The symbol fo the wrapped token. function initialize( IERC20Upgradeable _token, string memory _name, string memory _symbol ) public initializer { __ERC20_init(_name, _symbol); __ERC20Permit_init(_name); __ERC20Wrapper_init(_token); } /// @notice Checks if this or the parent contract supports an interface by its ID. /// @param _interfaceId The ID of the interface. /// @return Returns `true` if the interface is supported. function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) { return _interfaceId == type(IGovernanceWrappedERC20).interfaceId || _interfaceId == type(IERC20Upgradeable).interfaceId || _interfaceId == type(IERC20PermitUpgradeable).interfaceId || _interfaceId == type(IERC20MetadataUpgradeable).interfaceId || _interfaceId == type(IVotesUpgradeable).interfaceId || super.supportsInterface(_interfaceId); } /// @inheritdoc ERC20WrapperUpgradeable /// @dev Uses the `decimals` of the underlying [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token. function decimals() public view override(ERC20Upgradeable, ERC20WrapperUpgradeable) returns (uint8) { return ERC20WrapperUpgradeable.decimals(); } /// @inheritdoc IGovernanceWrappedERC20 function depositFor( address account, uint256 amount ) public override(IGovernanceWrappedERC20, ERC20WrapperUpgradeable) returns (bool) { return ERC20WrapperUpgradeable.depositFor(account, amount); } /// @inheritdoc IGovernanceWrappedERC20 function withdrawTo( address account, uint256 amount ) public override(IGovernanceWrappedERC20, ERC20WrapperUpgradeable) returns (bool) { return ERC20WrapperUpgradeable.withdrawTo(account, amount); } // https://forum.openzeppelin.com/t/self-delegation-in-erc20votes/17501/12?u=novaknole /// @inheritdoc ERC20VotesUpgradeable function _afterTokenTransfer( address from, address to, uint256 amount ) internal override(ERC20VotesUpgradeable, ERC20Upgradeable) { super._afterTokenTransfer(from, to, amount); // Automatically turn on delegation on mint/transfer but only for the first time. if (to != address(0) && numCheckpoints(to) == 0 && delegates(to) == address(0)) { _delegate(to, to); } } /// @inheritdoc ERC20VotesUpgradeable function _mint( address to, uint256 amount ) internal override(ERC20VotesUpgradeable, ERC20Upgradeable) { super._mint(to, amount); } /// @inheritdoc ERC20VotesUpgradeable function _burn( address account, uint256 amount ) internal override(ERC20VotesUpgradeable, ERC20Upgradeable) { super._burn(account, amount); } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import {ERC20WrapperUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol"; interface IGovernanceWrappedERC20 { /// @notice Deposits an amount of underlying token and mints the corresponding number of wrapped tokens for an receiving address. /// @param account The address receiving the minted, wrapped tokens. /// @param amount The amount of tokens to be minted. function depositFor(address account, uint256 amount) external returns (bool); /// @notice Withdraws an amount of underlying tokens to an receiving address and burns the corresponding number of wrapped tokens. /// @param account The address receiving the withdrawn, underlying tokens. /// @param amount The amount of underlying tokens to be withdrawn. function withdrawTo(address account, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; /// @title IERC20MintableUpgradeable /// @notice Interface to allow minting of [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens. interface IERC20MintableUpgradeable { /// @notice Mints [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens for a receiving address. /// @param _to The receiving address. /// @param _amount The amount of tokens. function mint(address _to, uint256 _amount) external; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.17; import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; /// @notice Free function to create a [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) proxy contract based on the passed base contract address. /// @param _logic The base contract address. /// @param _data The constructor arguments for this contract. /// @return The address of the proxy contract created. /// @dev Initializes the upgradeable proxy with an initial implementation specified by _logic. If _data is non-empty, it’s used as data in a delegate call to _logic. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor (see [OpenZepplin ERC1967Proxy-constructor](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Proxy-constructor-address-bytes-)). function createERC1967Proxy(address _logic, bytes memory _data) returns (address) { return address(new ERC1967Proxy(_logic, _data)); }
{ "optimizer": { "enabled": true, "runs": 2000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"TokenNotContract","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"TokenNotERC20","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"WrongHelpersArrayLength","type":"error"},{"inputs":[],"name":"governanceERC20Base","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceWrappedERC20Base","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dao","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"prepareInstallation","outputs":[{"internalType":"address","name":"plugin","type":"address"},{"components":[{"internalType":"address[]","name":"helpers","type":"address[]"},{"components":[{"internalType":"enum PermissionLib.Operation","name":"operation","type":"uint8"},{"internalType":"address","name":"where","type":"address"},{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"condition","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"}],"internalType":"struct PermissionLib.MultiTargetPermission[]","name":"permissions","type":"tuple[]"}],"internalType":"struct IPluginSetup.PreparedSetupData","name":"preparedSetupData","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dao","type":"address"},{"components":[{"internalType":"address","name":"plugin","type":"address"},{"internalType":"address[]","name":"currentHelpers","type":"address[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IPluginSetup.SetupPayload","name":"_payload","type":"tuple"}],"name":"prepareUninstallation","outputs":[{"components":[{"internalType":"enum PermissionLib.Operation","name":"operation","type":"uint8"},{"internalType":"address","name":"where","type":"address"},{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"condition","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"}],"internalType":"struct PermissionLib.MultiTargetPermission[]","name":"permissions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dao","type":"address"},{"internalType":"uint16","name":"_currentBuild","type":"uint16"},{"components":[{"internalType":"address","name":"plugin","type":"address"},{"internalType":"address[]","name":"currentHelpers","type":"address[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IPluginSetup.SetupPayload","name":"_payload","type":"tuple"}],"name":"prepareUpdate","outputs":[{"internalType":"bytes","name":"initData","type":"bytes"},{"components":[{"internalType":"address[]","name":"helpers","type":"address[]"},{"components":[{"internalType":"enum PermissionLib.Operation","name":"operation","type":"uint8"},{"internalType":"address","name":"where","type":"address"},{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"condition","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"}],"internalType":"struct PermissionLib.MultiTargetPermission[]","name":"permissions","type":"tuple[]"}],"internalType":"struct IPluginSetup.PreparedSetupData","name":"preparedSetupData","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60e06040523480156200001157600080fd5b506040805160008183018181526060830184528252825181815260208082018552830152915162000042906200011f565b6200004f92919062000149565b604051809103906000f0801580156200006c573d6000803e3d6000fd5b506001600160a01b031660a0526040516000906200008a906200012d565b6001600160a01b039091168152606060208201819052600090820181905260806040830181905282015260a001604051809103906000f080158015620000d4573d6000803e3d6000fd5b506001600160a01b031660c052604051620000ef906200013b565b604051809103906000f0801580156200010c573d6000803e3d6000fd5b506001600160a01b031660805262000214565b613ad8806200297383390190565b613472806200644b83390190565b61393180620098bd83390190565b600060018060a01b03808516835260206080818501526000608085015260a06040850152600060a085015260c0606085015261010084018551604060c0870152818151808452610120880191508483019350600092505b80831015620001c457835186168252928401926001929092019190840190620001a0565b508784015187820360bf190160e0890152805180835290850195509084019250905060005b818110156200020757845183529383019391830191600101620001e9565b5090979650505050505050565b60805160a05160c0516127006200027360003960008181610173015261099201526000818160be0152610a5a01526000818160fb01528181610404015281816104fe01528181610b5001528181610ca70152610d9101526127006000f3fe60806040523480156200001157600080fd5b5060043610620000875760003560e01c80639cb0a12411620000625780639cb0a1241462000120578063a8a9c29e1462000146578063e89b6b91146200016d578063f10832f1146200019557600080fd5b806301ffc9a7146200008c578063599cb1a614620000b85780635c60da1b14620000f9575b600080fd5b620000a36200009d366004620014ae565b620001bc565b60405190151581526020015b60405180910390f35b620000e07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001620000af565b7f0000000000000000000000000000000000000000000000000000000000000000620000e0565b62000137620001313660046200150b565b6200020d565b604051620000af9190620015d4565b6200015d6200015736600462001621565b6200075f565b604051620000af92919062001795565b620000e07f000000000000000000000000000000000000000000000000000000000000000081565b620001ac620001a6366004620017c7565b62000787565b604051620000af92919062001851565b60006001600160e01b031982167f99718b500000000000000000000000000000000000000000000000000000000014806200020757506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600062000220602084018462001875565b9150506001811462000266576040517ff14c61fc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b600062000277602085018562001875565b60008181106200028b576200028b620018e7565b9050602002016020810190620002a29190620018fd565b90506000620002b18262000fec565b9050600081600081518110620002cb57620002cb620018e7565b60200260200101518015620002fa575081600181518110620002f157620002f1620018e7565b60200260200101515b801562000322575081600281518110620003185762000318620018e7565b6020026020010151155b9050806200033257600362000335565b60045b60ff1667ffffffffffffffff8111156200035357620003536200191b565b604051908082528060200260200182016040528015620003ae57816020015b6040805160a081018252600080825260208083018290529282018190526060820181905260808201528252600019909201910181620003725790505b506040805160a0810190915260018152909550602080820190620003d590890189620018fd565b6001600160a01b03168152602001886001600160a01b0316815260200160006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631befc4056040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000461573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000487919062001931565b81525085600081518110620004a057620004a0620018e7565b60209081029190910101526040805160a081019091528060018152602090810190620004cf90890189620018fd565b6001600160a01b03168152602001886001600160a01b0316815260200160006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c9c4bfca6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200055b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000581919062001931565b815250856001815181106200059a576200059a620018e7565b60209081029190910101526040805160a081019091528060018152602001886001600160a01b03168152602001876000016020810190620005dc9190620018fd565b6001600160a01b0316815260200160006001600160a01b03168152602001886001600160a01b0316630729d0546040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000639573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200065f919062001931565b81525085600281518110620006785762000678620018e7565b6020026020010181905250801562000755576040805160a081019091528060018152602001846001600160a01b03168152602001886001600160a01b0316815260200160006001600160a01b03168152602001846001600160a01b031663b2d2989c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200070a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000730919062001931565b81525085600381518110620007495762000749620018e7565b60200260200101819052505b5050505092915050565b60606200077f604051806040016040528060608152602001606081525090565b935093915050565b6000620007a7604051806040016040528060608152602001606081525090565b60008080620007b98688018862001c6f565b815160408051600180825281830190925294975092955090935091600091602080830190803683370190505090506001600160a01b0382161562000a54576001600160a01b0382163b62000845576040517f18aca2db0000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024016200025d565b620008508262001130565b62000893576040517ffa8925f10000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024016200025d565b6000620008a08362000fec565b905080600081518110620008b857620008b8620018e7565b6020026020010151158015620008e9575080600181518110620008df57620008df620018e7565b6020026020010151155b801562000911575080600281518110620009075762000907620018e7565b6020026020010151155b80620009865750806000815181106200092e576200092e620018e7565b602002602001015180156200095e575080600181518110620009545762000954620018e7565b6020026020010151155b8015620009865750806002815181106200097c576200097c620018e7565b6020026020010151155b1562000a4d57620009c07f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031662001200565b8551602087015160408089015190517f906571470000000000000000000000000000000000000000000000000000000081529396506001600160a01b0387169363906571479362000a18939092909160040162001d52565b600060405180830381600087803b15801562000a3357600080fd5b505af115801562000a48573d6000803e3d6000fd5b505050505b5062000b13565b62000a887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031662001200565b602085015160408087015190517fdab27fa90000000000000000000000000000000000000000000000000000000081529294506001600160a01b0385169263dab27fa99262000ade928f92899060040162001d94565b600060405180830381600087803b15801562000af957600080fd5b505af115801562000b0e573d6000803e3d6000fd5b505050505b818160008151811062000b2a5762000b2a620018e7565b60200260200101906001600160a01b031690816001600160a01b03168152505062000bc67f000000000000000000000000000000000000000000000000000000000000000063b2673b0760e01b8c888660405160240162000b8e9392919062001e3c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152620012bd565b84519097506000906001600160a01b031662000be457600462000be7565b60035b60ff1667ffffffffffffffff81111562000c055762000c056200191b565b60405190808252806020026020018201604052801562000c6057816020015b6040805160a08101825260008082526020808301829052928201819052606082018190526080820152825260001990920191018162000c245790505b506040805160a081019091529091508060008152602001896001600160a01b031681526020018c6001600160a01b0316815260200160006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631befc4056040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d04573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d2a919062001931565b8152508160008151811062000d435762000d43620018e7565b60209081029190910101526040805160a081019091528060008152602001896001600160a01b031681526020018c6001600160a01b0316815260200160006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c9c4bfca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000dee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e14919062001931565b8152508160018151811062000e2d5762000e2d620018e7565b60209081029190910101526040805160a0810190915280600081526020018c6001600160a01b03168152602001896001600160a01b0316815260200160006001600160a01b031681526020018c6001600160a01b0316630729d0546040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000eb8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ede919062001931565b8152508160028151811062000ef75762000ef7620018e7565b602090810291909101015284516001600160a01b031662000fd5576000836001600160a01b031663b2d2989c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000f53573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f79919062001931565b6040805160a0810190915290915080600081526001600160a01b0380871660208301528e1660408201526000606082015260800182905282518390600390811062000fc85762000fc8620018e7565b6020026020010181905250505b908652602086015250939792965091945050505050565b60408051600380825260808201909252606091600091906020820184803683370190505090507f36372b070000000000000000000000000000000000000000000000000000000081600081518110620010495762001049620018e7565b60200260200101906001600160e01b03191690816001600160e01b031916815250507fe90fb3f60000000000000000000000000000000000000000000000000000000081600181518110620010a257620010a2620018e7565b60200260200101906001600160e01b03191690816001600160e01b031916815250507f0f13099a0000000000000000000000000000000000000000000000000000000081600281518110620010fb57620010fb620018e7565b6001600160e01b031990921660209283029190910190910152620011296001600160a01b03841682620012cb565b9392505050565b604080513060248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f70a08231000000000000000000000000000000000000000000000000000000001790529051600091829182916001600160a01b03861691620011a2919062001eb2565b600060405180830381855afa9150503d8060008114620011df576040519150601f19603f3d011682016040523d82523d6000602084013e620011e4565b606091505b5091509150818015620011f8575080516020145b949350505050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b038116620012b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f455243313136373a20637265617465206661696c65640000000000000000000060448201526064016200025d565b919050565b6000620011298383620013a1565b60606000825167ffffffffffffffff811115620012ec57620012ec6200191b565b60405190808252806020026020018201604052801562001316578160200160208202803683370190505b5090506200132484620013dd565b15620011295760005b835181101562001399576200135f85858381518110620013515762001351620018e7565b602002602001015162001415565b828281518110620013745762001374620018e7565b9115156020928302919091019091015280620013908162001ed0565b9150506200132d565b509392505050565b60008282604051620013b390620014a0565b620013c092919062001ef9565b604051809103906000f08015801562001399573d6000803e3d6000fd5b6000620013f2826301ffc9a760e01b62001415565b80156200020757506200140e826001600160e01b031962001415565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d9150600051905082801562001488575060208210155b8015620014955750600081115b979650505050505050565b6107ad8062001f1e83390190565b600060208284031215620014c157600080fd5b81356001600160e01b0319811681146200112957600080fd5b80356001600160a01b0381168114620012b857600080fd5b6000606082840312156200150557600080fd5b50919050565b600080604083850312156200151f57600080fd5b6200152a83620014da565b9150602083013567ffffffffffffffff8111156200154757600080fd5b6200155585828601620014f2565b9150509250929050565b600381106200157e57634e487b7160e01b600052602160045260246000fd5b50565b6000815162001590816200155f565b8352506020818101516001600160a01b0390811691840191909152604080830151821690840152606080830151909116908301526080908101519082015260a00190565b6020808252825182820181905260009190848201906040850190845b8181101562001615576200160683855162001581565b938501939250600101620015f0565b50909695505050505050565b6000806000606084860312156200163757600080fd5b6200164284620014da565b9250602084013561ffff811681146200165a57600080fd5b9150604084013567ffffffffffffffff8111156200167757600080fd5b6200168586828701620014f2565b9150509250925092565b60005b83811015620016ac57818101518382015260200162001692565b50506000910152565b60008151808452620016cf8160208601602086016200168f565b601f01601f19169290920160200192915050565b600081518084526020808501945080840160005b838110156200171e5781516001600160a01b031687529582019590820190600101620016f7565b509495945050505050565b6000815160408452620017406040850182620016e3565b60208481015186830387830152805180845290820193509091600091908301905b808310156200178a576200177782865162001581565b9150838501945060018301925062001761565b509695505050505050565b604081526000620017aa6040830185620016b5565b8281036020840152620017be818562001729565b95945050505050565b600080600060408486031215620017dd57600080fd5b620017e884620014da565b9250602084013567ffffffffffffffff808211156200180657600080fd5b818601915086601f8301126200181b57600080fd5b8135818111156200182b57600080fd5b8760208285010111156200183e57600080fd5b6020830194508093505050509250925092565b6001600160a01b0383168152604060208201526000620011f8604083018462001729565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112620018ab57600080fd5b83018035915067ffffffffffffffff821115620018c757600080fd5b6020019150600581901b3603821315620018e057600080fd5b9250929050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200191057600080fd5b6200112982620014da565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156200194457600080fd5b5051919050565b6040805190810167ffffffffffffffff811182821017156200197157620019716200191b565b60405290565b60405160a0810167ffffffffffffffff811182821017156200197157620019716200191b565b604051601f8201601f1916810167ffffffffffffffff81118282101715620019c957620019c96200191b565b604052919050565b803563ffffffff81168114620012b857600080fd5b600082601f830112620019f857600080fd5b813567ffffffffffffffff81111562001a155762001a156200191b565b62001a2a6020601f19601f840116016200199d565b81815284602083860101111562001a4057600080fd5b816020850160208301376000918101602001919091529392505050565b60006060828403121562001a7057600080fd5b6040516060810167ffffffffffffffff828210818311171562001a975762001a976200191b565b8160405282935062001aa985620014da565b8352602085013591508082111562001ac057600080fd5b62001ace86838701620019e6565b6020840152604085013591508082111562001ae857600080fd5b5062001af785828601620019e6565b6040830152505092915050565b600067ffffffffffffffff82111562001b215762001b216200191b565b5060051b60200190565b600082601f83011262001b3d57600080fd5b8135602062001b5662001b508362001b04565b6200199d565b82815260059290921b8401810191818101908684111562001b7657600080fd5b8286015b848110156200178a578035835291830191830162001b7a565b60006040828403121562001ba657600080fd5b62001bb06200194b565b9050813567ffffffffffffffff8082111562001bcb57600080fd5b818401915084601f83011262001be057600080fd5b8135602062001bf362001b508362001b04565b82815260059290921b8401810191818101908884111562001c1357600080fd5b948201945b8386101562001c3c5762001c2c86620014da565b8252948201949082019062001c18565b8652508581013593508284111562001c5357600080fd5b62001c618785880162001b2b565b818601525050505092915050565b600080600083850360e081121562001c8657600080fd5b60a081121562001c9557600080fd5b5062001ca062001977565b84356003811062001cb057600080fd5b815262001cc060208601620019d1565b602082015262001cd360408601620019d1565b6040820152606085013567ffffffffffffffff808216821462001cf557600080fd5b8160608401526080870135608084015282955060a087013592508083111562001d1d57600080fd5b62001d2b8884890162001a5d565b945060c087013592508083111562001d4257600080fd5b5050620016858682870162001b93565b6001600160a01b038416815260606020820152600062001d766060830185620016b5565b828103604084015262001d8a8185620016b5565b9695505050505050565b6001600160a01b03851681526000602060808184015262001db96080840187620016b5565b838103604085015262001dcd8187620016b5565b9050838103606085015284516040825262001dec6040830182620016e3565b8684015183820393850193909352825180825290840192840191506000905b8082101562001e2d578251845292840192918401916001919091019062001e0b565b50919998505050505050505050565b6001600160a01b038481168252835160e08301919062001e5c816200155f565b80602085015250602085015163ffffffff8082166040860152806040880151166060860152505067ffffffffffffffff6060860151166080840152608085015160a084015280841660c084015250949350505050565b6000825162001ec68184602087016200168f565b9190910192915050565b6000600019820362001ef257634e487b7160e01b600052601160045260246000fd5b5060010190565b6001600160a01b0383168152604060208201526000620011f86040830184620016b556fe60806040526040516107ad3803806107ad83398101604081905261002291610319565b61002e82826000610035565b5050610436565b61003e8361006b565b60008251118061004b5750805b156100665761006483836100ab60201b6100291760201c565b505b505050565b610074816100d7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606100d08383604051806060016040528060278152602001610786602791396101a9565b9392505050565b6100ea8161022260201b6100551760201c565b6101515760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084015b60405180910390fd5b806101887f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b61023160201b6100711760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b6060600080856001600160a01b0316856040516101c691906103e7565b600060405180830381855af49150503d8060008114610201576040519150601f19603f3d011682016040523d82523d6000602084013e610206565b606091505b50909250905061021886838387610234565b9695505050505050565b6001600160a01b03163b151590565b90565b606083156102a357825160000361029c576001600160a01b0385163b61029c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610148565b50816102ad565b6102ad83836102b5565b949350505050565b8151156102c55781518083602001fd5b8060405162461bcd60e51b81526004016101489190610403565b634e487b7160e01b600052604160045260246000fd5b60005b838110156103105781810151838201526020016102f8565b50506000910152565b6000806040838503121561032c57600080fd5b82516001600160a01b038116811461034357600080fd5b60208401519092506001600160401b038082111561036057600080fd5b818501915085601f83011261037457600080fd5b815181811115610386576103866102df565b604051601f8201601f19908116603f011681019083821181831017156103ae576103ae6102df565b816040528281528860208487010111156103c757600080fd5b6103d88360208301602088016102f5565b80955050505050509250929050565b600082516103f98184602087016102f5565b9190910192915050565b60208152600082518060208401526104228160408501602087016102f5565b601f01601f19169190910160400192915050565b610341806104456000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610074565b6100b9565b565b606061004e83836040518060600160405280602781526020016102e5602791396100dd565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b90565b60006100b47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b3660008037600080366000845af43d6000803e8080156100d8573d6000f35b3d6000fd5b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516101079190610277565b600060405180830381855af49150503d8060008114610142576040519150601f19603f3d011682016040523d82523d6000602084013e610147565b606091505b509150915061015886838387610162565b9695505050505050565b606083156101fd5782516000036101f65773ffffffffffffffffffffffffffffffffffffffff85163b6101f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610207565b610207838361020f565b949350505050565b81511561021f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ed9190610293565b60005b8381101561026e578181015183820152602001610256565b50506000910152565b60008251610289818460208701610253565b9190910192915050565b60208152600082518060208401526102b2816040850160208701610253565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a7c6f2fcb78c7b4c40d8fd8b3b79a2770d3af4a9e7da56689bfa5ce2c1ce5a2164736f6c63430008110033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212203a85aa1185f8c81fbbb2df9e52860eb11b92c66df30ec936c97a3384f39e2ed164736f6c6343000811003360806040523480156200001157600080fd5b5060405162003ad838038062003ad8833981016040819052620000349162000d20565b62000042848484846200004c565b5050505062001037565b600054610100900460ff16158080156200006d5750600054600160ff909116105b806200009d57506200008a306200023f60201b62000eb11760201c565b1580156200009d575060005460ff166001145b620001065760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156200012a576000805461ff0019166101001790555b6020820151518251511462000165578151516020830151516040516398b1381560e01b815260048101929092526024820152604401620000fd565b6200017184846200024e565b6200017c84620002ba565b620001878562000344565b60005b825151811015620001f057620001e783600001518281518110620001b257620001b262000e85565b602002602001015184602001518381518110620001d357620001d362000e85565b6020026020010151620003c360201b60201c565b6001016200018a565b50801562000238576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b6001600160a01b03163b151590565b600054610100900460ff16620002aa5760405162461bcd60e51b815260206004820152602b602482015260008051602062003a9883398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fd565b620002b6828262000477565b5050565b600054610100900460ff16620003165760405162461bcd60e51b815260206004820152602b602482015260008051602062003a9883398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fd565b6200034181604051806040016040528060018152602001603160f81b815250620004f560201b60201c565b50565b600054610100900460ff16620003a05760405162461bcd60e51b815260206004820152602b602482015260008051602062003a9883398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fd565b61013080546001600160a01b0319166001600160a01b0392909216919091179055565b620003da82826200056b60201b62000ec01760201c565b6001600160e01b03620003ee6200063a8216565b1115620004575760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201526f766572666c6f77696e6720766f74657360801b6064820152608401620000fd565b6200047161010062000f8d6200064060201b178362000657565b50505050565b600054610100900460ff16620004d35760405162461bcd60e51b815260206004820152602b602482015260008051602062003a9883398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fd565b6068620004e1838262000f29565b506069620004f0828262000f29565b505050565b600054610100900460ff16620005515760405162461bcd60e51b815260206004820152602b602482015260008051602062003a9883398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fd565b815160209283012081519190920120609791909155609855565b6001600160a01b038216620005c35760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620000fd565b8060676000828254620005d791906200100b565b90915550506001600160a01b0382166000818152606560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3620002b660008383620007e9565b60675490565b60006200064e82846200100b565b90505b92915050565b82546000908190818115620006b75762000686876200067860018562001021565b600091825260209091200190565b60408051808201909152905463ffffffff8116825264010000000090046001600160e01b03166020820152620006cc565b60408051808201909152600080825260208201525b905080602001516001600160e01b03169350620006ea84868860201c565b9250600082118015620007035750805163ffffffff1643145b156200075a576200071f836200085f60201b62000f991760201c565b62000731886200067860018662001021565b80546001600160e01b03929092166401000000000263ffffffff909216919091179055620007df565b8660405180604001604052806200077c43620008ce60201b6200101c1760201c565b63ffffffff1681526020016200079d866200085f60201b62000f991760201c565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b5050935093915050565b620008018383836200093560201b620010981760201c565b6001600160a01b03821615801590620008285750620008208262000981565b63ffffffff16155b80156200084d57506001600160a01b03828116600090815260fe602052604090205416155b15620004f057620004f08280620009b0565b60006001600160e01b03821115620008ca5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608401620000fd565b5090565b600063ffffffff821115620008ca5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401620000fd565b6200094d838383620004f060201b620007941760201c565b6001600160a01b03838116600090815260fe6020526040808220548584168352912054620004f09291821691168362000a27565b6001600160a01b038116600090815260ff6020908152604082205462000651916200101c620008ce821b17901c565b6001600160a01b03828116600081815260fe6020818152604080842080546065845282862054949093528787166001600160a01b03198416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a4620004718284835b816001600160a01b0316836001600160a01b03161415801562000a4a5750600081115b15620004f0576001600160a01b0383161562000ad7576001600160a01b038316600090815260ff602090815260408220829162000a94919062000b62901b620010ca178562000657565b91509150846001600160a01b031660008051602062003ab8833981519152838360405162000acc929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615620004f0576001600160a01b038216600090815260ff602090815260408220829162000b1b919062000640901b62000f8d178562000657565b91509150836001600160a01b031660008051602062003ab8833981519152838360405162000b53929190918252602082015260400190565b60405180910390a25050505050565b60006200064e828462001021565b6001600160a01b03811681146200034157600080fd5b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171562000bc15762000bc162000b86565b60405290565b604051601f8201601f191681016001600160401b038111828210171562000bf25762000bf262000b86565b604052919050565b600082601f83011262000c0c57600080fd5b81516001600160401b0381111562000c285762000c2862000b86565b602062000c3e601f8301601f1916820162000bc7565b828152858284870101111562000c5357600080fd5b60005b8381101562000c7357858101830151828201840152820162000c56565b506000928101909101919091529392505050565b60006001600160401b0382111562000ca35762000ca362000b86565b5060051b60200190565b600082601f83011262000cbf57600080fd5b8151602062000cd862000cd28362000c87565b62000bc7565b82815260059290921b8401810191818101908684111562000cf857600080fd5b8286015b8481101562000d15578051835291830191830162000cfc565b509695505050505050565b6000806000806080858703121562000d3757600080fd5b845162000d448162000b70565b602086810151919550906001600160401b038082111562000d6457600080fd5b62000d7289838a0162000bfa565b9550604088015191508082111562000d8957600080fd5b62000d9789838a0162000bfa565b9450606088015191508082111562000dae57600080fd5b908701906040828a03121562000dc357600080fd5b62000dcd62000b9c565b82518281111562000ddd57600080fd5b8301601f81018b1362000def57600080fd5b805162000e0062000cd28262000c87565b81815260059190911b8201860190868101908d83111562000e2057600080fd5b928701925b8284101562000e4b57835162000e3b8162000b70565b8252928701929087019062000e25565b8452505050828401518281111562000e6257600080fd5b62000e708b82860162000cad565b85830152508094505050505092959194509250565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168062000eb057607f821691505b60208210810362000ed157634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004f057600081815260208120601f850160051c8101602086101562000f005750805b601f850160051c820191505b8181101562000f215782815560010162000f0c565b505050505050565b81516001600160401b0381111562000f455762000f4562000b86565b62000f5d8162000f56845462000e9b565b8462000ed7565b602080601f83116001811462000f95576000841562000f7c5750858301515b600019600386901b1c1916600185901b17855562000f21565b600085815260208120601f198616915b8281101562000fc65788860151825594840194600190910190840162000fa5565b508582101562000fe55787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b8082018082111562000651576200065162000ff5565b8181038181111562000651576200065162000ff5565b612a5180620010476000396000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80636fcfff45116100f9578063a9059cbb11610097578063d505accf11610071578063d505accf146103dc578063dab27fa9146103ef578063dd62ed3e14610402578063f1127ed81461043b57600080fd5b8063a9059cbb1461038f578063b2d2989c146103a2578063c3cda520146103c957600080fd5b80638e539e8c116100d35780638e539e8c1461034e57806395d89b41146103615780639ab24eb014610369578063a457c2d71461037c57600080fd5b80636fcfff45146102ea57806370a08231146103125780637ecebe001461033b57600080fd5b80633644e5151161016657806340c10f191161014057806340c10f19146102705780634162169f14610285578063587cde1e146102ab5780635c19a95c146102d757600080fd5b80633644e51514610242578063395093511461024a5780633a46b1a81461025d57600080fd5b806318160ddd1161019757806318160ddd1461020e57806323b872dd14610220578063313ce5671461023357600080fd5b806301ffc9a7146101be57806306fdde03146101e6578063095ea7b3146101fb575b600080fd5b6101d16101cc366004612294565b610478565b60405190151581526020015b60405180910390f35b6101ee6105b1565b6040516101dd91906122be565b6101d1610209366004612321565b610643565b6067545b6040519081526020016101dd565b6101d161022e36600461234d565b61065b565b604051601281526020016101dd565b61021261067f565b6101d1610258366004612321565b61068e565b61021261026b366004612321565b6106cd565b61028361027e366004612321565b61074c565b005b610130546001600160a01b03165b6040516001600160a01b0390911681526020016101dd565b6102936102b936600461238e565b6001600160a01b03908116600090815260fe60205260409020541690565b6102836102e536600461238e565b610799565b6102fd6102f836600461238e565b6107a6565b60405163ffffffff90911681526020016101dd565b61021261032036600461238e565b6001600160a01b031660009081526065602052604090205490565b61021261034936600461238e565b6107c8565b61021261035c3660046123ab565b6107e6565b6101ee610843565b61021261037736600461238e565b610852565b6101d161038a366004612321565b6108d9565b6101d161039d366004612321565b610983565b6102127fb737b436e6cc542520cb79ec04245c720c38eebfa56d9e2d99b043979db20e4c81565b6102836103d73660046123da565b610991565b6102836103ea366004612434565b610ac7565b6102836103fd366004612611565b610c2b565b61021261041036600461275b565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b61044e610449366004612794565b610e2d565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016101dd565b60006001600160e01b031982167f36372b070000000000000000000000000000000000000000000000000000000014806104db57506001600160e01b031982167f9d8ff7da00000000000000000000000000000000000000000000000000000000145b8061050f57506001600160e01b031982167fa219a02500000000000000000000000000000000000000000000000000000000145b8061054357506001600160e01b031982167fe90fb3f600000000000000000000000000000000000000000000000000000000145b8061057757506001600160e01b031982167f40c10f1900000000000000000000000000000000000000000000000000000000145b806105ab57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b6060606880546105c0906127cb565b80601f01602080910402602001604051908101604052809291908181526020018280546105ec906127cb565b80156106395780601f1061060e57610100808354040283529160200191610639565b820191906000526020600020905b81548152906001019060200180831161061c57829003601f168201915b5050505050905090565b6000336106518185856110d6565b5060019392505050565b60003361066985828561122e565b6106748585856112c0565b506001949350505050565b60006106896114ba565b905090565b3360008181526066602090815260408083206001600160a01b038716845290915281205490919061065190829086906106c8908790612815565b6110d6565b60004382106107235760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e65640060448201526064015b60405180910390fd5b6001600160a01b038316600090815260ff602052604090206107459083611535565b9392505050565b610130547fb737b436e6cc542520cb79ec04245c720c38eebfa56d9e2d99b043979db20e4c9061078a906001600160a01b031630338460003661162c565b610794838361171a565b505050565b6107a333826117b2565b50565b6001600160a01b038116600090815260ff60205260408120546105ab9061101c565b6001600160a01b038116600090815260cb60205260408120546105ab565b60004382106108375760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400604482015260640161071a565b6105ab61010083611535565b6060606980546105c0906127cb565b6001600160a01b038116600090815260ff602052604081205480156108c6576001600160a01b038316600090815260ff60205260409020610894600183612828565b815481106108a4576108a461283b565b60009182526020909120015464010000000090046001600160e01b03166108c9565b60005b6001600160e01b03169392505050565b3360008181526066602090815260408083206001600160a01b0387168452909152812054909190838110156109765760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161071a565b61067482868684036110d6565b6000336106518185856112c0565b834211156109e15760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e61747572652065787069726564000000604482015260640161071a565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b038816918101919091526060810186905260808101859052600090610a5b90610a539060a00160405160208183030381529060405280519060200120611844565b8585856118ad565b9050610a66816118d5565b8614610ab45760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000604482015260640161071a565b610abe81886117b2565b50505050505050565b83421115610b175760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015260640161071a565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610b468c6118d5565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610ba182611844565b90506000610bb1828787876118ad565b9050896001600160a01b0316816001600160a01b031614610c145760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015260640161071a565b610c1f8a8a8a6110d6565b50505050505050505050565b600054610100900460ff1615808015610c4b5750600054600160ff909116105b80610c655750303b158015610c65575060005460ff166001145b610cd75760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161071a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610d18576000805461ff0019166101001790555b60208201515182515114610d6a578151516020830151516040517f98b138150000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161071a565b610d7484846118fd565b610d7d84611972565b610d8685611a1c565b60005b825151811015610ddf57610dd783600001518281518110610dac57610dac61283b565b602002602001015184602001518381518110610dca57610dca61283b565b602002602001015161171a565b600101610d89565b508015610e26576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b60408051808201909152600080825260208201526001600160a01b038316600090815260ff60205260409020805463ffffffff8416908110610e7157610e7161283b565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b6001600160a01b03163b151590565b6001600160a01b038216610f165760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161071a565b8060676000828254610f289190612815565b90915550506001600160a01b0382166000818152606560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610f8960008383611ac2565b5050565b60006107458284612815565b60006001600160e01b038211156110185760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f3234206269747300000000000000000000000000000000000000000000000000606482015260840161071a565b5090565b600063ffffffff8211156110185760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f3220626974730000000000000000000000000000000000000000000000000000606482015260840161071a565b6001600160a01b03838116600090815260fe602052604080822054858416835291205461079492918216911683611b24565b60006107458284612828565b6001600160a01b0383166111515760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161071a565b6001600160a01b0382166111cd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161071a565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383811660009081526066602090815260408083209386168352929052205460001981146112ba57818110156112ad5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161071a565b6112ba84848484036110d6565b50505050565b6001600160a01b03831661133c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161071a565b6001600160a01b0382166113b85760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161071a565b6001600160a01b038316600090815260656020526040902054818110156114475760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161071a565b6001600160a01b0380851660008181526065602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906114a79086815260200190565b60405180910390a36112ba848484611ac2565b60006106897f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6114e960975490565b6098546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b81546000908181600581111561158f57600061155084611c61565b61155a9085612828565b600088815260209020909150869082015463ffffffff16111561157f5780915061158d565b61158a816001612815565b92505b505b808210156115dc5760006115a38383611d49565b600088815260209020909150869082015463ffffffff1611156115c8578091506115d6565b6115d3816001612815565b92505b5061158f565b8015611616576115ff866115f1600184612828565b600091825260209091200190565b5464010000000090046001600160e01b0316611619565b60005b6001600160e01b03169695505050505050565b6040517ffdef91060000000000000000000000000000000000000000000000000000000081526001600160a01b0387169063fdef9106906116799088908890889088908890600401612851565b602060405180830381865afa158015611696573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ba91906128a5565b611712576040517f32dbe3b40000000000000000000000000000000000000000000000000000000081526001600160a01b0380881660048301528087166024830152851660448201526064810184905260840161071a565b505050505050565b6117248282610ec0565b6067546001600160e01b0310156117a35760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f74657300000000000000000000000000000000606482015260840161071a565b6112ba610100610f8d83611d64565b6001600160a01b03828116600081815260fe6020818152604080842080546065845282862054949093528787167fffffffffffffffffffffffff00000000000000000000000000000000000000008416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46112ba828483611b24565b60006105ab6118516114ba565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006118be87878787611eb8565b915091506118cb81611f7c565b5095945050505050565b6001600160a01b038116600090815260cb602052604090208054600181018255905b50919050565b600054610100900460ff166119685760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161071a565b610f8982826120e1565b600054610100900460ff166119dd5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161071a565b6107a3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250612165565b600054610100900460ff16611a875760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161071a565b61013080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b611acd838383611098565b6001600160a01b03821615801590611af15750611ae9826107a6565b63ffffffff16155b8015611b1557506001600160a01b03828116600090815260fe602052604090205416155b156107945761079482836117b2565b816001600160a01b0316836001600160a01b031614158015611b465750600081115b15610794576001600160a01b03831615611bd4576001600160a01b038316600090815260ff602052604081208190611b81906110ca85611d64565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611bc9929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615610794576001600160a01b038216600090815260ff602052604081208190611c0a90610f8d85611d64565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611c52929190918252602082015260400190565b60405180910390a25050505050565b600081600003611c7357506000919050565b60006001611c80846121ea565b901c6001901b90506001818481611c9957611c996128c7565b048201901c90506001818481611cb157611cb16128c7565b048201901c90506001818481611cc957611cc96128c7565b048201901c90506001818481611ce157611ce16128c7565b048201901c90506001818481611cf957611cf96128c7565b048201901c90506001818481611d1157611d116128c7565b048201901c90506001818481611d2957611d296128c7565b048201901c905061074581828581611d4357611d436128c7565b0461227e565b6000611d5860028484186128dd565b61074590848416612815565b82546000908190818115611db157611d81876115f1600185612828565b60408051808201909152905463ffffffff8116825264010000000090046001600160e01b03166020820152611dc6565b60408051808201909152600080825260208201525b905080602001516001600160e01b03169350611de684868863ffffffff16565b9250600082118015611dfe5750805163ffffffff1643145b15611e4357611e0c83610f99565b611e1b886115f1600186612828565b80546001600160e01b03929092166401000000000263ffffffff909216919091179055611eae565b866040518060400160405280611e584361101c565b63ffffffff168152602001611e6c86610f99565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b5050935093915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611eef5750600090506003611f73565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611f43573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611f6c57600060019250925050611f73565b9150600090505b94509492505050565b6000816004811115611f9057611f906128ff565b03611f985750565b6001816004811115611fac57611fac6128ff565b03611ff95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161071a565b600281600481111561200d5761200d6128ff565b0361205a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161071a565b600381600481111561206e5761206e6128ff565b036107a35760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161071a565b600054610100900460ff1661214c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161071a565b6068612158838261295b565b506069610794828261295b565b600054610100900460ff166121d05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161071a565b815160209283012081519190920120609791909155609855565b600080608083901c156121ff57608092831c92015b604083901c1561221157604092831c92015b602083901c1561222357602092831c92015b601083901c1561223557601092831c92015b600883901c1561224757600892831c92015b600483901c1561225957600492831c92015b600283901c1561226b57600292831c92015b600183901c156105ab5760010192915050565b600081831061228d5781610745565b5090919050565b6000602082840312156122a657600080fd5b81356001600160e01b03198116811461074557600080fd5b600060208083528351808285015260005b818110156122eb578581018301518582016040015282016122cf565b506000604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b03811681146107a357600080fd5b6000806040838503121561233457600080fd5b823561233f8161230c565b946020939093013593505050565b60008060006060848603121561236257600080fd5b833561236d8161230c565b9250602084013561237d8161230c565b929592945050506040919091013590565b6000602082840312156123a057600080fd5b81356107458161230c565b6000602082840312156123bd57600080fd5b5035919050565b803560ff811681146123d557600080fd5b919050565b60008060008060008060c087890312156123f357600080fd5b86356123fe8161230c565b9550602087013594506040870135935061241a606088016123c4565b92506080870135915060a087013590509295509295509295565b600080600080600080600060e0888a03121561244f57600080fd5b873561245a8161230c565b9650602088013561246a8161230c565b95506040880135945060608801359350612486608089016123c4565b925060a0880135915060c0880135905092959891949750929550565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156124db576124db6124a2565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561250a5761250a6124a2565b604052919050565b600082601f83011261252357600080fd5b813567ffffffffffffffff81111561253d5761253d6124a2565b6125506020601f19601f840116016124e1565b81815284602083860101111561256557600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff82111561259c5761259c6124a2565b5060051b60200190565b600082601f8301126125b757600080fd5b813560206125cc6125c783612582565b6124e1565b82815260059290921b840181019181810190868411156125eb57600080fd5b8286015b8481101561260657803583529183019183016125ef565b509695505050505050565b6000806000806080858703121561262757600080fd5b84356126328161230c565b935060208581013567ffffffffffffffff8082111561265057600080fd5b61265c89838a01612512565b9550604088013591508082111561267257600080fd5b61267e89838a01612512565b9450606088013591508082111561269457600080fd5b908701906040828a0312156126a857600080fd5b6126b06124b8565b8235828111156126bf57600080fd5b8301601f81018b136126d057600080fd5b80356126de6125c782612582565b81815260059190911b8201860190868101908d8311156126fd57600080fd5b928701925b828410156127245783356127158161230c565b82529287019290870190612702565b8452505050828401358281111561273a57600080fd5b6127468b8286016125a6565b85830152508094505050505092959194509250565b6000806040838503121561276e57600080fd5b82356127798161230c565b915060208301356127898161230c565b809150509250929050565b600080604083850312156127a757600080fd5b82356127b28161230c565b9150602083013563ffffffff8116811461278957600080fd5b600181811c908216806127df57607f821691505b6020821081036118f757634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156105ab576105ab6127ff565b818103818111156105ab576105ab6127ff565b634e487b7160e01b600052603260045260246000fd5b60006001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a0840137600060a0848401015260a0601f19601f85011683010190509695505050505050565b6000602082840312156128b757600080fd5b8151801515811461074557600080fd5b634e487b7160e01b600052601260045260246000fd5b6000826128fa57634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052602160045260246000fd5b601f82111561079457600081815260208120601f850160051c8101602086101561293c5750805b601f850160051c820191505b8181101561171257828155600101612948565b815167ffffffffffffffff811115612975576129756124a2565b6129898161298384546127cb565b84612915565b602080601f8311600181146129be57600084156129a65750858301515b600019600386901b1c1916600185901b178555611712565b600085815260208120601f198616915b828110156129ed578886015182559484019460019091019084016129ce565b5085821015612a0b5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212208cfc50d955157b2d12f69f52f4a11a8378a311cac18997d45a259ba39da73e2964736f6c63430008110033496e697469616c697a61626c653a20636f6e7472616374206973206e6f742069dec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72460806040523480156200001157600080fd5b50604051620034723803806200347283398101604081905262000034916200053b565b620000418383836200004a565b5050506200071f565b600054610100900460ff16158080156200006b5750600054600160ff909116105b806200009b575062000088306200019760201b62000dd61760201c565b1580156200009b575060005460ff166001145b620001045760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff19166001179055801562000128576000805461ff0019166101001790555b620001348383620001a6565b6200013f8362000212565b6200014a846200029c565b801562000191576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6001600160a01b03163b151590565b600054610100900460ff16620002025760405162461bcd60e51b815260206004820152602b60248201526000805160206200345283398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fb565b6200020e828262000303565b5050565b600054610100900460ff166200026e5760405162461bcd60e51b815260206004820152602b60248201526000805160206200345283398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fb565b6200029981604051806040016040528060018152602001603160f81b8152506200038160201b60201c565b50565b600054610100900460ff16620002f85760405162461bcd60e51b815260206004820152602b60248201526000805160206200345283398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fb565b6200029981620003f7565b600054610100900460ff166200035f5760405162461bcd60e51b815260206004820152602b60248201526000805160206200345283398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fb565b60686200036d838262000653565b5060696200037c828262000653565b505050565b600054610100900460ff16620003dd5760405162461bcd60e51b815260206004820152602b60248201526000805160206200345283398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fb565b815160209283012081519190920120609791909155609855565b600054610100900460ff16620004535760405162461bcd60e51b815260206004820152602b60248201526000805160206200345283398151915260448201526a6e697469616c697a696e6760a81b6064820152608401620000fb565b61013080546001600160a01b0319166001600160a01b0392909216919091179055565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200049e57600080fd5b81516001600160401b0380821115620004bb57620004bb62000476565b604051601f8301601f19908116603f01168101908282118183101715620004e657620004e662000476565b816040528381526020925086838588010111156200050357600080fd5b600091505b8382101562000527578582018301518183018401529082019062000508565b600093810190920192909252949350505050565b6000806000606084860312156200055157600080fd5b83516001600160a01b03811681146200056957600080fd5b60208501519093506001600160401b03808211156200058757600080fd5b62000595878388016200048c565b93506040860151915080821115620005ac57600080fd5b50620005bb868287016200048c565b9150509250925092565b600181811c90821680620005da57607f821691505b602082108103620005fb57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200037c57600081815260208120601f850160051c810160208610156200062a5750805b601f850160051c820191505b818110156200064b5782815560010162000636565b505050505050565b81516001600160401b038111156200066f576200066f62000476565b6200068781620006808454620005c5565b8462000601565b602080601f831160018114620006bf5760008415620006a65750858301515b600019600386901b1c1916600185901b1785556200064b565b600085815260208120601f198616915b82811015620006f057888601518255948401946001909101908401620006cf565b50858210156200070f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b612d23806200072f6000396000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80636f307dc3116100f95780639ab24eb011610097578063c3cda52011610071578063c3cda520146103d9578063d505accf146103ec578063dd62ed3e146103ff578063f1127ed81461043857600080fd5b80639ab24eb0146103a0578063a457c2d7146103b3578063a9059cbb146103c657600080fd5b80637ecebe00116100d35780637ecebe001461035f5780638e539e8c14610372578063906571471461038557806395d89b411461039857600080fd5b80636f307dc3146102fa5780636fcfff451461030e57806370a082311461033657600080fd5b80632f4f21e2116101665780633950935111610140578063395093511461027b5780633a46b1a81461028e578063587cde1e146102a15780635c19a95c146102e557600080fd5b80632f4f21e214610246578063313ce567146102595780633644e5151461027357600080fd5b806318160ddd1161019757806318160ddd1461020e578063205c28781461022057806323b872dd1461023357600080fd5b806301ffc9a7146101be57806306fdde03146101e6578063095ea7b3146101fb575b600080fd5b6101d16101cc366004612712565b610475565b60405190151581526020015b60405180910390f35b6101ee6105ae565b6040516101dd9190612760565b6101d16102093660046127a8565b610640565b6067545b6040519081526020016101dd565b6101d161022e3660046127a8565b610658565b6101d16102413660046127d4565b61066b565b6101d16102543660046127a8565b61068f565b61026161069b565b60405160ff90911681526020016101dd565b6102126106aa565b6101d16102893660046127a8565b6106b4565b61021261029c3660046127a8565b6106f3565b6102cd6102af366004612815565b6001600160a01b03908116600090815260fe60205260409020541690565b6040516001600160a01b0390911681526020016101dd565b6102f86102f3366004612815565b61076b565b005b610130546102cd906001600160a01b031681565b61032161031c366004612815565b610778565b60405163ffffffff90911681526020016101dd565b610212610344366004612815565b6001600160a01b031660009081526065602052604090205490565b61021261036d366004612815565b61079a565b610212610380366004612832565b6107b8565b6102f86103933660046128ee565b610815565b6101ee61096a565b6102126103ae366004612815565b610979565b6101d16103c13660046127a8565b610a00565b6101d16103d43660046127a8565b610aaa565b6102f86103e7366004612973565b610ab8565b6102f86103fa3660046129cf565b610bee565b61021261040d366004612a40565b6001600160a01b03918216600090815260666020908152604080832093909416825291909152205490565b61044b610446366004612a79565b610d52565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016101dd565b60006001600160e01b031982167f0f13099a0000000000000000000000000000000000000000000000000000000014806104d857506001600160e01b031982167f36372b0700000000000000000000000000000000000000000000000000000000145b8061050c57506001600160e01b031982167f9d8ff7da00000000000000000000000000000000000000000000000000000000145b8061054057506001600160e01b031982167fa219a02500000000000000000000000000000000000000000000000000000000145b8061057457506001600160e01b031982167fe90fb3f600000000000000000000000000000000000000000000000000000000145b806105a857507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b6060606880546105bd90612ab0565b80601f01602080910402602001604051908101604052809291908181526020018280546105e990612ab0565b80156106365780601f1061060b57610100808354040283529160200191610636565b820191906000526020600020905b81548152906001019060200180831161061957829003601f168201915b5050505050905090565b60003361064e818585610de5565b5060019392505050565b60006106648383610f3d565b9392505050565b600033610679858285610f6a565b610684858585610ff6565b506001949350505050565b600061066483836111f0565b60006106a5611216565b905090565b60006106a56112a5565b3360008181526066602090815260408083206001600160a01b038716845290915281205490919061064e90829086906106ee908790612afa565b610de5565b60004382106107495760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e65640060448201526064015b60405180910390fd5b6001600160a01b038316600090815260ff602052604090206106649083611320565b6107753382611417565b50565b6001600160a01b038116600090815260ff60205260408120546105a8906114a9565b6001600160a01b038116600090815260cb60205260408120546105a8565b60004382106108095760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610740565b6105a861010083611320565b600054610100900460ff16158080156108355750600054600160ff909116105b8061084f5750303b15801561084f575060005460ff166001145b6108c15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610740565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610902576000805461ff0019166101001790555b61090c8383611529565b610915836115a2565b61091e8461164c565b8015610964576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6060606980546105bd90612ab0565b6001600160a01b038116600090815260ff602052604081205480156109ed576001600160a01b038316600090815260ff602052604090206109bb600183612b0d565b815481106109cb576109cb612b20565b60009182526020909120015464010000000090046001600160e01b03166109f0565b60005b6001600160e01b03169392505050565b3360008181526066602090815260408083206001600160a01b038716845290915281205490919083811015610a9d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610740565b6106848286868403610de5565b60003361064e818585610ff6565b83421115610b085760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610740565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b038816918101919091526060810186905260808101859052600090610b8290610b7a9060a001604051602081830303815290604052805190602001206116c0565b858585611729565b9050610b8d81611753565b8614610bdb5760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610740565b610be58188611417565b50505050505050565b83421115610c3e5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610740565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610c6d8c611753565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610cc8826116c0565b90506000610cd882878787611729565b9050896001600160a01b0316816001600160a01b031614610d3b5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610740565b610d468a8a8a610de5565b50505050505050505050565b60408051808201909152600080825260208201526001600160a01b038316600090815260ff60205260409020805463ffffffff8416908110610d9657610d96612b20565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b6001600160a01b03163b151590565b6001600160a01b038316610e605760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610740565b6001600160a01b038216610edc5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610740565b6001600160a01b0383811660008181526066602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6000610f49338361177b565b61013054610f61906001600160a01b03168484611785565b50600192915050565b6001600160a01b0383811660009081526066602090815260408083209386168352929052205460001981146109645781811015610fe95760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610740565b6109648484848403610de5565b6001600160a01b0383166110725760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610740565b6001600160a01b0382166110ee5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610740565b6001600160a01b0383166000908152606560205260409020548181101561117d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610740565b6001600160a01b0380851660008181526065602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906111dd9086815260200190565b60405180910390a3610964848484611806565b6101305460009061120c906001600160a01b0316333085611868565b610f6183836118b9565b61013054604080517f313ce56700000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163313ce5679160048083019260209291908290030181865afa925050508015611296575060408051601f3d908101601f1916820190925261129391810190612b36565b60015b6112a05750601290565b919050565b60006106a57f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6112d460975490565b6098546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b81546000908181600581111561137a57600061133b846118c3565b6113459085612b0d565b600088815260209020909150869082015463ffffffff16111561136a57809150611378565b611375816001612afa565b92505b505b808210156113c757600061138e83836119ab565b600088815260209020909150869082015463ffffffff1611156113b3578091506113c1565b6113be816001612afa565b92505b5061137a565b8015611401576113ea866113dc600184612b0d565b600091825260209091200190565b5464010000000090046001600160e01b0316611404565b60005b6001600160e01b03169695505050505050565b6001600160a01b03828116600081815260fe6020818152604080842080546065845282862054949093528787167fffffffffffffffffffffffff00000000000000000000000000000000000000008416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46109648284836119c6565b600063ffffffff8211156115255760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610740565b5090565b600054610100900460ff166115945760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610740565b61159e8282611b03565b5050565b600054610100900460ff1661160d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610740565b610775816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250611b87565b600054610100900460ff166116b75760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610740565b61077581611c0c565b60006105a86116cd6112a5565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b600080600061173a87878787611cb2565b9150915061174781611d76565b5090505b949350505050565b6001600160a01b038116600090815260cb602052604090208054600181018255905b50919050565b61159e8282611edb565b6040516001600160a01b0383166024820152604481018290526118019084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611ef4565b505050565b611811838383611fd9565b6001600160a01b03821615801590611835575061182d82610778565b63ffffffff16155b801561185957506001600160a01b03828116600090815260fe602052604090205416155b15611801576118018283611417565b6040516001600160a01b03808516602483015283166044820152606481018290526109649085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016117ca565b61159e828261200b565b6000816000036118d557506000919050565b600060016118e2846120a3565b901c6001901b905060018184816118fb576118fb612b53565b048201901c9050600181848161191357611913612b53565b048201901c9050600181848161192b5761192b612b53565b048201901c9050600181848161194357611943612b53565b048201901c9050600181848161195b5761195b612b53565b048201901c9050600181848161197357611973612b53565b048201901c9050600181848161198b5761198b612b53565b048201901c9050610664818285816119a5576119a5612b53565b04612137565b60006119ba6002848418612b69565b61066490848416612afa565b816001600160a01b0316836001600160a01b0316141580156119e85750600081115b15611801576001600160a01b03831615611a76576001600160a01b038316600090815260ff602052604081208190611a239061214d85612159565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611a6b929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615611801576001600160a01b038216600090815260ff602052604081208190611aac906122ad85612159565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611af4929190918252602082015260400190565b60405180910390a25050505050565b600054610100900460ff16611b6e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610740565b6068611b7a8382612bd9565b5060696118018282612bd9565b600054610100900460ff16611bf25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610740565b815160209283012081519190920120609791909155609855565b600054610100900460ff16611c775760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610740565b61013080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611ce95750600090506003611d6d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611d3d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611d6657600060019250925050611d6d565b9150600090505b94509492505050565b6000816004811115611d8a57611d8a612c99565b03611d925750565b6001816004811115611da657611da6612c99565b03611df35760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610740565b6002816004811115611e0757611e07612c99565b03611e545760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610740565b6003816004811115611e6857611e68612c99565b036107755760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610740565b611ee582826122b9565b61096461010061214d83612159565b6000611f49826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661242b9092919063ffffffff16565b8051909150156118015780806020019051810190611f679190612caf565b6118015760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610740565b6001600160a01b03838116600090815260fe6020526040808220548584168352912054611801929182169116836119c6565b612015828261243a565b6067546001600160e01b0310156120945760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f746573000000000000000000000000000000006064820152608401610740565b6109646101006122ad83612159565b600080608083901c156120b857608092831c92015b604083901c156120ca57604092831c92015b602083901c156120dc57602092831c92015b601083901c156120ee57601092831c92015b600883901c1561210057600892831c92015b600483901c1561211257600492831c92015b600283901c1561212457600292831c92015b600183901c156105a85760010192915050565b60008183106121465781610664565b5090919050565b60006106648284612b0d565b825460009081908181156121a657612176876113dc600185612b0d565b60408051808201909152905463ffffffff8116825264010000000090046001600160e01b031660208201526121bb565b60408051808201909152600080825260208201525b905080602001516001600160e01b031693506121db84868863ffffffff16565b92506000821180156121f35750805163ffffffff1643145b156122385761220183612503565b612210886113dc600186612b0d565b80546001600160e01b03929092166401000000000263ffffffff9092169190911790556122a3565b86604051806040016040528061224d436114a9565b63ffffffff16815260200161226186612503565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b5050935093915050565b60006106648284612afa565b6001600160a01b0382166123355760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610740565b6001600160a01b038216600090815260656020526040902054818110156123c45760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610740565b6001600160a01b03831660008181526065602090815260408083208686039055606780548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361180183600084611806565b606061174b8484600085612582565b6001600160a01b0382166124905760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610740565b80606760008282546124a29190612afa565b90915550506001600160a01b0382166000818152606560209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a361159e60008383611806565b60006001600160e01b038211156115255760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f32342062697473000000000000000000000000000000000000000000000000006064820152608401610740565b6060824710156125fa5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610740565b600080866001600160a01b031685876040516126169190612cd1565b60006040518083038185875af1925050503d8060008114612653576040519150601f19603f3d011682016040523d82523d6000602084013e612658565b606091505b509150915061266987838387612674565b979650505050505050565b606083156126e35782516000036126dc576001600160a01b0385163b6126dc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610740565b508161174b565b61174b83838151156126f85781518083602001fd5b8060405162461bcd60e51b81526004016107409190612760565b60006020828403121561272457600080fd5b81356001600160e01b03198116811461066457600080fd5b60005b8381101561275757818101518382015260200161273f565b50506000910152565b602081526000825180602084015261277f81604085016020870161273c565b601f01601f19169190910160400192915050565b6001600160a01b038116811461077557600080fd5b600080604083850312156127bb57600080fd5b82356127c681612793565b946020939093013593505050565b6000806000606084860312156127e957600080fd5b83356127f481612793565b9250602084013561280481612793565b929592945050506040919091013590565b60006020828403121561282757600080fd5b813561066481612793565b60006020828403121561284457600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261287257600080fd5b813567ffffffffffffffff8082111561288d5761288d61284b565b604051601f8301601f19908116603f011681019082821181831017156128b5576128b561284b565b816040528381528660208588010111156128ce57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561290357600080fd5b833561290e81612793565b9250602084013567ffffffffffffffff8082111561292b57600080fd5b61293787838801612861565b9350604086013591508082111561294d57600080fd5b5061295a86828701612861565b9150509250925092565b60ff8116811461077557600080fd5b60008060008060008060c0878903121561298c57600080fd5b863561299781612793565b9550602087013594506040870135935060608701356129b581612964565b9598949750929560808101359460a0909101359350915050565b600080600080600080600060e0888a0312156129ea57600080fd5b87356129f581612793565b96506020880135612a0581612793565b955060408801359450606088013593506080880135612a2381612964565b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215612a5357600080fd5b8235612a5e81612793565b91506020830135612a6e81612793565b809150509250929050565b60008060408385031215612a8c57600080fd5b8235612a9781612793565b9150602083013563ffffffff81168114612a6e57600080fd5b600181811c90821680612ac457607f821691505b60208210810361177557634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156105a8576105a8612ae4565b818103818111156105a8576105a8612ae4565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612b4857600080fd5b815161066481612964565b634e487b7160e01b600052601260045260246000fd5b600082612b8657634e487b7160e01b600052601260045260246000fd5b500490565b601f82111561180157600081815260208120601f850160051c81016020861015612bb25750805b601f850160051c820191505b81811015612bd157828155600101612bbe565b505050505050565b815167ffffffffffffffff811115612bf357612bf361284b565b612c0781612c018454612ab0565b84612b8b565b602080601f831160018114612c3c5760008415612c245750858301515b600019600386901b1c1916600185901b178555612bd1565b600085815260208120601f198616915b82811015612c6b57888601518255948401946001909101908401612c4c565b5085821015612c895787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052602160045260246000fd5b600060208284031215612cc157600080fd5b8151801515811461066457600080fd5b60008251612ce381846020870161273c565b919091019291505056fea26469706673582212204c5906ebcb45b715033693901873f3ecb56ed6a7eecf921f5dcdb12b1b8c8dc964736f6c63430008110033496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161381162000120600039600081816107b70152818161085201528181610959015281816109ef0152610ae601526138116000f3fe6080604052600436106101cd5760003560e01c80637c36e8e8116100f7578063c9c4bfca11610095578063da35c66411610064578063da35c664146105c6578063e28c3b19146105db578063f60046b2146105fa578063fe0d94c11461061057600080fd5b8063c9c4bfca14610532578063cc63604a14610566578063ce6366c414610586578063cf131149146105a657600080fd5b80639cba3021116100d15780639cba3021146104a0578063a230c524146104c0578063b2673b07146104e0578063c7f758a81461050057600080fd5b80637c36e8e8146104075780638a4b00f814610428578063970601d81461044857600080fd5b80633659cfe61161016f57806352d1902d1161013e57806352d1902d1461037c578063536f9f421461039157806356715761146103b15780635c60da1b146103f257600080fd5b80633659cfe6146103035780634162169f1461032357806341de6830146103555780634f1ef2861461036957600080fd5b80630dfb278e116101ab5780630dfb278e1461025d57806317d1b4041461027f5780631befc4051461029f57806323d07188146102e157600080fd5b806301ffc9a7146101d2578063054fd2c2146102075780630de218561461023d575b600080fd5b3480156101de57600080fd5b506101f26101ed3660046129f5565b610630565b60405190151581526020015b60405180910390f35b34801561021357600080fd5b506101605465010000000000900463ffffffff165b60405163ffffffff90911681526020016101fe565b34801561024957600080fd5b506101f2610258366004612a1f565b6106a8565b34801561026957600080fd5b5061027d610278366004612a50565b61074b565b005b34801561028b57600080fd5b506101f261029a366004612a95565b610796565b3480156102ab57600080fd5b506102d37fbba35d41610b7d25c8e486006535c76bd423091563e694d206ae3d71ce949fe581565b6040519081526020016101fe565b3480156102ed57600080fd5b506101605460ff165b6040516101fe9190612af9565b34801561030f57600080fd5b5061027d61031e366004612b0c565b6107ad565b34801561032f57600080fd5b5060c9546001600160a01b03165b6040516001600160a01b0390911681526020016101fe565b34801561036157600080fd5b5060006102f6565b61027d610377366004612b98565b61094f565b34801561038857600080fd5b506102d3610ad9565b34801561039d57600080fd5b506102d36103ac366004612a1f565b610b9f565b3480156103bd57600080fd5b50610160546901000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff90911681526020016101fe565b3480156103fe57600080fd5b5061033d610c27565b34801561041357600080fd5b5061016054610100900463ffffffff16610228565b34801561043457600080fd5b506101f2610443366004612a1f565b610c5f565b34801561045457600080fd5b50610493610463366004612c2b565b600082815261015f602090815260408083206001600160a01b038516845260060190915290205460ff1692915050565b6040516101fe9190612c6f565b3480156104ac57600080fd5b506102d36104bb366004612d03565b610c9f565b3480156104cc57600080fd5b506101f26104db366004612b0c565b610fdd565b3480156104ec57600080fd5b5061027d6104fb366004612de8565b611070565b34801561050c57600080fd5b5061052061051b366004612a1f565b6111ea565b6040516101fe96959493929190612f00565b34801561053e57600080fd5b506102d37f821b6e3a557148015a918c89e5d092e878a69854a2d1a410635f771bd5a8a3f581565b34801561057257600080fd5b506101f2610581366004612a1f565b611452565b34801561059257600080fd5b5061027d6105a1366004612fb8565b61145d565b3480156105b257600080fd5b506101f26105c1366004612a1f565b6114b1565b3480156105d257600080fd5b506102d3611513565b3480156105e757600080fd5b50610191546001600160a01b031661033d565b34801561060657600080fd5b50610161546102d3565b34801561061c57600080fd5b5061027d61062b366004612a1f565b61151f565b60006001600160e01b031982167f50eb001e00000000000000000000000000000000000000000000000000000000148061069357506001600160e01b031982167fa230c52400000000000000000000000000000000000000000000000000000000145b806106a257506106a28261156a565b92915050565b600081815261015f60205260408120600381015460048201546001830154849291906106e490600160a81b900467ffffffffffffffff16610b9f565b6106ee9190613003565b6106f89190613003565b6001830154909150610716908290610100900463ffffffff16613016565b6004830154600184015461073890610100900463ffffffff16620f4240613003565b6107429190613016565b11949350505050565b60c9547fbba35d41610b7d25c8e486006535c76bd423091563e694d206ae3d71ce949fe590610789906001600160a01b031630335b846000366115dc565b610792826116ca565b5050565b60006107a38484846118cd565b90505b9392505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036108505760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084015b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108ab7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146109275760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610847565b61093081611a3a565b6040805160008082526020820190925261094c91839190611a73565b50565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036109ed5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610847565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610a487f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610ac45760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610847565b610acd82611a3a565b61079282826001611a73565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b795760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610847565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b90565b610191546040517f8e539e8c000000000000000000000000000000000000000000000000000000008152600481018390526000916001600160a01b031690638e539e8c90602401602060405180830381865afa158015610c03573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106a2919061302d565b6000610c5a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b600081815261015f602052604081206002810154600382015460058301546004840154610c8c9190613046565b610c969190613046565b10159392505050565b6000600019430181610cb082610b9f565b905080600003610cec576040517f7c176b7400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61016154610191546001600160a01b0316633a46b1a8336040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101869052604401602060405180830381865afa158015610d4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d72919061302d565b1015610dac576040517feab99344000000000000000000000000000000000000000000000000000000008152336004820152602401610847565b610dbc338d8d8a8a8f8f8f611c18565b600081815261015f60205260409020909350610dd88888611c7e565b6001830180547fffffffffffffffffffffff00000000000000000000000000000000ffffffffff166d010000000000000000000000000067ffffffffffffffff938416027fffffffffffffffffffffffffffffffffffffff0000000000000000ffffffffff1617650100000000009390921692909202179055610e5a83611dbf565b60018201805467ffffffffffffffff92909216600160a81b027fffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffff909216919091179055610eaa6101605460ff1690565b60018083018054909160ff1990911690836002811115610ecc57610ecc612ad3565b021790555061016054610100900463ffffffff166001820180547fffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000ff1661010063ffffffff9384160217905561016054610f369184916501000000000090041663ffffffff16611e43565b60028201558815610f4957600881018990555b60005b8a811015610fa857816007018c8c83818110610f6a57610f6a613059565b9050602002810190610f7c919061306f565b815460018101835560009283526020909220909160030201610f9e8282613109565b5050600101610f4c565b506000866003811115610fbd57610fbd612ad3565b14610fcd57610fcd84878761145d565b5050509998505050505050505050565b610191546040517f9ab24eb00000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526000928392911690639ab24eb090602401602060405180830381865afa158015611045573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611069919061302d565b1192915050565b600054610100900460ff16158080156110905750600054600160ff909116105b806110aa5750303b1580156110aa575060005460ff166001145b61111c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610847565b6000805460ff19166001179055801561113f576000805461ff0019166101001790555b6111498484611ed3565b610191805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f3f1ec22954d444cb99f80a1989ac8f631616b8a575a89379e514c0f7f748c93390600090a280156111e4576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101829052819061124160405180606001604052806000815260200160008152602001600081525090565b600085815261015f602052604081206060919061125d81611f62565b81546040805160c08101909152600184018054939a5060ff928316995090929091839116600281111561129257611292612ad3565b60028111156112a3576112a3612ad3565b8152815463ffffffff61010082041660208084019190915267ffffffffffffffff65010000000000830481166040808601919091526d010000000000000000000000000084048216606080870191909152600160a81b909404909116608085015260019094015460a090930192909252825190810183526003850154815260048501548183015260058501548184015260078501805484518185028101850190955280855294995090975091929060009084015b8282101561143b576000848152602090819020604080516060810182526003860290920180546001600160a01b03168352600181015493830193909352600283018054929392918401916113aa9061308f565b80601f01602080910402602001604051908101604052809291908181526020018280546113d69061308f565b80156114235780601f106113f857610100808354040283529160200191611423565b820191906000526020600020905b81548152906001019060200180831161140657829003601f168201915b50505050508152505081526020019060010190611357565b505050509250806008015491505091939550919395565b60006106a282611fd0565b336114698482856118cd565b6114a5578381846040517f70b4b2540000000000000000000000000000000000000000000000000000000081526004016108479392919061323a565b6111e484848385612078565b600081815261015f60205260408120600581015460018201546114df9190610100900463ffffffff16613016565b6004820154600183015461150190610100900463ffffffff16620f4240613003565b61150b9190613016565b119392505050565b6000610c5a61012d5490565b61152881611fd0565b611561576040517f9fefd0f100000000000000000000000000000000000000000000000000000000815260048101829052602401610847565b61094c8161231f565b60006001600160e01b031982167f8678b01e0000000000000000000000000000000000000000000000000000000014806115cd57506001600160e01b031982167f4d19145e00000000000000000000000000000000000000000000000000000000145b806106a257506106a282612487565b6040517ffdef91060000000000000000000000000000000000000000000000000000000081526001600160a01b0387169063fdef9106906116299088908890889088908890600401613290565b602060405180830381865afa158015611646573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166a91906132ce565b6116c2576040517f32dbe3b40000000000000000000000000000000000000000000000000000000081526001600160a01b03808816600483015280871660248301528516604482015260648101849052608401610847565b505050505050565b6116d86001620f4240613003565b6116e860408301602084016132fd565b63ffffffff161115611753576117026001620f4240613003565b61171260408301602084016132fd565b6040517fcc80c195000000000000000000000000000000000000000000000000000000008152600481019290925263ffffffff166024820152604401610847565b620f424061176760608301604084016132fd565b63ffffffff16111561178757620f424061171260608301604084016132fd565b610e1061179a608083016060840161331a565b67ffffffffffffffff16101561180357610e106117bd608083016060840161331a565b6040517fc51033ee00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff928316600482015291166024820152604401610847565b6301e13380611818608083016060840161331a565b67ffffffffffffffff16111561183d576301e133806117bd608083016060840161331a565b8061016061184b8282613351565b507fa8a18d06ddd19f24a872740e3d364c86f62be25f7154525dda18ef07fda46f3e905061187c6020830183613464565b61188c60408401602085016132fd565b61189c60608501604086016132fd565b6118ac608086016060870161331a565b85608001356040516118c2959493929190613481565b60405180910390a150565b600083815261015f602052604081206118e581611f62565b6118f35760009150506107a6565b600083600381111561190757611907612ad3565b036119165760009150506107a6565b6101915460018201546040517f3a46b1a80000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152600160a81b90920467ffffffffffffffff166024820152911690633a46b1a890604401602060405180830381865afa158015611995573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b9919061302d565b6000036119ca5760009150506107a6565b6001600160a01b038416600090815260068201602052604081205460ff1660038111156119f9576119f9612ad3565b14158015611a2057506002600182015460ff166002811115611a1d57611a1d612ad3565b14155b15611a2f5760009150506107a6565b506001949350505050565b60c9547f821b6e3a557148015a918c89e5d092e878a69854a2d1a410635f771bd5a8a3f590610792906001600160a01b03163033610780565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611aab57611aa6836124c5565b505050565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611b05575060408051601f3d908101601f19168201909252611b029181019061302d565b60015b611b775760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608401610847565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114611c0c5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152608401610847565b50611aa6838383612590565b6000611c226125b5565b9050886001600160a01b0316817fa6c1f8f4276dc3f243459e13b557c84e8f4e90b2e09070bad5f6909cee687c9288888c8c8a8a8a604051611c6a97969594939291906134bd565b60405180910390a398975050505050505050565b6000806000611c8c42611dbf565b90508467ffffffffffffffff16600003611ca857809250611d0d565b8492508067ffffffffffffffff168367ffffffffffffffff161015611d0d576040517f4cc9c0f400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808316600483015284166024820152604401610847565b61016054600090611d35906901000000000000000000900467ffffffffffffffff16856135cc565b90508467ffffffffffffffff16600003611d5157809250611db6565b8492508067ffffffffffffffff168367ffffffffffffffff161015611db6576040517f4cc9c0f400000000000000000000000000000000000000000000000000000000815267ffffffffffffffff808316600483015284166024820152604401610847565b50509250929050565b600067ffffffffffffffff821115611e3f5760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201527f34206269747300000000000000000000000000000000000000000000000000006064820152608401610847565b5090565b6000620f4240821115611e8e576040517fcc80c195000000000000000000000000000000000000000000000000000000008152620f4240600482015260248101839052604401610847565b611e988284613016565b92506000611ea9620f424085613603565b9050611eb8620f424085613617565b91508015611ecc57611ec98261362b565b91505b5092915050565b600054610100900460ff16611f505760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610847565b611f59826125d0565b610792816116ca565b600080611f6e42611dbf565b600184015490915067ffffffffffffffff808316650100000000009092041611801590611fbd5750600183015467ffffffffffffffff6d01000000000000000000000000009091048116908216105b80156107a6575050905460ff1615919050565b600081815261015f60205260408120805460ff1615611ff25750600092915050565b611ffb81611f62565b156120435760018082015460ff16600281111561201a5761201a612ad3565b146120285750600092915050565b612031836106a8565b61203e5750600092915050565b612059565b61204c836114b1565b6120595750600092915050565b61206283610c5f565b61206f5750600092915050565b50600192915050565b600084815261015f602052604080822061019154600182015492517f3a46b1a80000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152600160a81b90940467ffffffffffffffff1660248201529193921690633a46b1a890604401602060405180830381865afa158015612108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061212c919061302d565b6001600160a01b038516600090815260068401602052604090205490915060ff16600281600381111561216157612161612ad3565b03612180576004830154612176908390613003565b60048401556121e2565b600381600381111561219457612194612ad3565b036121b35760058301546121a9908390613003565b60058401556121e2565b60018160038111156121c7576121c7612ad3565b036121e25760038301546121dc908390613003565b60038401555b60028660038111156121f6576121f6612ad3565b0361221557600483015461220b908390613046565b6004840155612277565b600386600381111561222957612229612ad3565b0361224857600583015461223e908390613046565b6005840155612277565b600186600381111561225c5761225c612ad3565b03612277576003830154612271908390613046565b60038401555b6001600160a01b03851660009081526006840160205260409020805487919060ff191660018360038111156122ae576122ae612ad3565b0217905550846001600160a01b0316877fb83d25c6a5d258561330739951487acb4bd09ba5190b5d32c4f261817d90679288856040516122ef929190613645565b60405180910390a3838015612308575061230887611fd0565b15612316576123168761231f565b50505050505050565b600081815261015f60205260409020805460ff19166001179055611aa661234e60c9546001600160a01b031690565b8261015f6000858152602001908152602001600020600701805480602002602001604051908101604052809291908181526020016000905b8282101561246a576000848152602090819020604080516060810182526003860290920180546001600160a01b03168352600181015493830193909352600283018054929392918401916123d99061308f565b80601f01602080910402602001604051908101604052809291908181526020018280546124059061308f565b80156124525780601f1061242757610100808354040283529160200191612452565b820191906000526020600020905b81548152906001019060200180831161243557829003601f168201915b50505050508152505081526020019060010190612386565b505050600086815261015f60205260409020600801549050612656565b60006001600160e01b031982167fda35c6640000000000000000000000000000000000000000000000000000000014806106a257506106a282612725565b6001600160a01b0381163b6125425760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610847565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b612599836127c0565b6000825111806125a65750805b15611aa6576111e48383612800565b60006125bf611513565b9050610b9c61012d80546001019055565b600054610100900460ff1661264d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610847565b61094c8161290b565b6040517fc71bf3240000000000000000000000000000000000000000000000000000000081526060906000906001600160a01b0387169063c71bf324906126a590889088908890600401613660565b6000604051808303816000875af11580156126c4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126ec9190810190613689565b604051919350915085907f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f90600090a294509492505050565b60006001600160e01b031982167f41de683000000000000000000000000000000000000000000000000000000000148061278857506001600160e01b031982167f52d1902d00000000000000000000000000000000000000000000000000000000145b806106a257507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146106a2565b6127c9816124c5565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b61287f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152608401610847565b600080846001600160a01b03168460405161289a919061378f565b600060405180830381855af49150503d80600081146128d5576040519150601f19603f3d011682016040523d82523d6000602084013e6128da565b606091505b509150915061290282826040518060600160405280602781526020016137b5602791396129b7565b95945050505050565b600054610100900460ff166129885760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610847565b60c9805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b606083156129c65750816107a6565b6107a683838151156129db5781518083602001fd5b8060405162461bcd60e51b815260040161084791906137a1565b600060208284031215612a0757600080fd5b81356001600160e01b0319811681146107a657600080fd5b600060208284031215612a3157600080fd5b5035919050565b600060a08284031215612a4a57600080fd5b50919050565b600060a08284031215612a6257600080fd5b6107a68383612a38565b6001600160a01b038116811461094c57600080fd5b803560048110612a9057600080fd5b919050565b600080600060608486031215612aaa57600080fd5b833592506020840135612abc81612a6c565b9150612aca60408501612a81565b90509250925092565b634e487b7160e01b600052602160045260246000fd5b6003811061094c5761094c612ad3565b60208101612b0683612ae9565b91905290565b600060208284031215612b1e57600080fd5b81356107a681612a6c565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612b6857612b68612b29565b604052919050565b600067ffffffffffffffff821115612b8a57612b8a612b29565b50601f01601f191660200190565b60008060408385031215612bab57600080fd5b8235612bb681612a6c565b9150602083013567ffffffffffffffff811115612bd257600080fd5b8301601f81018513612be357600080fd5b8035612bf6612bf182612b70565b612b3f565b818152866020838501011115612c0b57600080fd5b816020840160208301376000602083830101528093505050509250929050565b60008060408385031215612c3e57600080fd5b823591506020830135612c5081612a6c565b809150509250929050565b60048110612c6b57612c6b612ad3565b9052565b602081016106a28284612c5b565b60008083601f840112612c8f57600080fd5b50813567ffffffffffffffff811115612ca757600080fd5b6020830191508360208260051b8501011115612cc257600080fd5b9250929050565b67ffffffffffffffff8116811461094c57600080fd5b8035612a9081612cc9565b801515811461094c57600080fd5b8035612a9081612cea565b600080600080600080600080600060e08a8c031215612d2157600080fd5b893567ffffffffffffffff80821115612d3957600080fd5b818c0191508c601f830112612d4d57600080fd5b813581811115612d5c57600080fd5b8d6020828501011115612d6e57600080fd5b60209283019b509950908b01359080821115612d8957600080fd5b50612d968c828d01612c7d565b90985096505060408a01359450612daf60608b01612cdf565b9350612dbd60808b01612cdf565b9250612dcb60a08b01612a81565b9150612dd960c08b01612cf8565b90509295985092959850929598565b600080600060e08486031215612dfd57600080fd5b8335612e0881612a6c565b9250612e178560208601612a38565b915060c0840135612e2781612a6c565b809150509250925092565b60005b83811015612e4d578181015183820152602001612e35565b50506000910152565b60008151808452612e6e816020860160208601612e32565b601f01601f19169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b85811015612ef3578284038952815180516001600160a01b031685528581015186860152604090810151606091860182905290612edf81870183612e56565b9a87019a9550505090840190600101612ea0565b5091979650505050505050565b60006101a0881515835287151560208401528651612f1d81612ae9565b8060408501525063ffffffff6020880151166060840152604087015167ffffffffffffffff80821660808601528060608a01511660a08601528060808a01511660c0860152505060a087015160e0840152612f906101008401878051825260208082015190830152604090810151910152565b80610160840152612fa381840186612e82565b91505082610180830152979650505050505050565b600080600060608486031215612fcd57600080fd5b83359250612fdd60208501612a81565b91506040840135612e2781612cea565b634e487b7160e01b600052601160045260246000fd5b818103818111156106a2576106a2612fed565b80820281158282048414176106a2576106a2612fed565b60006020828403121561303f57600080fd5b5051919050565b808201808211156106a2576106a2612fed565b634e487b7160e01b600052603260045260246000fd5b60008235605e1983360301811261308557600080fd5b9190910192915050565b600181811c908216806130a357607f821691505b602082108103612a4a57634e487b7160e01b600052602260045260246000fd5b601f821115611aa657600081815260208120601f850160051c810160208610156130ea5750805b601f850160051c820191505b818110156116c2578281556001016130f6565b813561311481612a6c565b6001600160a01b03811673ffffffffffffffffffffffffffffffffffffffff1983541617825550600160208084013582840155600283016040850135601e1986360301811261316257600080fd5b8501803567ffffffffffffffff81111561317b57600080fd5b803603848301131561318c57600080fd5b6131a08161319a855461308f565b856130c3565b6000601f8211600181146131d657600083156131be57508382018601355b600019600385901b1c1916600184901b17855561322f565b600085815260209020601f19841690835b82811015613206578685018901358255938801939089019088016131e7565b50848210156132255760001960f88660031b161c198885880101351681555b50508683881b0185555b505050505050505050565b8381526001600160a01b03831660208201526060810161325d6040830184612c5b565b949350505050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b60006001600160a01b038088168352808716602084015250846040830152608060608301526132c3608083018486613265565b979650505050505050565b6000602082840312156132e057600080fd5b81516107a681612cea565b63ffffffff8116811461094c57600080fd5b60006020828403121561330f57600080fd5b81356107a6816132eb565b60006020828403121561332c57600080fd5b81356107a681612cc9565b6003811061094c57600080fd5b600081356106a281612cc9565b813561335c81613337565b61336581612ae9565b815460ff821691508160ff1982161783556020840135613384816132eb565b64ffffffff008160081b16905080837fffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000084161717845560408501356133c8816132eb565b68ffffffff00000000008160281b16847fffffffffffffffffffffffffffffffffffffffffffffff00000000000000000085161783171785555050505061345661341460608401613344565b82547fffffffffffffffffffffffffffffff0000000000000000ffffffffffffffffff1660489190911b70ffffffffffffffff00000000000000000016178255565b608082013560018201555050565b60006020828403121561347657600080fd5b81356107a681613337565b60a0810161348e87612ae9565b95815263ffffffff948516602082015292909316604083015267ffffffffffffffff1660608201526080015290565b600067ffffffffffffffff808a1683526020818a1681850152604060a0818601526134ec60a086018a8c613265565b606086820381880152818983528483019050848a60051b8401018b60005b8c8110156135ae57601f198684030184528135605e198f360301811261352f57600080fd5b8e01803561353c81612a6c565b6001600160a01b0316845280890135898501528781013536829003601e1901811261356657600080fd5b0188810190358a81111561357957600080fd5b80360382131561358857600080fd5b868986015261359a8786018284613265565b958a0195945050509087019060010161350a565b50508097505050505050505082608083015298975050505050505050565b67ffffffffffffffff818116838216019080821115611ecc57611ecc612fed565b634e487b7160e01b600052601260045260246000fd5b600082613612576136126135ed565b500690565b600082613626576136266135ed565b500490565b6000600019820361363e5761363e612fed565b5060010190565b604081016136538285612c5b565b8260208301529392505050565b8381526060602082015260006136796060830185612e82565b9050826040830152949350505050565b600080604080848603121561369d57600080fd5b835167ffffffffffffffff808211156136b557600080fd5b818601915086601f8301126136c957600080fd5b81516020828211156136dd576136dd612b29565b8160051b6136ec828201612b3f565b928352848101820192828101908b85111561370657600080fd5b83870192505b8483101561377b578251868111156137245760008081fd5b8701603f81018d136137365760008081fd5b84810151613746612bf182612b70565b8181528e8b83850101111561375b5760008081fd5b61376a828883018d8601612e32565b84525050918301919083019061370c565b9990920151989a9899505050505050505050565b60008251613085818460208701612e32565b6020815260006107a66020830184612e5656fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a444b6e77b32316d537e238b5ce5ba5513d43834406978ef37cad7cc9302075764736f6c63430008110033
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620000875760003560e01c80639cb0a12411620000625780639cb0a1241462000120578063a8a9c29e1462000146578063e89b6b91146200016d578063f10832f1146200019557600080fd5b806301ffc9a7146200008c578063599cb1a614620000b85780635c60da1b14620000f9575b600080fd5b620000a36200009d366004620014ae565b620001bc565b60405190151581526020015b60405180910390f35b620000e07f0000000000000000000000007b0189345261375c2de9185ca4cebc1974827c0981565b6040516001600160a01b039091168152602001620000af565b7f0000000000000000000000003ce7c13d183eb46e4dd5828710954aa92d3086b1620000e0565b62000137620001313660046200150b565b6200020d565b604051620000af9190620015d4565b6200015d6200015736600462001621565b6200075f565b604051620000af92919062001795565b620000e07f0000000000000000000000007432f332ad071cbd95c8e92c28e5aa7c9177ab2981565b620001ac620001a6366004620017c7565b62000787565b604051620000af92919062001851565b60006001600160e01b031982167f99718b500000000000000000000000000000000000000000000000000000000014806200020757506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600062000220602084018462001875565b9150506001811462000266576040517ff14c61fc000000000000000000000000000000000000000000000000000000008152600481018290526024015b60405180910390fd5b600062000277602085018562001875565b60008181106200028b576200028b620018e7565b9050602002016020810190620002a29190620018fd565b90506000620002b18262000fec565b9050600081600081518110620002cb57620002cb620018e7565b60200260200101518015620002fa575081600181518110620002f157620002f1620018e7565b60200260200101515b801562000322575081600281518110620003185762000318620018e7565b6020026020010151155b9050806200033257600362000335565b60045b60ff1667ffffffffffffffff8111156200035357620003536200191b565b604051908082528060200260200182016040528015620003ae57816020015b6040805160a081018252600080825260208083018290529282018190526060820181905260808201528252600019909201910181620003725790505b506040805160a0810190915260018152909550602080820190620003d590890189620018fd565b6001600160a01b03168152602001886001600160a01b0316815260200160006001600160a01b031681526020017f0000000000000000000000003ce7c13d183eb46e4dd5828710954aa92d3086b16001600160a01b0316631befc4056040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000461573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000487919062001931565b81525085600081518110620004a057620004a0620018e7565b60209081029190910101526040805160a081019091528060018152602090810190620004cf90890189620018fd565b6001600160a01b03168152602001886001600160a01b0316815260200160006001600160a01b031681526020017f0000000000000000000000003ce7c13d183eb46e4dd5828710954aa92d3086b16001600160a01b031663c9c4bfca6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200055b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000581919062001931565b815250856001815181106200059a576200059a620018e7565b60209081029190910101526040805160a081019091528060018152602001886001600160a01b03168152602001876000016020810190620005dc9190620018fd565b6001600160a01b0316815260200160006001600160a01b03168152602001886001600160a01b0316630729d0546040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000639573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200065f919062001931565b81525085600281518110620006785762000678620018e7565b6020026020010181905250801562000755576040805160a081019091528060018152602001846001600160a01b03168152602001886001600160a01b0316815260200160006001600160a01b03168152602001846001600160a01b031663b2d2989c6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200070a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000730919062001931565b81525085600381518110620007495762000749620018e7565b60200260200101819052505b5050505092915050565b60606200077f604051806040016040528060608152602001606081525090565b935093915050565b6000620007a7604051806040016040528060608152602001606081525090565b60008080620007b98688018862001c6f565b815160408051600180825281830190925294975092955090935091600091602080830190803683370190505090506001600160a01b0382161562000a54576001600160a01b0382163b62000845576040517f18aca2db0000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024016200025d565b620008508262001130565b62000893576040517ffa8925f10000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024016200025d565b6000620008a08362000fec565b905080600081518110620008b857620008b8620018e7565b6020026020010151158015620008e9575080600181518110620008df57620008df620018e7565b6020026020010151155b801562000911575080600281518110620009075762000907620018e7565b6020026020010151155b80620009865750806000815181106200092e576200092e620018e7565b602002602001015180156200095e575080600181518110620009545762000954620018e7565b6020026020010151155b8015620009865750806002815181106200097c576200097c620018e7565b6020026020010151155b1562000a4d57620009c07f0000000000000000000000007432f332ad071cbd95c8e92c28e5aa7c9177ab296001600160a01b031662001200565b8551602087015160408089015190517f906571470000000000000000000000000000000000000000000000000000000081529396506001600160a01b0387169363906571479362000a18939092909160040162001d52565b600060405180830381600087803b15801562000a3357600080fd5b505af115801562000a48573d6000803e3d6000fd5b505050505b5062000b13565b62000a887f0000000000000000000000007b0189345261375c2de9185ca4cebc1974827c096001600160a01b031662001200565b602085015160408087015190517fdab27fa90000000000000000000000000000000000000000000000000000000081529294506001600160a01b0385169263dab27fa99262000ade928f92899060040162001d94565b600060405180830381600087803b15801562000af957600080fd5b505af115801562000b0e573d6000803e3d6000fd5b505050505b818160008151811062000b2a5762000b2a620018e7565b60200260200101906001600160a01b031690816001600160a01b03168152505062000bc67f0000000000000000000000003ce7c13d183eb46e4dd5828710954aa92d3086b163b2673b0760e01b8c888660405160240162000b8e9392919062001e3c565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152620012bd565b84519097506000906001600160a01b031662000be457600462000be7565b60035b60ff1667ffffffffffffffff81111562000c055762000c056200191b565b60405190808252806020026020018201604052801562000c6057816020015b6040805160a08101825260008082526020808301829052928201819052606082018190526080820152825260001990920191018162000c245790505b506040805160a081019091529091508060008152602001896001600160a01b031681526020018c6001600160a01b0316815260200160006001600160a01b031681526020017f0000000000000000000000003ce7c13d183eb46e4dd5828710954aa92d3086b16001600160a01b0316631befc4056040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d04573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d2a919062001931565b8152508160008151811062000d435762000d43620018e7565b60209081029190910101526040805160a081019091528060008152602001896001600160a01b031681526020018c6001600160a01b0316815260200160006001600160a01b031681526020017f0000000000000000000000003ce7c13d183eb46e4dd5828710954aa92d3086b16001600160a01b031663c9c4bfca6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000dee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e14919062001931565b8152508160018151811062000e2d5762000e2d620018e7565b60209081029190910101526040805160a0810190915280600081526020018c6001600160a01b03168152602001896001600160a01b0316815260200160006001600160a01b031681526020018c6001600160a01b0316630729d0546040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000eb8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ede919062001931565b8152508160028151811062000ef75762000ef7620018e7565b602090810291909101015284516001600160a01b031662000fd5576000836001600160a01b031663b2d2989c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000f53573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f79919062001931565b6040805160a0810190915290915080600081526001600160a01b0380871660208301528e1660408201526000606082015260800182905282518390600390811062000fc85762000fc8620018e7565b6020026020010181905250505b908652602086015250939792965091945050505050565b60408051600380825260808201909252606091600091906020820184803683370190505090507f36372b070000000000000000000000000000000000000000000000000000000081600081518110620010495762001049620018e7565b60200260200101906001600160e01b03191690816001600160e01b031916815250507fe90fb3f60000000000000000000000000000000000000000000000000000000081600181518110620010a257620010a2620018e7565b60200260200101906001600160e01b03191690816001600160e01b031916815250507f0f13099a0000000000000000000000000000000000000000000000000000000081600281518110620010fb57620010fb620018e7565b6001600160e01b031990921660209283029190910190910152620011296001600160a01b03841682620012cb565b9392505050565b604080513060248083019190915282518083039091018152604490910182526020810180516001600160e01b03167f70a08231000000000000000000000000000000000000000000000000000000001790529051600091829182916001600160a01b03861691620011a2919062001eb2565b600060405180830381855afa9150503d8060008114620011df576040519150601f19603f3d011682016040523d82523d6000602084013e620011e4565b606091505b5091509150818015620011f8575080516020145b949350505050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008260601b60e81c176000526e5af43d82803e903d91602b57fd5bf38260781b17602052603760096000f090506001600160a01b038116620012b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f455243313136373a20637265617465206661696c65640000000000000000000060448201526064016200025d565b919050565b6000620011298383620013a1565b60606000825167ffffffffffffffff811115620012ec57620012ec6200191b565b60405190808252806020026020018201604052801562001316578160200160208202803683370190505b5090506200132484620013dd565b15620011295760005b835181101562001399576200135f85858381518110620013515762001351620018e7565b602002602001015162001415565b828281518110620013745762001374620018e7565b9115156020928302919091019091015280620013908162001ed0565b9150506200132d565b509392505050565b60008282604051620013b390620014a0565b620013c092919062001ef9565b604051809103906000f08015801562001399573d6000803e3d6000fd5b6000620013f2826301ffc9a760e01b62001415565b80156200020757506200140e826001600160e01b031962001415565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d9150600051905082801562001488575060208210155b8015620014955750600081115b979650505050505050565b6107ad8062001f1e83390190565b600060208284031215620014c157600080fd5b81356001600160e01b0319811681146200112957600080fd5b80356001600160a01b0381168114620012b857600080fd5b6000606082840312156200150557600080fd5b50919050565b600080604083850312156200151f57600080fd5b6200152a83620014da565b9150602083013567ffffffffffffffff8111156200154757600080fd5b6200155585828601620014f2565b9150509250929050565b600381106200157e57634e487b7160e01b600052602160045260246000fd5b50565b6000815162001590816200155f565b8352506020818101516001600160a01b0390811691840191909152604080830151821690840152606080830151909116908301526080908101519082015260a00190565b6020808252825182820181905260009190848201906040850190845b8181101562001615576200160683855162001581565b938501939250600101620015f0565b50909695505050505050565b6000806000606084860312156200163757600080fd5b6200164284620014da565b9250602084013561ffff811681146200165a57600080fd5b9150604084013567ffffffffffffffff8111156200167757600080fd5b6200168586828701620014f2565b9150509250925092565b60005b83811015620016ac57818101518382015260200162001692565b50506000910152565b60008151808452620016cf8160208601602086016200168f565b601f01601f19169290920160200192915050565b600081518084526020808501945080840160005b838110156200171e5781516001600160a01b031687529582019590820190600101620016f7565b509495945050505050565b6000815160408452620017406040850182620016e3565b60208481015186830387830152805180845290820193509091600091908301905b808310156200178a576200177782865162001581565b9150838501945060018301925062001761565b509695505050505050565b604081526000620017aa6040830185620016b5565b8281036020840152620017be818562001729565b95945050505050565b600080600060408486031215620017dd57600080fd5b620017e884620014da565b9250602084013567ffffffffffffffff808211156200180657600080fd5b818601915086601f8301126200181b57600080fd5b8135818111156200182b57600080fd5b8760208285010111156200183e57600080fd5b6020830194508093505050509250925092565b6001600160a01b0383168152604060208201526000620011f8604083018462001729565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112620018ab57600080fd5b83018035915067ffffffffffffffff821115620018c757600080fd5b6020019150600581901b3603821315620018e057600080fd5b9250929050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156200191057600080fd5b6200112982620014da565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156200194457600080fd5b5051919050565b6040805190810167ffffffffffffffff811182821017156200197157620019716200191b565b60405290565b60405160a0810167ffffffffffffffff811182821017156200197157620019716200191b565b604051601f8201601f1916810167ffffffffffffffff81118282101715620019c957620019c96200191b565b604052919050565b803563ffffffff81168114620012b857600080fd5b600082601f830112620019f857600080fd5b813567ffffffffffffffff81111562001a155762001a156200191b565b62001a2a6020601f19601f840116016200199d565b81815284602083860101111562001a4057600080fd5b816020850160208301376000918101602001919091529392505050565b60006060828403121562001a7057600080fd5b6040516060810167ffffffffffffffff828210818311171562001a975762001a976200191b565b8160405282935062001aa985620014da565b8352602085013591508082111562001ac057600080fd5b62001ace86838701620019e6565b6020840152604085013591508082111562001ae857600080fd5b5062001af785828601620019e6565b6040830152505092915050565b600067ffffffffffffffff82111562001b215762001b216200191b565b5060051b60200190565b600082601f83011262001b3d57600080fd5b8135602062001b5662001b508362001b04565b6200199d565b82815260059290921b8401810191818101908684111562001b7657600080fd5b8286015b848110156200178a578035835291830191830162001b7a565b60006040828403121562001ba657600080fd5b62001bb06200194b565b9050813567ffffffffffffffff8082111562001bcb57600080fd5b818401915084601f83011262001be057600080fd5b8135602062001bf362001b508362001b04565b82815260059290921b8401810191818101908884111562001c1357600080fd5b948201945b8386101562001c3c5762001c2c86620014da565b8252948201949082019062001c18565b8652508581013593508284111562001c5357600080fd5b62001c618785880162001b2b565b818601525050505092915050565b600080600083850360e081121562001c8657600080fd5b60a081121562001c9557600080fd5b5062001ca062001977565b84356003811062001cb057600080fd5b815262001cc060208601620019d1565b602082015262001cd360408601620019d1565b6040820152606085013567ffffffffffffffff808216821462001cf557600080fd5b8160608401526080870135608084015282955060a087013592508083111562001d1d57600080fd5b62001d2b8884890162001a5d565b945060c087013592508083111562001d4257600080fd5b5050620016858682870162001b93565b6001600160a01b038416815260606020820152600062001d766060830185620016b5565b828103604084015262001d8a8185620016b5565b9695505050505050565b6001600160a01b03851681526000602060808184015262001db96080840187620016b5565b838103604085015262001dcd8187620016b5565b9050838103606085015284516040825262001dec6040830182620016e3565b8684015183820393850193909352825180825290840192840191506000905b8082101562001e2d578251845292840192918401916001919091019062001e0b565b50919998505050505050505050565b6001600160a01b038481168252835160e08301919062001e5c816200155f565b80602085015250602085015163ffffffff8082166040860152806040880151166060860152505067ffffffffffffffff6060860151166080840152608085015160a084015280841660c084015250949350505050565b6000825162001ec68184602087016200168f565b9190910192915050565b6000600019820362001ef257634e487b7160e01b600052601160045260246000fd5b5060010190565b6001600160a01b0383168152604060208201526000620011f86040830184620016b556fe60806040526040516107ad3803806107ad83398101604081905261002291610319565b61002e82826000610035565b5050610436565b61003e8361006b565b60008251118061004b5750805b156100665761006483836100ab60201b6100291760201c565b505b505050565b610074816100d7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606100d08383604051806060016040528060278152602001610786602791396101a9565b9392505050565b6100ea8161022260201b6100551760201c565b6101515760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084015b60405180910390fd5b806101887f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b61023160201b6100711760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b6060600080856001600160a01b0316856040516101c691906103e7565b600060405180830381855af49150503d8060008114610201576040519150601f19603f3d011682016040523d82523d6000602084013e610206565b606091505b50909250905061021886838387610234565b9695505050505050565b6001600160a01b03163b151590565b90565b606083156102a357825160000361029c576001600160a01b0385163b61029c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610148565b50816102ad565b6102ad83836102b5565b949350505050565b8151156102c55781518083602001fd5b8060405162461bcd60e51b81526004016101489190610403565b634e487b7160e01b600052604160045260246000fd5b60005b838110156103105781810151838201526020016102f8565b50506000910152565b6000806040838503121561032c57600080fd5b82516001600160a01b038116811461034357600080fd5b60208401519092506001600160401b038082111561036057600080fd5b818501915085601f83011261037457600080fd5b815181811115610386576103866102df565b604051601f8201601f19908116603f011681019083821181831017156103ae576103ae6102df565b816040528281528860208487010111156103c757600080fd5b6103d88360208301602088016102f5565b80955050505050509250929050565b600082516103f98184602087016102f5565b9190910192915050565b60208152600082518060208401526104228160408501602087016102f5565b601f01601f19169190910160400192915050565b610341806104456000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610074565b6100b9565b565b606061004e83836040518060600160405280602781526020016102e5602791396100dd565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b90565b60006100b47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b3660008037600080366000845af43d6000803e8080156100d8573d6000f35b3d6000fd5b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516101079190610277565b600060405180830381855af49150503d8060008114610142576040519150601f19603f3d011682016040523d82523d6000602084013e610147565b606091505b509150915061015886838387610162565b9695505050505050565b606083156101fd5782516000036101f65773ffffffffffffffffffffffffffffffffffffffff85163b6101f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610207565b610207838361020f565b949350505050565b81511561021f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ed9190610293565b60005b8381101561026e578181015183820152602001610256565b50506000910152565b60008251610289818460208701610253565b9190910192915050565b60208152600082518060208401526102b2816040850160208701610253565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220a7c6f2fcb78c7b4c40d8fd8b3b79a2770d3af4a9e7da56689bfa5ce2c1ce5a2164736f6c63430008110033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212203a85aa1185f8c81fbbb2df9e52860eb11b92c66df30ec936c97a3384f39e2ed164736f6c63430008110033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.