Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
16721863 | 711 days ago | Contract Creation | 0 ETH |
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 Source Code Verified (Exact Match)
Contract Name:
DAO
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 "@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 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); for (uint256 i = 0; i < _actions.length; ) { address to = _actions[i].to; (bool success, bytes memory response) = to.call{value: _actions[i].value}( _actions[i].data ); if (!success) { // If the call failed and wasn't allowed in allowFailureMap, revert. if (!hasBit(_allowFailureMap, uint8(i))) { revert ActionFailed(i); } // If the call failed, but was allowed in allowFailureMap, store that // this specific action has actually failed. failureMap = flipBit(failureMap, uint8(i)); } execResults[i] = response; 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: 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 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.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/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.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 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: 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 no failure map is provided, one failing action results in the entire excution to be reverted. If a non-zero failure map is provided, allowed actions can fail without the remaining actions 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 constructed failureMap which contains which 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; /// @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; }
{ "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":"uint256","name":"index","type":"uint256"}],"name":"ActionFailed","type":"error"},{"inputs":[],"name":"AnyAddressDisallowedForWhoAndWhere","type":"error"},{"inputs":[],"name":"ConditionNotPresentForAnyAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"NativeTokenDepositAmountMismatch","type":"error"},{"inputs":[{"internalType":"address","name":"where","type":"address"},{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"},{"internalType":"address","name":"currentCondition","type":"address"},{"internalType":"address","name":"newCondition","type":"address"}],"name":"PermissionAlreadyGrantedForDifferentCondition","type":"error"},{"inputs":[],"name":"PermissionsForAnyAddressDisallowed","type":"error"},{"inputs":[],"name":"TooManyActions","type":"error"},{"inputs":[{"internalType":"address","name":"where","type":"address"},{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"}],"name":"Unauthorized","type":"error"},{"inputs":[{"internalType":"bytes4","name":"callbackSelector","type":"bytes4"},{"internalType":"bytes4","name":"magicNumber","type":"bytes4"}],"name":"UnkownCallback","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"CallbackReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"_reference","type":"string"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":false,"internalType":"bytes32","name":"callId","type":"bytes32"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct IDAO.Action[]","name":"actions","type":"tuple[]"},{"indexed":false,"internalType":"uint256","name":"failureMap","type":"uint256"},{"indexed":false,"internalType":"bytes[]","name":"execResults","type":"bytes[]"}],"name":"Executed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"permissionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"here","type":"address"},{"indexed":false,"internalType":"address","name":"where","type":"address"},{"indexed":true,"internalType":"address","name":"who","type":"address"},{"indexed":false,"internalType":"contract IPermissionCondition","name":"condition","type":"address"}],"name":"Granted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"MetadataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeTokenDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"daoURI","type":"string"}],"name":"NewURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"permissionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"here","type":"address"},{"indexed":false,"internalType":"address","name":"where","type":"address"},{"indexed":true,"internalType":"address","name":"who","type":"address"}],"name":"Revoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signatureValidator","type":"address"}],"name":"SignatureValidatorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"interfaceId","type":"bytes4"},{"indexed":false,"internalType":"bytes4","name":"callbackSelector","type":"bytes4"},{"indexed":false,"internalType":"bytes4","name":"magicNumber","type":"bytes4"}],"name":"StandardCallbackRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"forwarder","type":"address"}],"name":"TrustedForwarderSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"EXECUTE_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTER_STANDARD_CALLBACK_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_METADATA_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_SIGNATURE_VALIDATOR_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_TRUSTED_FORWARDER_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPGRADE_DAO_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"_items","type":"tuple[]"}],"name":"applyMultiTargetPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"components":[{"internalType":"enum PermissionLib.Operation","name":"operation","type":"uint8"},{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"}],"internalType":"struct PermissionLib.SingleTargetPermission[]","name":"items","type":"tuple[]"}],"name":"applySingleTargetPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"daoURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_reference","type":"string"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_callId","type":"bytes32"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IDAO.Action[]","name":"_actions","type":"tuple[]"},{"internalType":"uint256","name":"_allowFailureMap","type":"uint256"}],"name":"execute","outputs":[{"internalType":"bytes[]","name":"execResults","type":"bytes[]"},{"internalType":"uint256","name":"failureMap","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getTrustedForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"}],"name":"grant","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"},{"internalType":"contract IPermissionCondition","name":"_condition","type":"address"}],"name":"grantWithCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"hasPermission","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_metadata","type":"bytes"},{"internalType":"address","name":"_initialOwner","type":"address"},{"internalType":"address","name":"_trustedForwarder","type":"address"},{"internalType":"string","name":"daoURI_","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"isGranted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"},{"internalType":"bytes4","name":"_callbackSelector","type":"bytes4"},{"internalType":"bytes4","name":"_magicNumber","type":"bytes4"}],"name":"registerStandardCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"}],"name":"revoke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newDaoURI","type":"string"}],"name":"setDaoURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_metadata","type":"bytes"}],"name":"setMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signatureValidator","type":"address"}],"name":"setSignatureValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTrustedForwarder","type":"address"}],"name":"setTrustedForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signatureValidator","outputs":[{"internalType":"contract IERC1271","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161353b6200012060003960008181610a6c01528181610b0201528181610c9701528181610d2d0152610e28015261353b6000f3fe6080604052600436106101d15760003560e01c8063829331a1116100f7578063d96054c411610095578063e978afe511610064578063e978afe5146106b2578063eafb8b06146106d2578063ee57e36f146106f2578063fdef91061461071257610210565b8063d96054c41461060a578063da7422281461062a578063e2e355631461064a578063e306bee71461067e57610210565b8063c71bf324116100d1578063c71bf3241461057d578063c9dbc2a4146105ab578063ce1b815f146105cb578063d68bad2c146105ea57610210565b8063829331a114610516578063bfe07da61461054a578063c4a501451461055d57610210565b80632675fdd01161016f5780633e2ab0d91161013e5780633e2ab0d9146104ac5780634f1ef286146104cc57806352d1902d146104df5780637034731b146104f457610210565b80632675fdd0146103ff57806326875b1f1461041f5780633659cfe614610453578063388da9341461047357610210565b80631080f99b116101ab5780631080f99b146103505780631626ba7e1461037257806322844d04146103ab57806324b4d73f146103cb57610210565b806301ffc9a7146102a55780630729d054146102da57806309e56b141461031c57610210565b3661021057604080513381523460208201527f62c2c8e34665db7c56b2cabd7f5fb9702ccd352ffa8150147e450797e9f8e8f3910160405180910390a1005b34801561021c57600080fd5b50600036606060006102706000356001600160e01b03191685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061073292505050565b604080516001600160e01b03198316602082015291925001604051602081830303815290604052915050915050805190602001f35b3480156102b157600080fd5b506102c56102c03660046128ee565b610809565b60405190151581526020015b60405180910390f35b3480156102e657600080fd5b5061030e7fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d81565b6040519081526020016102d1565b34801561032857600080fd5b5061030e7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada3381565b34801561035c57600080fd5b5061037061036b366004612954565b61085e565b005b34801561037e57600080fd5b5061039261038d366004612a39565b610897565b6040516001600160e01b031990911681526020016102d1565b3480156103b757600080fd5b506103706103c6366004612a95565b610947565b3480156103d757600080fd5b5061030e7f1f53edd44352e5d15bad2b29233baa93bcd595e09457780bc7c5445bbbe751cc81565b34801561040b57600080fd5b506102c561041a366004612b1d565b610a17565b34801561042b57600080fd5b5061030e7ffaf505be9907aa6951c2ebe5b0312f4980e14f21912ed355372103cc8bd683bc81565b34801561045f57600080fd5b5061037061046e366004612b89565b610a62565b34801561047f57600080fd5b5061012d54610494906001600160a01b031681565b6040516001600160a01b0390911681526020016102d1565b3480156104b857600080fd5b506103706104c7366004612b89565b610bff565b6103706104da366004612ba6565b610c8d565b3480156104eb57600080fd5b5061030e610e1b565b34801561050057600080fd5b50610509610ee0565b6040516102d19190612c30565b34801561052257600080fd5b5061030e7f06d294bc8cbad2e393408b20dd019a772661f60b8d633e56761157cb1ec85f8c81565b610370610558366004612c43565b610f73565b34801561056957600080fd5b50610370610578366004612c9f565b6110ad565b34801561058957600080fd5b5061059d610598366004612cea565b611160565b6040516102d1929190612dc4565b3480156105b757600080fd5b506103706105c6366004612de6565b6113e9565b3480156105d757600080fd5b5061012e546001600160a01b0316610494565b3480156105f657600080fd5b50610370610605366004612e39565b61141f565b34801561061657600080fd5b50610370610625366004612e39565b61145a565b34801561063657600080fd5b50610370610645366004612b89565b61148f565b34801561065657600080fd5b5061030e7f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e77808837281565b34801561068a57600080fd5b5061030e7f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b81565b3480156106be57600080fd5b506103706106cd366004612e7a565b6114c2565b3480156106de57600080fd5b506103706106ed366004612eef565b6115c9565b3480156106fe57600080fd5b5061037061070d366004612954565b611790565b34801561071e57600080fd5b506102c561072d366004612b1d565b6117c4565b6001600160e01b0319808316600090815260fb6020526040812054909160e09190911b9081166107a7576040517f54bdcc3e0000000000000000000000000000000000000000000000000000000081526001600160e01b03198086166004830152821660248201526044015b60405180910390fd5b837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f4792cb6e46e49876374bea490ba23274bacea6b84c216a64f47abab54027589b33856040516107f8929190612f88565b60405180910390a290505b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b0319831614806108035750506001600160e01b03191660009081526033602052604090205460ff1690565b7f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b610888816117d2565b610892838361185a565b505050565b61012d546000906001600160a01b03166108b357506000610803565b61012d546040517f1626ba7e0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690631626ba7e906108ff9086908690600401612faa565b602060405180830381865afa15801561091c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109409190612fc3565b9392505050565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33610971816117d2565b60005b82811015610a1057600084848381811061099057610990612fe0565b9050606002018036038101906109a6919061300a565b90506000815160028111156109bd576109bd613073565b036109da576109d5868260200151836040015161189a565b610a07565b6001815160028111156109ef576109ef613073565b03610a0757610a0786826020015183604001516118a7565b50600101610974565b5050505050565b6000610a25858585856119ae565b80610a3e5750610a3e856001600160a01b0385856119ae565b80610a575750610a576001600160a01b038585856119ae565b90505b949350505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610b005760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c0000000000000000000000000000000000000000606482015260840161079e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610b5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610bd75760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f78790000000000000000000000000000000000000000606482015260840161079e565b610be081611b22565b60408051600080825260208201909252610bfc91839190611b4c565b50565b7f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e778088372610c29816117d2565b61012d805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040519081527f3b25c5d3870ec0eac28822b177f18c9130233ade5b7f857c6a224a507c37fc4e906020015b60405180910390a15050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610d2b5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c0000000000000000000000000000000000000000606482015260840161079e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610d867f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610e025760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f78790000000000000000000000000000000000000000606482015260840161079e565b610e0b82611b22565b610e1782826001611b4c565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610ebb5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161079e565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b606061012f8054610ef090613089565b80601f0160208091040260200160405190810160405280929190818152602001828054610f1c90613089565b8015610f695780601f10610f3e57610100808354040283529160200191610f69565b820191906000526020600020905b815481529060010190602001808311610f4c57829003601f168201915b5050505050905090565b82600003610fad576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03841661100257823414610ffd576040517f1abd56100000000000000000000000000000000000000000000000000000000081526004810184905234602482015260440161079e565b611058565b3415611043576040517f1abd56100000000000000000000000000000000000000000000000000000000081526000600482015234602482015260440161079e565b6110586001600160a01b038516333086611cec565b836001600160a01b0316336001600160a01b03167f2bc500cf071be2d1c1458ed6ff484cd4db4345ada8943dee7ff29e7af3558f7685858560405161109f939291906130ee565b60405180910390a350505050565b7ffaf505be9907aa6951c2ebe5b0312f4980e14f21912ed355372103cc8bd683bc6110d7816117d2565b6110e084611d74565b6001600160e01b03198316600090815260fb60205260409020805463ffffffff191660e084901c179055604080516001600160e01b0319808716825280861660208301528416918101919091527ffc72fd547553f7a663e0048e590afc9c47b56a4242e960f31cf4c62e23d308b99060600160405180910390a150505050565b606060007fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d61118e816117d2565b6101008511156111ca576040517f11c763d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8467ffffffffffffffff8111156111e3576111e3612996565b60405190808252806020026020018201604052801561121657816020015b60608152602001906001900390816112015790505b50925060005b8581101561139557600087878381811061123857611238612fe0565b905060200281019061124a9190613108565b611258906020810190612b89565b9050600080826001600160a01b03168a8a8681811061127957611279612fe0565b905060200281019061128b9190613108565b602001358b8b878181106112a1576112a1612fe0565b90506020028101906112b39190613108565b6112c1906040810190613128565b6040516112cf92919061316f565b60006040518083038185875af1925050503d806000811461130c576040519150601f19603f3d011682016040523d82523d6000602084013e611311565b606091505b50915091508161136957600160ff85161b881661135d576040517fa6a7dbbd0000000000000000000000000000000000000000000000000000000081526004810185905260240161079e565b600160ff85161b861895505b8087858151811061137c5761137c612fe0565b602002602001018190525083600101935050505061121c565b50336001600160a01b03167fd0de18eab8dc7532aab0fc4eb308477031cabf9fd312ea3b3a5fe9aa45ac8ed788888886886040516113d795949392919061317f565b60405180910390a25094509492505050565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33611413816117d2565b610a1085858585611df3565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33611449816117d2565b61145484848461189a565b50505050565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33611484816117d2565b6114548484846118a7565b7f06d294bc8cbad2e393408b20dd019a772661f60b8d633e56761157cb1ec85f8c6114b9816117d2565b610e17826120b1565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada336114ec816117d2565b60005b8281101561145457600084848381811061150b5761150b612fe0565b905060a0020180360381019061152191906132a4565b905060008151600281111561153857611538613073565b036115595761155481602001518260400151836080015161189a565b6115c0565b60018151600281111561156e5761156e613073565b0361158a576115548160200151826040015183608001516118a7565b60028151600281111561159f5761159f613073565b036115c0576115c08160200151826040015183608001518460600151611df3565b506001016114ef565b600054610100900460ff16158080156115e95750600054600160ff909116105b806116035750303b158015611603575060005460ff166001145b6116755760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161079e565b6000805460ff191660011790558015611698576000805461ff0019166101001790555b6116c17f9385547e00000000000000000000000000000000000000000000000000000000611d74565b6116ea7f1626ba7e00000000000000000000000000000000000000000000000000000000611d74565b6117137f7034731b00000000000000000000000000000000000000000000000000000000611d74565b61171b612113565b6117258787612220565b61172e846120b1565b611738838361185a565b61174185612251565b8015611787576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b7f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b6117ba816117d2565b6108928383612220565b6000610a5785858585610a17565b6118153033836000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610a1792505050565b610bfc576040517f1e09743f0000000000000000000000000000000000000000000000000000000081523060048201523360248201526044810182905260640161079e565b61012f611868828483613381565b507fe9b617ecb5f63f6a9ccd8d4d5fa0d7b2ef9b17ce3f48e6b135808d6a40e677428282604051610c81929190613441565b6108928383836002611df3565b604080517f5045524d495353494f4e000000000000000000000000000000000000000000006020808301919091526bffffffffffffffffffffffff19606086811b8216602a85015287901b16603e83015260528083018590528351808403909101815260729092019092528051910120600090600081815260c960205260409020549091506001600160a01b03161561145457600081815260c96020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916905590516001600160a01b038681168252851691339185917f3ca48185ec3f6e47e24db18b13f1c65b1ce05da1659f9c1c4fe717dda5f67524910160405180910390a450505050565b60008060c96000611a338888886040517f5045524d495353494f4e0000000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606084811b8216602a84015285901b16603e820152605281018290526000906072016040516020818303038152906040528051906020012090509392505050565b81526020810191909152604001600020546001600160a01b0316905080611a5e576000915050610a5a565b6001196001600160a01b03821601611a7a576001915050610a5a565b6040517f2675fdd00000000000000000000000000000000000000000000000000000000081526001600160a01b03821690632675fdd090611ac5908990899089908990600401613455565b602060405180830381865afa925050508015611afe575060408051601f3d908101601f19168201909252611afb91810190613491565b60015b15611b16578015611b1457600192505050610a5a565b505b50600095945050505050565b7f1f53edd44352e5d15bad2b29233baa93bcd595e09457780bc7c5445bbbe751cc610e17816117d2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611b7f57610892836122d7565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611bd9575060408051601f3d908101601f19168201909252611bd6918101906134b3565b60015b611c4b5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f742055555053000000000000000000000000000000000000606482015260840161079e565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114611ce05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c65555549440000000000000000000000000000000000000000000000606482015260840161079e565b506108928383836123a2565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526114549085906123c7565b6001600160e01b03198082169003611dce5760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640161079e565b6001600160e01b0319166000908152603360205260409020805460ff19166001179055565b6001600160a01b03848116148015611e1357506001600160a01b03838116145b15611e4a576040517f85f1ba9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038481161480611e6957506001600160a01b03838116145b15611f23576000611e79836124ac565b90507f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33831480611ea65750805b15611edd576040517f24159e5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001196001600160a01b03831601611f21576040517f92ab7d0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b604080517f5045524d495353494f4e000000000000000000000000000000000000000000006020808301919091526bffffffffffffffffffffffff19606087811b8216602a85015288901b16603e83015260528083018690528351808403909101815260729092019092528051910120600090600081815260c960205260409020549091506001600160a01b0316828161203c57600083815260c96020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038581169190911790915582518a8216815287821692810192909252881691339188917f0f579ad49235a8c1fd9041427e7067b1eb10926bbed380bf6fabc73e0e807644910160405180910390a4611787565b806001600160a01b0316826001600160a01b031614611787576040517f0b98789e0000000000000000000000000000000000000000000000000000000081526001600160a01b03808916600483015280881660248301526044820187905280841660648301528216608482015260a40161079e565b61012e805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd91237492a9e30cd2faf361fc103998a382ff0ec2b1b07dc1cbebb76ae2f1ea29060200160405180910390a150565b61213c7f150b7a0200000000000000000000000000000000000000000000000000000000611d74565b6121657f4e2312e000000000000000000000000000000000000000000000000000000000611d74565b60fb6020527f5a08f87af82de422c581ce019b2e54a9c17372e9cba575ae0470ba2482d63686805463ffffffff1990811663150b7a02179091557fe1cfe341950d56d8854f782066100d5ae1d5930cdb4949b973e554a343efc6c38054821663f23a6e611790557fbc197c81000000000000000000000000000000000000000000000000000000006000527f08ba3617671847c1c169da222a5bc01cfdefcc3c4f1e5525214a474479c89123805490911663bc197c81179055565b7fbb39ebb37e60fb5d606ffdb749d2336e56b88e6c88c4bd6513b308f643186eed8282604051610c81929190613441565b600054610100900460ff166122ce5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161079e565b610bfc816125a5565b6001600160a01b0381163b6123545760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161079e565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6123ab836125d0565b6000825111806123b85750805b15610892576114548383612610565b600061241c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661271b9092919063ffffffff16565b805190915015610892578080602001905181019061243a9190613491565b6108925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161079e565b60007fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d8214806124fb57507f1f53edd44352e5d15bad2b29233baa93bcd595e09457780bc7c5445bbbe751cc82145b8061252557507f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b82145b8061254f57507f06d294bc8cbad2e393408b20dd019a772661f60b8d633e56761157cb1ec85f8c82145b8061257957507f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e77808837282145b806108035750507ffaf505be9907aa6951c2ebe5b0312f4980e14f21912ed355372103cc8bd683bc1490565b610bfc30827f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada3361189a565b6125d9816122d7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b61268f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161079e565b600080846001600160a01b0316846040516126aa91906134cc565b600060405180830381855af49150503d80600081146126e5576040519150601f19603f3d011682016040523d82523d6000602084013e6126ea565b606091505b509150915061271282826040518060600160405280602781526020016134df6027913961272a565b95945050505050565b6060610a5a8484600085612743565b60608315612739575081610940565b6109408383612835565b6060824710156127bb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161079e565b600080866001600160a01b031685876040516127d791906134cc565b60006040518083038185875af1925050503d8060008114612814576040519150601f19603f3d011682016040523d82523d6000602084013e612819565b606091505b509150915061282a8783838761285f565b979650505050505050565b8151156128455781518083602001fd5b8060405162461bcd60e51b815260040161079e9190612c30565b606083156128ce5782516000036128c7576001600160a01b0385163b6128c75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161079e565b5081610a5a565b610a5a8383612835565b6001600160e01b031981168114610bfc57600080fd5b60006020828403121561290057600080fd5b8135610940816128d8565b60008083601f84011261291d57600080fd5b50813567ffffffffffffffff81111561293557600080fd5b60208301915083602082850101111561294d57600080fd5b9250929050565b6000806020838503121561296757600080fd5b823567ffffffffffffffff81111561297e57600080fd5b61298a8582860161290b565b90969095509350505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126129bd57600080fd5b813567ffffffffffffffff808211156129d8576129d8612996565b604051601f8301601f19908116603f01168101908282118183101715612a0057612a00612996565b81604052838152866020858801011115612a1957600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215612a4c57600080fd5b82359150602083013567ffffffffffffffff811115612a6a57600080fd5b612a76858286016129ac565b9150509250929050565b6001600160a01b0381168114610bfc57600080fd5b600080600060408486031215612aaa57600080fd5b8335612ab581612a80565b9250602084013567ffffffffffffffff80821115612ad257600080fd5b818601915086601f830112612ae657600080fd5b813581811115612af557600080fd5b876020606083028501011115612b0a57600080fd5b6020830194508093505050509250925092565b60008060008060808587031215612b3357600080fd5b8435612b3e81612a80565b93506020850135612b4e81612a80565b925060408501359150606085013567ffffffffffffffff811115612b7157600080fd5b612b7d878288016129ac565b91505092959194509250565b600060208284031215612b9b57600080fd5b813561094081612a80565b60008060408385031215612bb957600080fd5b8235612bc481612a80565b9150602083013567ffffffffffffffff811115612a6a57600080fd5b60005b83811015612bfb578181015183820152602001612be3565b50506000910152565b60008151808452612c1c816020860160208601612be0565b601f01601f19169290920160200192915050565b6020815260006109406020830184612c04565b60008060008060608587031215612c5957600080fd5b8435612c6481612a80565b935060208501359250604085013567ffffffffffffffff811115612c8757600080fd5b612c938782880161290b565b95989497509550505050565b600080600060608486031215612cb457600080fd5b8335612cbf816128d8565b92506020840135612ccf816128d8565b91506040840135612cdf816128d8565b809150509250925092565b60008060008060608587031215612d0057600080fd5b84359350602085013567ffffffffffffffff80821115612d1f57600080fd5b818701915087601f830112612d3357600080fd5b813581811115612d4257600080fd5b8860208260051b8501011115612d5757600080fd5b95986020929092019750949560400135945092505050565b600081518084526020808501808196508360051b8101915082860160005b85811015612db7578284038952612da5848351612c04565b98850198935090840190600101612d8d565b5091979650505050505050565b604081526000612dd76040830185612d6f565b90508260208301529392505050565b60008060008060808587031215612dfc57600080fd5b8435612e0781612a80565b93506020850135612e1781612a80565b9250604085013591506060850135612e2e81612a80565b939692955090935050565b600080600060608486031215612e4e57600080fd5b8335612e5981612a80565b92506020840135612e6981612a80565b929592945050506040919091013590565b60008060208385031215612e8d57600080fd5b823567ffffffffffffffff80821115612ea557600080fd5b818501915085601f830112612eb957600080fd5b813581811115612ec857600080fd5b86602060a083028501011115612edd57600080fd5b60209290920196919550909350505050565b60008060008060008060808789031215612f0857600080fd5b863567ffffffffffffffff80821115612f2057600080fd5b612f2c8a838b0161290b565b909850965060208901359150612f4182612a80565b909450604088013590612f5382612a80565b90935060608801359080821115612f6957600080fd5b50612f7689828a0161290b565b979a9699509497509295939492505050565b6001600160a01b0383168152604060208201526000610a5a6040830184612c04565b828152604060208201526000610a5a6040830184612c04565b600060208284031215612fd557600080fd5b8151610940816128d8565b634e487b7160e01b600052603260045260246000fd5b80356003811061300557600080fd5b919050565b60006060828403121561301c57600080fd5b6040516060810181811067ffffffffffffffff8211171561303f5761303f612996565b60405261304b83612ff6565b8152602083013561305b81612a80565b60208201526040928301359281019290925250919050565b634e487b7160e01b600052602160045260246000fd5b600181811c9082168061309d57607f821691505b6020821081036130bd57634e487b7160e01b600052602260045260246000fd5b50919050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b838152604060208201526000610a576040830184866130c3565b60008235605e1983360301811261311e57600080fd5b9190910192915050565b6000808335601e1984360301811261313f57600080fd5b83018035915067ffffffffffffffff82111561315a57600080fd5b60200191503681900382131561294d57600080fd5b8183823760009101908152919050565b60006080820187835260206080818501528187835260a08501905060a08860051b86010192508860005b8981101561327c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608786030183528135605e198c36030181126131ec57600080fd5b8b01606081356131fb81612a80565b6001600160a01b03168752818601358688015260408083013536849003601e1901811261322757600080fd5b90920186810192903567ffffffffffffffff81111561324557600080fd5b80360384131561325457600080fd5b82828a0152613266838a0182866130c3565b98505050938501935050908301906001016131a9565b5050505084604084015282810360608401526132988185612d6f565b98975050505050505050565b600060a082840312156132b657600080fd5b60405160a0810181811067ffffffffffffffff821117156132d9576132d9612996565b6040526132e583612ff6565b815260208301356132f581612a80565b6020820152604083013561330881612a80565b6040820152606083013561331b81612a80565b60608201526080928301359281019290925250919050565b601f82111561089257600081815260208120601f850160051c8101602086101561335a5750805b601f850160051c820191505b8181101561337957828155600101613366565b505050505050565b67ffffffffffffffff83111561339957613399612996565b6133ad836133a78354613089565b83613333565b6000601f8411600181146133e157600085156133c95750838201355b600019600387901b1c1916600186901b178355610a10565b600083815260209020601f19861690835b8281101561341257868501358255602094850194600190920191016133f2565b508682101561342f5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b602081526000610a5a6020830184866130c3565b60006001600160a01b038087168352808616602084015250836040830152608060608301526134876080830184612c04565b9695505050505050565b6000602082840312156134a357600080fd5b8151801515811461094057600080fd5b6000602082840312156134c557600080fd5b5051919050565b6000825161311e818460208701612be056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b55c80c2cc7b924d22e237a58f76c79f8d57a922fcd58b51d82917ef3aef5d9c64736f6c63430008110033
Deployed Bytecode
0x6080604052600436106101d15760003560e01c8063829331a1116100f7578063d96054c411610095578063e978afe511610064578063e978afe5146106b2578063eafb8b06146106d2578063ee57e36f146106f2578063fdef91061461071257610210565b8063d96054c41461060a578063da7422281461062a578063e2e355631461064a578063e306bee71461067e57610210565b8063c71bf324116100d1578063c71bf3241461057d578063c9dbc2a4146105ab578063ce1b815f146105cb578063d68bad2c146105ea57610210565b8063829331a114610516578063bfe07da61461054a578063c4a501451461055d57610210565b80632675fdd01161016f5780633e2ab0d91161013e5780633e2ab0d9146104ac5780634f1ef286146104cc57806352d1902d146104df5780637034731b146104f457610210565b80632675fdd0146103ff57806326875b1f1461041f5780633659cfe614610453578063388da9341461047357610210565b80631080f99b116101ab5780631080f99b146103505780631626ba7e1461037257806322844d04146103ab57806324b4d73f146103cb57610210565b806301ffc9a7146102a55780630729d054146102da57806309e56b141461031c57610210565b3661021057604080513381523460208201527f62c2c8e34665db7c56b2cabd7f5fb9702ccd352ffa8150147e450797e9f8e8f3910160405180910390a1005b34801561021c57600080fd5b50600036606060006102706000356001600160e01b03191685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061073292505050565b604080516001600160e01b03198316602082015291925001604051602081830303815290604052915050915050805190602001f35b3480156102b157600080fd5b506102c56102c03660046128ee565b610809565b60405190151581526020015b60405180910390f35b3480156102e657600080fd5b5061030e7fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d81565b6040519081526020016102d1565b34801561032857600080fd5b5061030e7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada3381565b34801561035c57600080fd5b5061037061036b366004612954565b61085e565b005b34801561037e57600080fd5b5061039261038d366004612a39565b610897565b6040516001600160e01b031990911681526020016102d1565b3480156103b757600080fd5b506103706103c6366004612a95565b610947565b3480156103d757600080fd5b5061030e7f1f53edd44352e5d15bad2b29233baa93bcd595e09457780bc7c5445bbbe751cc81565b34801561040b57600080fd5b506102c561041a366004612b1d565b610a17565b34801561042b57600080fd5b5061030e7ffaf505be9907aa6951c2ebe5b0312f4980e14f21912ed355372103cc8bd683bc81565b34801561045f57600080fd5b5061037061046e366004612b89565b610a62565b34801561047f57600080fd5b5061012d54610494906001600160a01b031681565b6040516001600160a01b0390911681526020016102d1565b3480156104b857600080fd5b506103706104c7366004612b89565b610bff565b6103706104da366004612ba6565b610c8d565b3480156104eb57600080fd5b5061030e610e1b565b34801561050057600080fd5b50610509610ee0565b6040516102d19190612c30565b34801561052257600080fd5b5061030e7f06d294bc8cbad2e393408b20dd019a772661f60b8d633e56761157cb1ec85f8c81565b610370610558366004612c43565b610f73565b34801561056957600080fd5b50610370610578366004612c9f565b6110ad565b34801561058957600080fd5b5061059d610598366004612cea565b611160565b6040516102d1929190612dc4565b3480156105b757600080fd5b506103706105c6366004612de6565b6113e9565b3480156105d757600080fd5b5061012e546001600160a01b0316610494565b3480156105f657600080fd5b50610370610605366004612e39565b61141f565b34801561061657600080fd5b50610370610625366004612e39565b61145a565b34801561063657600080fd5b50610370610645366004612b89565b61148f565b34801561065657600080fd5b5061030e7f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e77808837281565b34801561068a57600080fd5b5061030e7f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b81565b3480156106be57600080fd5b506103706106cd366004612e7a565b6114c2565b3480156106de57600080fd5b506103706106ed366004612eef565b6115c9565b3480156106fe57600080fd5b5061037061070d366004612954565b611790565b34801561071e57600080fd5b506102c561072d366004612b1d565b6117c4565b6001600160e01b0319808316600090815260fb6020526040812054909160e09190911b9081166107a7576040517f54bdcc3e0000000000000000000000000000000000000000000000000000000081526001600160e01b03198086166004830152821660248201526044015b60405180910390fd5b837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f4792cb6e46e49876374bea490ba23274bacea6b84c216a64f47abab54027589b33856040516107f8929190612f88565b60405180910390a290505b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b0319831614806108035750506001600160e01b03191660009081526033602052604090205460ff1690565b7f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b610888816117d2565b610892838361185a565b505050565b61012d546000906001600160a01b03166108b357506000610803565b61012d546040517f1626ba7e0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690631626ba7e906108ff9086908690600401612faa565b602060405180830381865afa15801561091c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109409190612fc3565b9392505050565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33610971816117d2565b60005b82811015610a1057600084848381811061099057610990612fe0565b9050606002018036038101906109a6919061300a565b90506000815160028111156109bd576109bd613073565b036109da576109d5868260200151836040015161189a565b610a07565b6001815160028111156109ef576109ef613073565b03610a0757610a0786826020015183604001516118a7565b50600101610974565b5050505050565b6000610a25858585856119ae565b80610a3e5750610a3e856001600160a01b0385856119ae565b80610a575750610a576001600160a01b038585856119ae565b90505b949350505050565b6001600160a01b037f00000000000000000000000060cd484f4a1b12a652f8ef71d2f55f6d76e64e4a163003610b005760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c0000000000000000000000000000000000000000606482015260840161079e565b7f00000000000000000000000060cd484f4a1b12a652f8ef71d2f55f6d76e64e4a6001600160a01b0316610b5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610bd75760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f78790000000000000000000000000000000000000000606482015260840161079e565b610be081611b22565b60408051600080825260208201909252610bfc91839190611b4c565b50565b7f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e778088372610c29816117d2565b61012d805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040519081527f3b25c5d3870ec0eac28822b177f18c9130233ade5b7f857c6a224a507c37fc4e906020015b60405180910390a15050565b6001600160a01b037f00000000000000000000000060cd484f4a1b12a652f8ef71d2f55f6d76e64e4a163003610d2b5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c0000000000000000000000000000000000000000606482015260840161079e565b7f00000000000000000000000060cd484f4a1b12a652f8ef71d2f55f6d76e64e4a6001600160a01b0316610d867f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614610e025760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f78790000000000000000000000000000000000000000606482015260840161079e565b610e0b82611b22565b610e1782826001611b4c565b5050565b6000306001600160a01b037f00000000000000000000000060cd484f4a1b12a652f8ef71d2f55f6d76e64e4a1614610ebb5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161079e565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b606061012f8054610ef090613089565b80601f0160208091040260200160405190810160405280929190818152602001828054610f1c90613089565b8015610f695780601f10610f3e57610100808354040283529160200191610f69565b820191906000526020600020905b815481529060010190602001808311610f4c57829003601f168201915b5050505050905090565b82600003610fad576040517f1f2a200500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03841661100257823414610ffd576040517f1abd56100000000000000000000000000000000000000000000000000000000081526004810184905234602482015260440161079e565b611058565b3415611043576040517f1abd56100000000000000000000000000000000000000000000000000000000081526000600482015234602482015260440161079e565b6110586001600160a01b038516333086611cec565b836001600160a01b0316336001600160a01b03167f2bc500cf071be2d1c1458ed6ff484cd4db4345ada8943dee7ff29e7af3558f7685858560405161109f939291906130ee565b60405180910390a350505050565b7ffaf505be9907aa6951c2ebe5b0312f4980e14f21912ed355372103cc8bd683bc6110d7816117d2565b6110e084611d74565b6001600160e01b03198316600090815260fb60205260409020805463ffffffff191660e084901c179055604080516001600160e01b0319808716825280861660208301528416918101919091527ffc72fd547553f7a663e0048e590afc9c47b56a4242e960f31cf4c62e23d308b99060600160405180910390a150505050565b606060007fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d61118e816117d2565b6101008511156111ca576040517f11c763d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8467ffffffffffffffff8111156111e3576111e3612996565b60405190808252806020026020018201604052801561121657816020015b60608152602001906001900390816112015790505b50925060005b8581101561139557600087878381811061123857611238612fe0565b905060200281019061124a9190613108565b611258906020810190612b89565b9050600080826001600160a01b03168a8a8681811061127957611279612fe0565b905060200281019061128b9190613108565b602001358b8b878181106112a1576112a1612fe0565b90506020028101906112b39190613108565b6112c1906040810190613128565b6040516112cf92919061316f565b60006040518083038185875af1925050503d806000811461130c576040519150601f19603f3d011682016040523d82523d6000602084013e611311565b606091505b50915091508161136957600160ff85161b881661135d576040517fa6a7dbbd0000000000000000000000000000000000000000000000000000000081526004810185905260240161079e565b600160ff85161b861895505b8087858151811061137c5761137c612fe0565b602002602001018190525083600101935050505061121c565b50336001600160a01b03167fd0de18eab8dc7532aab0fc4eb308477031cabf9fd312ea3b3a5fe9aa45ac8ed788888886886040516113d795949392919061317f565b60405180910390a25094509492505050565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33611413816117d2565b610a1085858585611df3565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33611449816117d2565b61145484848461189a565b50505050565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33611484816117d2565b6114548484846118a7565b7f06d294bc8cbad2e393408b20dd019a772661f60b8d633e56761157cb1ec85f8c6114b9816117d2565b610e17826120b1565b7f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada336114ec816117d2565b60005b8281101561145457600084848381811061150b5761150b612fe0565b905060a0020180360381019061152191906132a4565b905060008151600281111561153857611538613073565b036115595761155481602001518260400151836080015161189a565b6115c0565b60018151600281111561156e5761156e613073565b0361158a576115548160200151826040015183608001516118a7565b60028151600281111561159f5761159f613073565b036115c0576115c08160200151826040015183608001518460600151611df3565b506001016114ef565b600054610100900460ff16158080156115e95750600054600160ff909116105b806116035750303b158015611603575060005460ff166001145b6116755760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161079e565b6000805460ff191660011790558015611698576000805461ff0019166101001790555b6116c17f9385547e00000000000000000000000000000000000000000000000000000000611d74565b6116ea7f1626ba7e00000000000000000000000000000000000000000000000000000000611d74565b6117137f7034731b00000000000000000000000000000000000000000000000000000000611d74565b61171b612113565b6117258787612220565b61172e846120b1565b611738838361185a565b61174185612251565b8015611787576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b7f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b6117ba816117d2565b6108928383612220565b6000610a5785858585610a17565b6118153033836000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610a1792505050565b610bfc576040517f1e09743f0000000000000000000000000000000000000000000000000000000081523060048201523360248201526044810182905260640161079e565b61012f611868828483613381565b507fe9b617ecb5f63f6a9ccd8d4d5fa0d7b2ef9b17ce3f48e6b135808d6a40e677428282604051610c81929190613441565b6108928383836002611df3565b604080517f5045524d495353494f4e000000000000000000000000000000000000000000006020808301919091526bffffffffffffffffffffffff19606086811b8216602a85015287901b16603e83015260528083018590528351808403909101815260729092019092528051910120600090600081815260c960205260409020549091506001600160a01b03161561145457600081815260c96020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff1916905590516001600160a01b038681168252851691339185917f3ca48185ec3f6e47e24db18b13f1c65b1ce05da1659f9c1c4fe717dda5f67524910160405180910390a450505050565b60008060c96000611a338888886040517f5045524d495353494f4e0000000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606084811b8216602a84015285901b16603e820152605281018290526000906072016040516020818303038152906040528051906020012090509392505050565b81526020810191909152604001600020546001600160a01b0316905080611a5e576000915050610a5a565b6001196001600160a01b03821601611a7a576001915050610a5a565b6040517f2675fdd00000000000000000000000000000000000000000000000000000000081526001600160a01b03821690632675fdd090611ac5908990899089908990600401613455565b602060405180830381865afa925050508015611afe575060408051601f3d908101601f19168201909252611afb91810190613491565b60015b15611b16578015611b1457600192505050610a5a565b505b50600095945050505050565b7f1f53edd44352e5d15bad2b29233baa93bcd595e09457780bc7c5445bbbe751cc610e17816117d2565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611b7f57610892836122d7565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611bd9575060408051601f3d908101601f19168201909252611bd6918101906134b3565b60015b611c4b5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f742055555053000000000000000000000000000000000000606482015260840161079e565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114611ce05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c65555549440000000000000000000000000000000000000000000000606482015260840161079e565b506108928383836123a2565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526114549085906123c7565b6001600160e01b03198082169003611dce5760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640161079e565b6001600160e01b0319166000908152603360205260409020805460ff19166001179055565b6001600160a01b03848116148015611e1357506001600160a01b03838116145b15611e4a576040517f85f1ba9900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038481161480611e6957506001600160a01b03838116145b15611f23576000611e79836124ac565b90507f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33831480611ea65750805b15611edd576040517f24159e5b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001196001600160a01b03831601611f21576040517f92ab7d0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b604080517f5045524d495353494f4e000000000000000000000000000000000000000000006020808301919091526bffffffffffffffffffffffff19606087811b8216602a85015288901b16603e83015260528083018690528351808403909101815260729092019092528051910120600090600081815260c960205260409020549091506001600160a01b0316828161203c57600083815260c96020908152604091829020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038581169190911790915582518a8216815287821692810192909252881691339188917f0f579ad49235a8c1fd9041427e7067b1eb10926bbed380bf6fabc73e0e807644910160405180910390a4611787565b806001600160a01b0316826001600160a01b031614611787576040517f0b98789e0000000000000000000000000000000000000000000000000000000081526001600160a01b03808916600483015280881660248301526044820187905280841660648301528216608482015260a40161079e565b61012e805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040519081527fd91237492a9e30cd2faf361fc103998a382ff0ec2b1b07dc1cbebb76ae2f1ea29060200160405180910390a150565b61213c7f150b7a0200000000000000000000000000000000000000000000000000000000611d74565b6121657f4e2312e000000000000000000000000000000000000000000000000000000000611d74565b60fb6020527f5a08f87af82de422c581ce019b2e54a9c17372e9cba575ae0470ba2482d63686805463ffffffff1990811663150b7a02179091557fe1cfe341950d56d8854f782066100d5ae1d5930cdb4949b973e554a343efc6c38054821663f23a6e611790557fbc197c81000000000000000000000000000000000000000000000000000000006000527f08ba3617671847c1c169da222a5bc01cfdefcc3c4f1e5525214a474479c89123805490911663bc197c81179055565b7fbb39ebb37e60fb5d606ffdb749d2336e56b88e6c88c4bd6513b308f643186eed8282604051610c81929190613441565b600054610100900460ff166122ce5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161079e565b610bfc816125a5565b6001600160a01b0381163b6123545760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161079e565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6123ab836125d0565b6000825111806123b85750805b15610892576114548383612610565b600061241c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661271b9092919063ffffffff16565b805190915015610892578080602001905181019061243a9190613491565b6108925760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161079e565b60007fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d8214806124fb57507f1f53edd44352e5d15bad2b29233baa93bcd595e09457780bc7c5445bbbe751cc82145b8061252557507f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b82145b8061254f57507f06d294bc8cbad2e393408b20dd019a772661f60b8d633e56761157cb1ec85f8c82145b8061257957507f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e77808837282145b806108035750507ffaf505be9907aa6951c2ebe5b0312f4980e14f21912ed355372103cc8bd683bc1490565b610bfc30827f815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada3361189a565b6125d9816122d7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b61268f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e74726163740000000000000000000000000000000000000000000000000000606482015260840161079e565b600080846001600160a01b0316846040516126aa91906134cc565b600060405180830381855af49150503d80600081146126e5576040519150601f19603f3d011682016040523d82523d6000602084013e6126ea565b606091505b509150915061271282826040518060600160405280602781526020016134df6027913961272a565b95945050505050565b6060610a5a8484600085612743565b60608315612739575081610940565b6109408383612835565b6060824710156127bb5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161079e565b600080866001600160a01b031685876040516127d791906134cc565b60006040518083038185875af1925050503d8060008114612814576040519150601f19603f3d011682016040523d82523d6000602084013e612819565b606091505b509150915061282a8783838761285f565b979650505050505050565b8151156128455781518083602001fd5b8060405162461bcd60e51b815260040161079e9190612c30565b606083156128ce5782516000036128c7576001600160a01b0385163b6128c75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161079e565b5081610a5a565b610a5a8383612835565b6001600160e01b031981168114610bfc57600080fd5b60006020828403121561290057600080fd5b8135610940816128d8565b60008083601f84011261291d57600080fd5b50813567ffffffffffffffff81111561293557600080fd5b60208301915083602082850101111561294d57600080fd5b9250929050565b6000806020838503121561296757600080fd5b823567ffffffffffffffff81111561297e57600080fd5b61298a8582860161290b565b90969095509350505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126129bd57600080fd5b813567ffffffffffffffff808211156129d8576129d8612996565b604051601f8301601f19908116603f01168101908282118183101715612a0057612a00612996565b81604052838152866020858801011115612a1957600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060408385031215612a4c57600080fd5b82359150602083013567ffffffffffffffff811115612a6a57600080fd5b612a76858286016129ac565b9150509250929050565b6001600160a01b0381168114610bfc57600080fd5b600080600060408486031215612aaa57600080fd5b8335612ab581612a80565b9250602084013567ffffffffffffffff80821115612ad257600080fd5b818601915086601f830112612ae657600080fd5b813581811115612af557600080fd5b876020606083028501011115612b0a57600080fd5b6020830194508093505050509250925092565b60008060008060808587031215612b3357600080fd5b8435612b3e81612a80565b93506020850135612b4e81612a80565b925060408501359150606085013567ffffffffffffffff811115612b7157600080fd5b612b7d878288016129ac565b91505092959194509250565b600060208284031215612b9b57600080fd5b813561094081612a80565b60008060408385031215612bb957600080fd5b8235612bc481612a80565b9150602083013567ffffffffffffffff811115612a6a57600080fd5b60005b83811015612bfb578181015183820152602001612be3565b50506000910152565b60008151808452612c1c816020860160208601612be0565b601f01601f19169290920160200192915050565b6020815260006109406020830184612c04565b60008060008060608587031215612c5957600080fd5b8435612c6481612a80565b935060208501359250604085013567ffffffffffffffff811115612c8757600080fd5b612c938782880161290b565b95989497509550505050565b600080600060608486031215612cb457600080fd5b8335612cbf816128d8565b92506020840135612ccf816128d8565b91506040840135612cdf816128d8565b809150509250925092565b60008060008060608587031215612d0057600080fd5b84359350602085013567ffffffffffffffff80821115612d1f57600080fd5b818701915087601f830112612d3357600080fd5b813581811115612d4257600080fd5b8860208260051b8501011115612d5757600080fd5b95986020929092019750949560400135945092505050565b600081518084526020808501808196508360051b8101915082860160005b85811015612db7578284038952612da5848351612c04565b98850198935090840190600101612d8d565b5091979650505050505050565b604081526000612dd76040830185612d6f565b90508260208301529392505050565b60008060008060808587031215612dfc57600080fd5b8435612e0781612a80565b93506020850135612e1781612a80565b9250604085013591506060850135612e2e81612a80565b939692955090935050565b600080600060608486031215612e4e57600080fd5b8335612e5981612a80565b92506020840135612e6981612a80565b929592945050506040919091013590565b60008060208385031215612e8d57600080fd5b823567ffffffffffffffff80821115612ea557600080fd5b818501915085601f830112612eb957600080fd5b813581811115612ec857600080fd5b86602060a083028501011115612edd57600080fd5b60209290920196919550909350505050565b60008060008060008060808789031215612f0857600080fd5b863567ffffffffffffffff80821115612f2057600080fd5b612f2c8a838b0161290b565b909850965060208901359150612f4182612a80565b909450604088013590612f5382612a80565b90935060608801359080821115612f6957600080fd5b50612f7689828a0161290b565b979a9699509497509295939492505050565b6001600160a01b0383168152604060208201526000610a5a6040830184612c04565b828152604060208201526000610a5a6040830184612c04565b600060208284031215612fd557600080fd5b8151610940816128d8565b634e487b7160e01b600052603260045260246000fd5b80356003811061300557600080fd5b919050565b60006060828403121561301c57600080fd5b6040516060810181811067ffffffffffffffff8211171561303f5761303f612996565b60405261304b83612ff6565b8152602083013561305b81612a80565b60208201526040928301359281019290925250919050565b634e487b7160e01b600052602160045260246000fd5b600181811c9082168061309d57607f821691505b6020821081036130bd57634e487b7160e01b600052602260045260246000fd5b50919050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b838152604060208201526000610a576040830184866130c3565b60008235605e1983360301811261311e57600080fd5b9190910192915050565b6000808335601e1984360301811261313f57600080fd5b83018035915067ffffffffffffffff82111561315a57600080fd5b60200191503681900382131561294d57600080fd5b8183823760009101908152919050565b60006080820187835260206080818501528187835260a08501905060a08860051b86010192508860005b8981101561327c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608786030183528135605e198c36030181126131ec57600080fd5b8b01606081356131fb81612a80565b6001600160a01b03168752818601358688015260408083013536849003601e1901811261322757600080fd5b90920186810192903567ffffffffffffffff81111561324557600080fd5b80360384131561325457600080fd5b82828a0152613266838a0182866130c3565b98505050938501935050908301906001016131a9565b5050505084604084015282810360608401526132988185612d6f565b98975050505050505050565b600060a082840312156132b657600080fd5b60405160a0810181811067ffffffffffffffff821117156132d9576132d9612996565b6040526132e583612ff6565b815260208301356132f581612a80565b6020820152604083013561330881612a80565b6040820152606083013561331b81612a80565b60608201526080928301359281019290925250919050565b601f82111561089257600081815260208120601f850160051c8101602086101561335a5750805b601f850160051c820191505b8181101561337957828155600101613366565b505050505050565b67ffffffffffffffff83111561339957613399612996565b6133ad836133a78354613089565b83613333565b6000601f8411600181146133e157600085156133c95750838201355b600019600387901b1c1916600186901b178355610a10565b600083815260209020601f19861690835b8281101561341257868501358255602094850194600190920191016133f2565b508682101561342f5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b602081526000610a5a6020830184866130c3565b60006001600160a01b038087168352808616602084015250836040830152608060608301526134876080830184612c04565b9695505050505050565b6000602082840312156134a357600080fd5b8151801515811461094057600080fd5b6000602082840312156134c557600080fd5b5051919050565b6000825161311e818460208701612be056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b55c80c2cc7b924d22e237a58f76c79f8d57a922fcd58b51d82917ef3aef5d9c64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.