Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 16456482 | 671 days ago | IN | 0 ETH | 0.05398669 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Vip3SBT
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./InitBaseConfig.sol"; import "./interfaces/ISBT721.sol"; import "./interfaces/IERC721Metadata.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; contract Vip3SBT is InitBaseConfig, IERC721Metadata { using Strings for uint256; using ECDSA for bytes32; using ECDSA for bytes; using Counters for Counters.Counter; using EnumerableMap for EnumerableMap.AddressToUintMap; using EnumerableMap for EnumerableMap.UintToAddressMap; // Token name string public override name; // Token symbol string public override symbol; // Token uri string public baseTokenURI; // Mapping from token ID to owner address EnumerableMap.UintToAddressMap private _ownerMap; EnumerableMap.AddressToUintMap private _tokenMap; // Token Id Counter Counters.Counter public _tokenIdCounter; function initialize( string memory _name, string memory _symbol, string memory _baseTokenURI ) public initializer { name = _name; symbol = _symbol; baseTokenURI = _baseTokenURI; __AccessControl_init(msg.sender, msg.sender); } /** * @dev Update _baseTokenURI */ function setBaseTokenURI(string calldata uri) public whenNotPaused onlyRole(ROLE_ADMIN) { baseTokenURI = uri; } /** * @dev Get _baseTokenURI */ function _baseURI() internal view returns (string memory) { return baseTokenURI; } /** * @dev Update symbol */ function setSymbol(string calldata _symbol) public whenNotPaused onlyRole(ROLE_ADMIN) { symbol = _symbol; } /** * @dev Update name */ function setName(string calldata _name) public whenNotPaused onlyRole(ROLE_ADMIN) { name = _name; } /** * @dev mint SBT by admin. */ function attest(address _to) external override whenNotPaused onlyRole(ROLE_ADMIN) returns (uint256) { require(_to != address(0), "Address is empty"); require(!_tokenMap.contains(_to), "SBT already exists"); _tokenIdCounter.increment(); emit Attest(_to, _tokenIdCounter.current()); return _mint(_to, _tokenIdCounter.current()); } /** * @dev batch mint SBT by admin. */ function batchAttest(address[] calldata addrs) external whenNotPaused onlyRole(ROLE_ADMIN) { uint256 addrLength = addrs.length; require(addrLength <= 100, "The max length of addresses is 100"); for (uint8 i = 0; i < addrLength; i++) { address to = addrs[i]; if (to == address(0) || _tokenMap.contains(to)) { continue; } _tokenIdCounter.increment(); emit Attest(to, _tokenIdCounter.current()); _mint(to, _tokenIdCounter.current()); } } /** * @dev revoke SBT by admin. */ function revoke(address from) external override whenNotPaused onlyRole(ROLE_ADMIN) { require(from != address(0), "Address is empty"); require(_tokenMap.contains(from), "The account does not have any SBT"); _revoke(from); } /** * @dev batch revoke SBT by admin. */ function batchRevoke(address[] calldata addrs) external whenNotPaused onlyRole(ROLE_ADMIN) { uint256 addrLength = addrs.length; require(addrLength <= 100, "The max length of addresses is 100"); for (uint8 i = 0; i < addrLength; i++) { address from = addrs[i]; if (from == address(0) || !_tokenMap.contains(from)) { continue; } _revoke(from); } } /** * @dev Revoke SBT which address is `from`. * */ function _revoke(address from) internal { uint256 tokenId = _tokenMap.get(from); _tokenMap.remove(from); _ownerMap.remove(tokenId); emit Revoke(from, tokenId); emit Transfer(from, address(0), tokenId); } function mint( address _to, uint256 deadline, bytes memory signature ) public override whenNotPaused returns (uint256) { // sign verify require(verifyMint(_to, deadline, signature)); _tokenIdCounter.increment(); return _mint(_to, _tokenIdCounter.current()); } /** * @dev Mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Attest} event. * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal returns (uint256) { require(to != address(0), "Address is empty"); require(!_tokenMap.contains(to), "SBT already exists"); _tokenMap.set(to, tokenId); _ownerMap.set(tokenId, to); emit Transfer(address(0), to, tokenId); return tokenId; } /** * @dev Burns `tokenId`. * * Requirements: * * - The caller must own `tokenId` and has the correct signature. */ function burn( uint256 _tokenId, uint256 deadline, bytes memory signature ) public override whenNotPaused { // sign verify require(verifyBurn(_tokenId, deadline, signature), "Sign verify error"); address sender = _msgSender(); require( _tokenMap.contains(sender), "The account does not have any SBT" ); require( _tokenId == _tokenMap.get(sender), "TokenId verify error" ); _tokenMap.remove(sender); _ownerMap.remove(_tokenId); emit Burn(sender, _tokenId); emit Transfer(sender, address(0), _tokenId); } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require( _ownerMap.contains(tokenId), "ERC721Metadata: URI query for nonexistent token" ); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) external view override returns (uint256) { (bool success, ) = _tokenMap.tryGet(owner); return success ? 1 : 0; } /** * @dev Returns a token ID owned by `from` */ function tokenIdOf(address from) external view override returns (uint256) { return _tokenMap.get(from, "The wallet has not hold any SBT"); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) external view override returns (address) { return _ownerMap.get(tokenId, "Invalid tokenId"); } /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view override returns (uint256) { return _tokenMap.length(); } /** * @dev Verify mint signature. */ function verifyMint( address _to, uint256 deadline, bytes memory signature ) internal view returns (bool) { require(block.timestamp < deadline, "The sign deadline error"); bytes32 messageHash = keccak256( abi.encodePacked(PROVENANCE, _to, deadline, MINT_METHOD) ); return hasRole(ROLE_ADMIN, messageHash.recover(signature)); } /** * @dev Verify burn signature. */ function verifyBurn( uint256 _tokenId, uint256 deadline, bytes memory signature ) internal view returns (bool) { require(block.timestamp < deadline, "The sign deadline error"); bytes32 messageHash = keccak256( abi.encodePacked(PROVENANCE, _tokenId, deadline, BURN_METHOD) ); return hasRole(ROLE_ADMIN, messageHash.recover(signature)); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(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 (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; import "../utils/ContextUpgradeable.sol"; import "../utils/StringsUpgradeable.sol"; import "../utils/introspection/ERC165Upgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal onlyInitializing { } function __AccessControl_init_unchained() internal onlyInitializing { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(account), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } /** * @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 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (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 Internal function that returns the initialized version. Returns `_initialized` */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Internal function that returns the initialized version. Returns `_initializing` */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @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 (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableMap.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableMap.js. pragma solidity ^0.8.0; import "./EnumerableSet.sol"; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * The following map types are supported: * * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0 * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableMap. * ==== */ library EnumerableMap { using EnumerableSet for EnumerableSet.Bytes32Set; // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct Bytes32ToBytes32Map { // Storage of keys EnumerableSet.Bytes32Set _keys; mapping(bytes32 => bytes32) _values; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value ) internal returns (bool) { map._values[key] = value; return map._keys.add(key); } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { delete map._values[key]; return map._keys.remove(key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { return map._keys.contains(key); } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { return map._keys.length(); } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { bytes32 key = map._keys.at(index); return (key, map._values[key]); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { bytes32 value = map._values[key]; if (value == bytes32(0)) { return (contains(map, key), bytes32(0)); } else { return (true, value); } } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key"); return value; } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( Bytes32ToBytes32Map storage map, bytes32 key, string memory errorMessage ) internal view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || contains(map, key), errorMessage); return value; } // UintToUintMap struct UintToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( UintToUintMap storage map, uint256 key, uint256 value ) internal returns (bool) { return set(map._inner, bytes32(key), bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { return remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { return contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) { (bytes32 key, bytes32 value) = at(map._inner, index); return (uint256(key), uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) { (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { return uint256(get(map._inner, bytes32(key))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( UintToUintMap storage map, uint256 key, string memory errorMessage ) internal view returns (uint256) { return uint256(get(map._inner, bytes32(key), errorMessage)); } // UintToAddressMap struct UintToAddressMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( UintToAddressMap storage map, uint256 key, address value ) internal returns (bool) { return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( UintToAddressMap storage map, uint256 key, string memory errorMessage ) internal view returns (address) { return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage)))); } // AddressToUintMap struct AddressToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( AddressToUintMap storage map, address key, uint256 value ) internal returns (bool) { return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToUintMap storage map, address key) internal returns (bool) { return remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToUintMap storage map, address key) internal view returns (bool) { return contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { (bytes32 key, bytes32 value) = at(map._inner, index); return (address(uint160(uint256(key))), uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToUintMap storage map, address key) internal view returns (uint256) { return uint256(get(map._inner, bytes32(uint256(uint160(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( AddressToUintMap storage map, address key, string memory errorMessage ) internal view returns (uint256) { return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage)); } // Bytes32ToUintMap struct Bytes32ToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( Bytes32ToUintMap storage map, bytes32 key, uint256 value ) internal returns (bool) { return set(map._inner, key, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { return remove(map._inner, key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { return contains(map._inner, key); } /** * @dev Returns the number of elements in the map. O(1). */ function length(Bytes32ToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) { (bytes32 key, bytes32 value) = at(map._inner, index); return (key, uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) { (bool success, bytes32 value) = tryGet(map._inner, key); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { return uint256(get(map._inner, key)); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( Bytes32ToUintMap storage map, bytes32 key, string memory errorMessage ) internal view returns (uint256) { return uint256(get(map._inner, key, errorMessage)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; contract InitBaseConfig is Initializable, AccessControlUpgradeable, PausableUpgradeable { bytes32 public constant ROLE_SUPER_ADMIN = keccak256("SUPER_ADMIN_ROLE"); bytes32 public constant ROLE_ADMIN = keccak256("ADMIN_ROLE"); string public constant PROVENANCE = "Vip3-Ethereum"; // Method name string public constant MINT_METHOD = "mint"; string public constant BURN_METHOD = "burn"; function __AccessControl_init(address superAdmin, address admin) internal onlyInitializing { _setupRole(ROLE_SUPER_ADMIN, superAdmin); _setupRole(ROLE_ADMIN, admin); _setRoleAdmin(ROLE_SUPER_ADMIN, ROLE_SUPER_ADMIN); _setRoleAdmin(ROLE_ADMIN, ROLE_SUPER_ADMIN); } function pause() public onlyRole(ROLE_SUPER_ADMIN) { _pause(); } function unpause() public onlyRole(ROLE_SUPER_ADMIN) { _unpause(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "./ISBT721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is ISBT721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ISBT721 { /** * @dev This emits when a new token is created and bound to an account by * any mechanism. * Note: For a reliable `to` parameter, retrieve the transaction's * authenticated `to` field. */ event Attest(address indexed to, uint256 indexed tokenId); /** * @dev This emits when an existing SBT is revoked from an account and * destroyed by any mechanism. * Note: For a reliable `from` parameter, retrieve the transaction's * authenticated `from` field. */ event Revoke(address indexed from, uint256 indexed tokenId); /** * @dev This emits when an existing SBT is burned by an account */ event Burn(address indexed from, uint256 indexed tokenId); /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); /** * @dev Mints SBT * * Requirements: * * - `to` must be valid. * - `to` must not exist. * * Emits a {Attest} event. * Emits a {Transfer} event. * @return The tokenId of the minted SBT */ function attest(address to) external returns (uint256); function mint( address _to, uint256 deadline, bytes memory signature ) external returns (uint256); /** * @dev Revokes SBT * * Requirements: * * - `from` must exist. * * Emits a {Revoke} event. * Emits a {Transfer} event. */ function revoke(address from) external; /** * @notice At any time, an SBT receiver must be able to * disassociate themselves from an SBT publicly through calling this * function. * * Emits a {Burn} event. * Emits a {Transfer} event. */ function burn( uint256 _tokenId, uint256 deadline, bytes memory signature ) external; /** * @notice Count all SBTs assigned to an owner * @dev SBTs assigned to the zero address is considered invalid, and this * function throws for queries about the zero address. * @param owner An address for whom to query the balance * @return The number of SBTs owned by `owner`, possibly zero */ function balanceOf(address owner) external view returns (uint256); /** * @param from The address of the SBT owner * @return The tokenId of the owner's SBT, and throw an error if there is no SBT belongs to the given address */ function tokenIdOf(address from) external view returns (uint256); /** * @notice Find the address bound to a SBT * @dev SBTs assigned to zero address are considered invalid, and queries * about them do throw. * @param tokenId The identifier for an SBT * @return The address of the owner bound to the SBT */ function ownerOf(uint256 tokenId) external view returns (address); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Attest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Revoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"BURN_METHOD","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_METHOD","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROVENANCE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_SUPER_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tokenIdCounter","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"attest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addrs","type":"address[]"}],"name":"batchAttest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addrs","type":"address[]"}],"name":"batchRevoke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_baseTokenURI","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"revoke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_symbol","type":"string"}],"name":"setSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"}],"name":"tokenIdOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50612858806100206000396000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c806380a5a3711161011a578063a6487c53116100ad578063d391014b1161007c578063d391014b14610464578063d547741f14610479578063d547cfb71461048c578063e82cd66014610494578063eb31403f146104b757600080fd5b8063a6487c5314610418578063b84c82461461042b578063c47f00271461043e578063c87b56dd1461045157600080fd5b806394d008ef116100e957806394d008ef146103d257806395d89b41146103e5578063a217fddf146103ed578063a5b4de64146103f557600080fd5b806380a5a3711461039a5780638456cb59146103ad57806384c4bd4b146103b557806391d14854146103bf57600080fd5b80633f4ba83a1161019d5780636c60144a1161016c5780636c60144a146103395780636cc8bb491461034c57806370a082311461036157806374a8f10314610374578063773c02d41461038757600080fd5b80633f4ba83a146102cf5780635c975abb146102d75780636352211e146102e25780636373a6b11461030d57600080fd5b8063248a9ca3116101d9578063248a9ca3146102735780632f2ff15d1461029657806330176e13146102a957806336568abe146102bc57600080fd5b8063011002df1461020b57806301ffc9a71461022057806306fdde031461024857806318160ddd1461025d575b600080fd5b61021e610219366004611fac565b6104ca565b005b61023361022e366004612021565b61059e565b60405190151581526020015b60405180910390f35b6102506105e4565b60405161023f919061206f565b610265610672565b60405190815260200161023f565b6102656102813660046120a2565b60009081526065602052604090206001015490565b61021e6102a43660046120d7565b610683565b61021e6102b7366004612103565b6106ad565b61021e6102ca3660046120d7565b6106e0565b61021e61075e565b60975460ff16610233565b6102f56102f03660046120a2565b610781565b6040516001600160a01b03909116815260200161023f565b6102506040518060400160405280600d81526020016c566970332d457468657265756d60981b81525081565b61021e610347366004611fac565b6107c0565b6102656000805160206127e383398151915281565b61026561036f366004612163565b6108d1565b61021e610382366004612163565b6108fb565b610265610395366004612163565b610971565b61021e6103a8366004612221565b6109be565b61021e610b15565b60d2546102659081565b6102336103cd3660046120d7565b610b35565b6102656103e0366004612271565b610b60565b610250610ba1565b610265600081565b61025060405180604001604052806004815260200163313ab93760e11b81525081565b61021e6104263660046122b2565b610bae565b61021e610439366004612103565b610cea565b61021e61044c366004612103565b610d17565b61025061045f3660046120a2565b610d44565b61026560008051602061280383398151915281565b61021e6104873660046120d7565b610e11565b610250610e36565b610250604051806040016040528060048152602001631b5a5b9d60e21b81525081565b6102656104c5366004612163565b610e43565b6104d2610f30565b6000805160206128038339815191526104ea81610f78565b8160648111156105155760405162461bcd60e51b815260040161050c90612330565b60405180910390fd5b60005b818160ff16101561059757600085858360ff1681811061053a5761053a612372565b905060200201602081019061054f9190612163565b90506001600160a01b038116158061056f575061056d60cf82610f82565b155b1561057a5750610585565b61058381610f97565b505b8061058f8161239e565b915050610518565b5050505050565b60006001600160e01b031982166380ac58cd60e01b14806105cf57506001600160e01b03198216635b5e139f60e01b145b806105de57506105de82611030565b92915050565b60c980546105f1906123bd565b80601f016020809104026020016040519081016040528092919081815260200182805461061d906123bd565b801561066a5780601f1061063f5761010080835404028352916020019161066a565b820191906000526020600020905b81548152906001019060200180831161064d57829003601f168201915b505050505081565b600061067e60cf611065565b905090565b60008281526065602052604090206001015461069e81610f78565b6106a88383611070565b505050565b6106b5610f30565b6000805160206128038339815191526106cd81610f78565b60cb6106da83858361243f565b50505050565b6001600160a01b03811633146107505760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161050c565b61075a82826110f6565b5050565b6000805160206127e383398151915261077681610f78565b61077e61115d565b50565b60006105de826040518060400160405280600f81526020016e125b9d985b1a59081d1bdad95b9259608a1b81525060cc6111af9092919063ffffffff16565b6107c8610f30565b6000805160206128038339815191526107e081610f78565b8160648111156108025760405162461bcd60e51b815260040161050c90612330565b60005b818160ff16101561059757600085858360ff1681811061082757610827612372565b905060200201602081019061083c9190612163565b90506001600160a01b038116158061085a575061085a60cf82610f82565b1561086557506108bf565b61087360d280546001019055565b60d2546040516001600160a01b038316907fe9274a84b19e9428826de6bae8c48329354f8f0e73f771b97cae2d9dccd45a2790600090a36108bc816108b760d25490565b6111bc565b50505b806108c98161239e565b915050610805565b6000806108df60cf84611289565b509050806108ee5760006108f1565b60015b60ff169392505050565b610903610f30565b60008051602061280383398151915261091b81610f78565b6001600160a01b0382166109415760405162461bcd60e51b815260040161050c906124ff565b61094c60cf83610f82565b6109685760405162461bcd60e51b815260040161050c90612529565b61075a82610f97565b60006105de826040518060400160405280601f81526020017f5468652077616c6c657420686173206e6f7420686f6c6420616e79205342540081525060cf6112b09092919063ffffffff16565b6109c6610f30565b6109d18383836112c6565b610a115760405162461bcd60e51b815260206004820152601160248201527029b4b3b7103b32b934b33c9032b93937b960791b604482015260640161050c565b33610a1d60cf82610f82565b610a395760405162461bcd60e51b815260040161050c90612529565b610a4460cf826113aa565b8414610a895760405162461bcd60e51b81526020600482015260146024820152732a37b5b2b724b2103b32b934b33c9032b93937b960611b604482015260640161050c565b610a9460cf826113bf565b50610aa060cc856113d4565b5060405184906001600160a01b038316907fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca590600090a360405184906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a450505050565b6000805160206127e3833981519152610b2d81610f78565b61077e6113e0565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6000610b6a610f30565b610b7584848461141d565b610b7e57600080fd5b610b8c60d280546001019055565b610b99846108b760d25490565b949350505050565b60ca80546105f1906123bd565b600054610100900460ff1615808015610bce5750600054600160ff909116105b80610be85750303b158015610be8575060005460ff166001145b610c4b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161050c565b6000805460ff191660011790558015610c6e576000805461ff0019166101001790555b60c9610c7a858261256a565b5060ca610c87848261256a565b5060cb610c94838261256a565b50610c9f33336114c2565b80156106da576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b610cf2610f30565b600080516020612803833981519152610d0a81610f78565b60ca6106da83858361243f565b610d1f610f30565b600080516020612803833981519152610d3781610f78565b60c96106da83858361243f565b6060610d5160cc8361159b565b610db55760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161050c565b6000610dbf6115a7565b90506000815111610ddf5760405180602001604052806000815250610e0a565b80610de984611639565b604051602001610dfa92919061262a565b6040516020818303038152906040525b9392505050565b600082815260656020526040902060010154610e2c81610f78565b6106a883836110f6565b60cb80546105f1906123bd565b6000610e4d610f30565b600080516020612803833981519152610e6581610f78565b6001600160a01b038316610e8b5760405162461bcd60e51b815260040161050c906124ff565b610e9660cf84610f82565b15610ed85760405162461bcd60e51b815260206004820152601260248201527153425420616c72656164792065786973747360701b604482015260640161050c565b610ee660d280546001019055565b60d2546040516001600160a01b038516907fe9274a84b19e9428826de6bae8c48329354f8f0e73f771b97cae2d9dccd45a2790600090a3610e0a836108b760d25490565b50919050565b60975460ff1615610f765760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161050c565b565b61077e81336116cc565b6000610e0a836001600160a01b038416611725565b6000610fa460cf836113aa565b9050610fb160cf836113bf565b50610fbd60cc826113d4565b5060405181906001600160a01b038416907fec9ab91322523c899ede7830ec9bfc992b5981cdcc27b91162fb23de5791117b90600090a360405181906000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006001600160e01b03198216637965db0b60e01b14806105de57506301ffc9a760e01b6001600160e01b03198316146105de565b60006105de82611731565b61107a8282610b35565b61075a5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556110b23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6111008282610b35565b1561075a5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b61116561173c565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000610b99848484611785565b60006001600160a01b0383166111e45760405162461bcd60e51b815260040161050c906124ff565b6111ef60cf84610f82565b156112315760405162461bcd60e51b815260206004820152601260248201527153425420616c72656164792065786973747360701b604482015260640161050c565b61123d60cf84846117d1565b5061124a60cc83856117e7565b5060405182906001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450919050565b60008080806112a1866001600160a01b0387166117fd565b909450925050505b9250929050565b6000610b99846001600160a01b03851684611785565b60008242106113115760405162461bcd60e51b81526020600482015260176024820152762a34329039b4b3b7103232b0b23634b7329032b93937b960491b604482015260640161050c565b60006040518060400160405280600d81526020016c566970332d457468657265756d60981b815250858560405180604001604052806004815260200163313ab93760e11b81525060405160200161136b9493929190612659565b60408051601f19818403018152919052805160209091012090506113a16000805160206128038339815191526103cd8386611837565b95945050505050565b6000610e0a836001600160a01b03841661185b565b6000610e0a836001600160a01b0384166118cb565b6000610e0a83836118cb565b6113e8610f30565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586111923390565b60008242106114685760405162461bcd60e51b81526020600482015260176024820152762a34329039b4b3b7103232b0b23634b7329032b93937b960491b604482015260640161050c565b60006040518060400160405280600d81526020016c566970332d457468657265756d60981b8152508585604051806040016040528060048152602001631b5a5b9d60e21b81525060405160200161136b949392919061269a565b600054610100900460ff1661152d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161050c565b6115456000805160206127e3833981519152836118e8565b61155d600080516020612803833981519152826118e8565b6115756000805160206127e3833981519152806118f2565b61075a6000805160206128038339815191526000805160206127e38339815191526118f2565b6000610e0a8383611725565b606060cb80546115b6906123bd565b80601f01602080910402602001604051908101604052809291908181526020018280546115e2906123bd565b801561162f5780601f106116045761010080835404028352916020019161162f565b820191906000526020600020905b81548152906001019060200180831161161257829003601f168201915b5050505050905090565b606060006116468361193d565b600101905060008167ffffffffffffffff8111156116665761166661217e565b6040519080825280601f01601f191660200182016040528015611690576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461169a57509392505050565b6116d68282610b35565b61075a576116e381611a15565b6116ee836020611a27565b6040516020016116ff9291906126ed565b60408051601f198184030181529082905262461bcd60e51b825261050c9160040161206f565b6000610e0a8383611bc3565b60006105de82611bdb565b60975460ff16610f765760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161050c565b6000828152600284016020526040812054801515806117a957506117a98585611725565b83906117c85760405162461bcd60e51b815260040161050c919061206f565b50949350505050565b6000610b99846001600160a01b03851684611be5565b6000610b9984846001600160a01b038516611be5565b600081815260028301602052604081205481908061182c5761181f8585611725565b9250600091506112a99050565b6001925090506112a9565b60008060006118468585611c02565b9150915061185381611c44565b509392505050565b60008181526002830160205260408120548015158061187f575061187f8484611725565b610e0a5760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640161050c565b60008181526002830160205260408120819055610e0a8383611d8e565b61075a8282611070565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061197c5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106119a8576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106119c657662386f26fc10000830492506010015b6305f5e10083106119de576305f5e100830492506008015b61271083106119f257612710830492506004015b60648310611a04576064830492506002015b600a83106105de5760010192915050565b60606105de6001600160a01b03831660145b60606000611a36836002612762565b611a41906002612779565b67ffffffffffffffff811115611a5957611a5961217e565b6040519080825280601f01601f191660200182016040528015611a83576020820181803683370190505b509050600360fc1b81600081518110611a9e57611a9e612372565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611acd57611acd612372565b60200101906001600160f81b031916908160001a9053506000611af1846002612762565b611afc906001612779565b90505b6001811115611b74576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611b3057611b30612372565b1a60f81b828281518110611b4657611b46612372565b60200101906001600160f81b031916908160001a90535060049490941c93611b6d8161278c565b9050611aff565b508315610e0a5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161050c565b60008181526001830160205260408120541515610e0a565b60006105de825490565b60008281526002840160205260408120829055610b998484611d9a565b6000808251604103611c385760208301516040840151606085015160001a611c2c87828585611da6565b945094505050506112a9565b506000905060026112a9565b6000816004811115611c5857611c586127a3565b03611c605750565b6001816004811115611c7457611c746127a3565b03611cc15760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161050c565b6002816004811115611cd557611cd56127a3565b03611d225760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161050c565b6003816004811115611d3657611d366127a3565b0361077e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161050c565b6000610e0a8383611e6a565b6000610e0a8383611f5d565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611ddd5750600090506003611e61565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e31573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611e5a57600060019250925050611e61565b9150600090505b94509492505050565b60008181526001830160205260408120548015611f53576000611e8e6001836127b9565b8554909150600090611ea2906001906127b9565b9050818114611f07576000866000018281548110611ec257611ec2612372565b9060005260206000200154905080876000018481548110611ee557611ee5612372565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611f1857611f186127cc565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105de565b60009150506105de565b6000818152600183016020526040812054611fa4575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105de565b5060006105de565b60008060208385031215611fbf57600080fd5b823567ffffffffffffffff80821115611fd757600080fd5b818501915085601f830112611feb57600080fd5b813581811115611ffa57600080fd5b8660208260051b850101111561200f57600080fd5b60209290920196919550909350505050565b60006020828403121561203357600080fd5b81356001600160e01b031981168114610e0a57600080fd5b60005b8381101561206657818101518382015260200161204e565b50506000910152565b602081526000825180602084015261208e81604085016020870161204b565b601f01601f19169190910160400192915050565b6000602082840312156120b457600080fd5b5035919050565b80356001600160a01b03811681146120d257600080fd5b919050565b600080604083850312156120ea57600080fd5b823591506120fa602084016120bb565b90509250929050565b6000806020838503121561211657600080fd5b823567ffffffffffffffff8082111561212e57600080fd5b818501915085601f83011261214257600080fd5b81358181111561215157600080fd5b86602082850101111561200f57600080fd5b60006020828403121561217557600080fd5b610e0a826120bb565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126121a557600080fd5b813567ffffffffffffffff808211156121c0576121c061217e565b604051601f8301601f19908116603f011681019082821181831017156121e8576121e861217e565b8160405283815286602085880101111561220157600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561223657600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561225b57600080fd5b61226786828701612194565b9150509250925092565b60008060006060848603121561228657600080fd5b61228f846120bb565b925060208401359150604084013567ffffffffffffffff81111561225b57600080fd5b6000806000606084860312156122c757600080fd5b833567ffffffffffffffff808211156122df57600080fd5b6122eb87838801612194565b9450602086013591508082111561230157600080fd5b61230d87838801612194565b9350604086013591508082111561232357600080fd5b5061226786828701612194565b60208082526022908201527f546865206d6178206c656e677468206f66206164647265737365732069732031604082015261030360f41b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff81036123b4576123b4612388565b60010192915050565b600181811c908216806123d157607f821691505b602082108103610f2a57634e487b7160e01b600052602260045260246000fd5b601f8211156106a857600081815260208120601f850160051c810160208610156124185750805b601f850160051c820191505b8181101561243757828155600101612424565b505050505050565b67ffffffffffffffff8311156124575761245761217e565b61246b8361246583546123bd565b836123f1565b6000601f84116001811461249f57600085156124875750838201355b600019600387901b1c1916600186901b178355610597565b600083815260209020601f19861690835b828110156124d057868501358255602094850194600190920191016124b0565b50868210156124ed5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60208082526010908201526f4164647265737320697320656d70747960801b604082015260600190565b60208082526021908201527f546865206163636f756e7420646f6573206e6f74206861766520616e792053426040820152601560fa1b606082015260800190565b815167ffffffffffffffff8111156125845761258461217e565b6125988161259284546123bd565b846123f1565b602080601f8311600181146125cd57600084156125b55750858301515b600019600386901b1c1916600185901b178555612437565b600085815260208120601f198616915b828110156125fc578886015182559484019460019091019084016125dd565b508582101561261a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000835161263c81846020880161204b565b83519083019061265081836020880161204b565b01949350505050565b6000855161266b818460208a0161204b565b8083019050858152846020820152835161268c81604084016020880161204b565b016040019695505050505050565b600085516126ac818460208a0161204b565b80830190506bffffffffffffffffffffffff198660601b16815284601482015283516126df81603484016020880161204b565b016034019695505050505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161272581601785016020880161204b565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161275681602884016020880161204b565b01602801949350505050565b80820281158282048414176105de576105de612388565b808201808211156105de576105de612388565b60008161279b5761279b612388565b506000190190565b634e487b7160e01b600052602160045260246000fd5b818103818111156105de576105de612388565b634e487b7160e01b600052603160045260246000fdfe7613a25ecc738585a232ad50a301178f12b3ba8887d13e138b523c4269c47689a49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775a2646970667358221220ccb105cd4672e1de0db8db459251bfdcc43df83deae14de4ff0fb7375ed3fb1664736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102065760003560e01c806380a5a3711161011a578063a6487c53116100ad578063d391014b1161007c578063d391014b14610464578063d547741f14610479578063d547cfb71461048c578063e82cd66014610494578063eb31403f146104b757600080fd5b8063a6487c5314610418578063b84c82461461042b578063c47f00271461043e578063c87b56dd1461045157600080fd5b806394d008ef116100e957806394d008ef146103d257806395d89b41146103e5578063a217fddf146103ed578063a5b4de64146103f557600080fd5b806380a5a3711461039a5780638456cb59146103ad57806384c4bd4b146103b557806391d14854146103bf57600080fd5b80633f4ba83a1161019d5780636c60144a1161016c5780636c60144a146103395780636cc8bb491461034c57806370a082311461036157806374a8f10314610374578063773c02d41461038757600080fd5b80633f4ba83a146102cf5780635c975abb146102d75780636352211e146102e25780636373a6b11461030d57600080fd5b8063248a9ca3116101d9578063248a9ca3146102735780632f2ff15d1461029657806330176e13146102a957806336568abe146102bc57600080fd5b8063011002df1461020b57806301ffc9a71461022057806306fdde031461024857806318160ddd1461025d575b600080fd5b61021e610219366004611fac565b6104ca565b005b61023361022e366004612021565b61059e565b60405190151581526020015b60405180910390f35b6102506105e4565b60405161023f919061206f565b610265610672565b60405190815260200161023f565b6102656102813660046120a2565b60009081526065602052604090206001015490565b61021e6102a43660046120d7565b610683565b61021e6102b7366004612103565b6106ad565b61021e6102ca3660046120d7565b6106e0565b61021e61075e565b60975460ff16610233565b6102f56102f03660046120a2565b610781565b6040516001600160a01b03909116815260200161023f565b6102506040518060400160405280600d81526020016c566970332d457468657265756d60981b81525081565b61021e610347366004611fac565b6107c0565b6102656000805160206127e383398151915281565b61026561036f366004612163565b6108d1565b61021e610382366004612163565b6108fb565b610265610395366004612163565b610971565b61021e6103a8366004612221565b6109be565b61021e610b15565b60d2546102659081565b6102336103cd3660046120d7565b610b35565b6102656103e0366004612271565b610b60565b610250610ba1565b610265600081565b61025060405180604001604052806004815260200163313ab93760e11b81525081565b61021e6104263660046122b2565b610bae565b61021e610439366004612103565b610cea565b61021e61044c366004612103565b610d17565b61025061045f3660046120a2565b610d44565b61026560008051602061280383398151915281565b61021e6104873660046120d7565b610e11565b610250610e36565b610250604051806040016040528060048152602001631b5a5b9d60e21b81525081565b6102656104c5366004612163565b610e43565b6104d2610f30565b6000805160206128038339815191526104ea81610f78565b8160648111156105155760405162461bcd60e51b815260040161050c90612330565b60405180910390fd5b60005b818160ff16101561059757600085858360ff1681811061053a5761053a612372565b905060200201602081019061054f9190612163565b90506001600160a01b038116158061056f575061056d60cf82610f82565b155b1561057a5750610585565b61058381610f97565b505b8061058f8161239e565b915050610518565b5050505050565b60006001600160e01b031982166380ac58cd60e01b14806105cf57506001600160e01b03198216635b5e139f60e01b145b806105de57506105de82611030565b92915050565b60c980546105f1906123bd565b80601f016020809104026020016040519081016040528092919081815260200182805461061d906123bd565b801561066a5780601f1061063f5761010080835404028352916020019161066a565b820191906000526020600020905b81548152906001019060200180831161064d57829003601f168201915b505050505081565b600061067e60cf611065565b905090565b60008281526065602052604090206001015461069e81610f78565b6106a88383611070565b505050565b6106b5610f30565b6000805160206128038339815191526106cd81610f78565b60cb6106da83858361243f565b50505050565b6001600160a01b03811633146107505760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161050c565b61075a82826110f6565b5050565b6000805160206127e383398151915261077681610f78565b61077e61115d565b50565b60006105de826040518060400160405280600f81526020016e125b9d985b1a59081d1bdad95b9259608a1b81525060cc6111af9092919063ffffffff16565b6107c8610f30565b6000805160206128038339815191526107e081610f78565b8160648111156108025760405162461bcd60e51b815260040161050c90612330565b60005b818160ff16101561059757600085858360ff1681811061082757610827612372565b905060200201602081019061083c9190612163565b90506001600160a01b038116158061085a575061085a60cf82610f82565b1561086557506108bf565b61087360d280546001019055565b60d2546040516001600160a01b038316907fe9274a84b19e9428826de6bae8c48329354f8f0e73f771b97cae2d9dccd45a2790600090a36108bc816108b760d25490565b6111bc565b50505b806108c98161239e565b915050610805565b6000806108df60cf84611289565b509050806108ee5760006108f1565b60015b60ff169392505050565b610903610f30565b60008051602061280383398151915261091b81610f78565b6001600160a01b0382166109415760405162461bcd60e51b815260040161050c906124ff565b61094c60cf83610f82565b6109685760405162461bcd60e51b815260040161050c90612529565b61075a82610f97565b60006105de826040518060400160405280601f81526020017f5468652077616c6c657420686173206e6f7420686f6c6420616e79205342540081525060cf6112b09092919063ffffffff16565b6109c6610f30565b6109d18383836112c6565b610a115760405162461bcd60e51b815260206004820152601160248201527029b4b3b7103b32b934b33c9032b93937b960791b604482015260640161050c565b33610a1d60cf82610f82565b610a395760405162461bcd60e51b815260040161050c90612529565b610a4460cf826113aa565b8414610a895760405162461bcd60e51b81526020600482015260146024820152732a37b5b2b724b2103b32b934b33c9032b93937b960611b604482015260640161050c565b610a9460cf826113bf565b50610aa060cc856113d4565b5060405184906001600160a01b038316907fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca590600090a360405184906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a450505050565b6000805160206127e3833981519152610b2d81610f78565b61077e6113e0565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6000610b6a610f30565b610b7584848461141d565b610b7e57600080fd5b610b8c60d280546001019055565b610b99846108b760d25490565b949350505050565b60ca80546105f1906123bd565b600054610100900460ff1615808015610bce5750600054600160ff909116105b80610be85750303b158015610be8575060005460ff166001145b610c4b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161050c565b6000805460ff191660011790558015610c6e576000805461ff0019166101001790555b60c9610c7a858261256a565b5060ca610c87848261256a565b5060cb610c94838261256a565b50610c9f33336114c2565b80156106da576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b610cf2610f30565b600080516020612803833981519152610d0a81610f78565b60ca6106da83858361243f565b610d1f610f30565b600080516020612803833981519152610d3781610f78565b60c96106da83858361243f565b6060610d5160cc8361159b565b610db55760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161050c565b6000610dbf6115a7565b90506000815111610ddf5760405180602001604052806000815250610e0a565b80610de984611639565b604051602001610dfa92919061262a565b6040516020818303038152906040525b9392505050565b600082815260656020526040902060010154610e2c81610f78565b6106a883836110f6565b60cb80546105f1906123bd565b6000610e4d610f30565b600080516020612803833981519152610e6581610f78565b6001600160a01b038316610e8b5760405162461bcd60e51b815260040161050c906124ff565b610e9660cf84610f82565b15610ed85760405162461bcd60e51b815260206004820152601260248201527153425420616c72656164792065786973747360701b604482015260640161050c565b610ee660d280546001019055565b60d2546040516001600160a01b038516907fe9274a84b19e9428826de6bae8c48329354f8f0e73f771b97cae2d9dccd45a2790600090a3610e0a836108b760d25490565b50919050565b60975460ff1615610f765760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161050c565b565b61077e81336116cc565b6000610e0a836001600160a01b038416611725565b6000610fa460cf836113aa565b9050610fb160cf836113bf565b50610fbd60cc826113d4565b5060405181906001600160a01b038416907fec9ab91322523c899ede7830ec9bfc992b5981cdcc27b91162fb23de5791117b90600090a360405181906000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60006001600160e01b03198216637965db0b60e01b14806105de57506301ffc9a760e01b6001600160e01b03198316146105de565b60006105de82611731565b61107a8282610b35565b61075a5760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556110b23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6111008282610b35565b1561075a5760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b61116561173c565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000610b99848484611785565b60006001600160a01b0383166111e45760405162461bcd60e51b815260040161050c906124ff565b6111ef60cf84610f82565b156112315760405162461bcd60e51b815260206004820152601260248201527153425420616c72656164792065786973747360701b604482015260640161050c565b61123d60cf84846117d1565b5061124a60cc83856117e7565b5060405182906001600160a01b038516906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450919050565b60008080806112a1866001600160a01b0387166117fd565b909450925050505b9250929050565b6000610b99846001600160a01b03851684611785565b60008242106113115760405162461bcd60e51b81526020600482015260176024820152762a34329039b4b3b7103232b0b23634b7329032b93937b960491b604482015260640161050c565b60006040518060400160405280600d81526020016c566970332d457468657265756d60981b815250858560405180604001604052806004815260200163313ab93760e11b81525060405160200161136b9493929190612659565b60408051601f19818403018152919052805160209091012090506113a16000805160206128038339815191526103cd8386611837565b95945050505050565b6000610e0a836001600160a01b03841661185b565b6000610e0a836001600160a01b0384166118cb565b6000610e0a83836118cb565b6113e8610f30565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586111923390565b60008242106114685760405162461bcd60e51b81526020600482015260176024820152762a34329039b4b3b7103232b0b23634b7329032b93937b960491b604482015260640161050c565b60006040518060400160405280600d81526020016c566970332d457468657265756d60981b8152508585604051806040016040528060048152602001631b5a5b9d60e21b81525060405160200161136b949392919061269a565b600054610100900460ff1661152d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161050c565b6115456000805160206127e3833981519152836118e8565b61155d600080516020612803833981519152826118e8565b6115756000805160206127e3833981519152806118f2565b61075a6000805160206128038339815191526000805160206127e38339815191526118f2565b6000610e0a8383611725565b606060cb80546115b6906123bd565b80601f01602080910402602001604051908101604052809291908181526020018280546115e2906123bd565b801561162f5780601f106116045761010080835404028352916020019161162f565b820191906000526020600020905b81548152906001019060200180831161161257829003601f168201915b5050505050905090565b606060006116468361193d565b600101905060008167ffffffffffffffff8111156116665761166661217e565b6040519080825280601f01601f191660200182016040528015611690576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461169a57509392505050565b6116d68282610b35565b61075a576116e381611a15565b6116ee836020611a27565b6040516020016116ff9291906126ed565b60408051601f198184030181529082905262461bcd60e51b825261050c9160040161206f565b6000610e0a8383611bc3565b60006105de82611bdb565b60975460ff16610f765760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161050c565b6000828152600284016020526040812054801515806117a957506117a98585611725565b83906117c85760405162461bcd60e51b815260040161050c919061206f565b50949350505050565b6000610b99846001600160a01b03851684611be5565b6000610b9984846001600160a01b038516611be5565b600081815260028301602052604081205481908061182c5761181f8585611725565b9250600091506112a99050565b6001925090506112a9565b60008060006118468585611c02565b9150915061185381611c44565b509392505050565b60008181526002830160205260408120548015158061187f575061187f8484611725565b610e0a5760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640161050c565b60008181526002830160205260408120819055610e0a8383611d8e565b61075a8282611070565b600082815260656020526040808220600101805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061197c5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef810000000083106119a8576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106119c657662386f26fc10000830492506010015b6305f5e10083106119de576305f5e100830492506008015b61271083106119f257612710830492506004015b60648310611a04576064830492506002015b600a83106105de5760010192915050565b60606105de6001600160a01b03831660145b60606000611a36836002612762565b611a41906002612779565b67ffffffffffffffff811115611a5957611a5961217e565b6040519080825280601f01601f191660200182016040528015611a83576020820181803683370190505b509050600360fc1b81600081518110611a9e57611a9e612372565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611acd57611acd612372565b60200101906001600160f81b031916908160001a9053506000611af1846002612762565b611afc906001612779565b90505b6001811115611b74576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611b3057611b30612372565b1a60f81b828281518110611b4657611b46612372565b60200101906001600160f81b031916908160001a90535060049490941c93611b6d8161278c565b9050611aff565b508315610e0a5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161050c565b60008181526001830160205260408120541515610e0a565b60006105de825490565b60008281526002840160205260408120829055610b998484611d9a565b6000808251604103611c385760208301516040840151606085015160001a611c2c87828585611da6565b945094505050506112a9565b506000905060026112a9565b6000816004811115611c5857611c586127a3565b03611c605750565b6001816004811115611c7457611c746127a3565b03611cc15760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161050c565b6002816004811115611cd557611cd56127a3565b03611d225760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161050c565b6003816004811115611d3657611d366127a3565b0361077e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161050c565b6000610e0a8383611e6a565b6000610e0a8383611f5d565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611ddd5750600090506003611e61565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e31573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611e5a57600060019250925050611e61565b9150600090505b94509492505050565b60008181526001830160205260408120548015611f53576000611e8e6001836127b9565b8554909150600090611ea2906001906127b9565b9050818114611f07576000866000018281548110611ec257611ec2612372565b9060005260206000200154905080876000018481548110611ee557611ee5612372565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611f1857611f186127cc565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105de565b60009150506105de565b6000818152600183016020526040812054611fa4575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105de565b5060006105de565b60008060208385031215611fbf57600080fd5b823567ffffffffffffffff80821115611fd757600080fd5b818501915085601f830112611feb57600080fd5b813581811115611ffa57600080fd5b8660208260051b850101111561200f57600080fd5b60209290920196919550909350505050565b60006020828403121561203357600080fd5b81356001600160e01b031981168114610e0a57600080fd5b60005b8381101561206657818101518382015260200161204e565b50506000910152565b602081526000825180602084015261208e81604085016020870161204b565b601f01601f19169190910160400192915050565b6000602082840312156120b457600080fd5b5035919050565b80356001600160a01b03811681146120d257600080fd5b919050565b600080604083850312156120ea57600080fd5b823591506120fa602084016120bb565b90509250929050565b6000806020838503121561211657600080fd5b823567ffffffffffffffff8082111561212e57600080fd5b818501915085601f83011261214257600080fd5b81358181111561215157600080fd5b86602082850101111561200f57600080fd5b60006020828403121561217557600080fd5b610e0a826120bb565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126121a557600080fd5b813567ffffffffffffffff808211156121c0576121c061217e565b604051601f8301601f19908116603f011681019082821181831017156121e8576121e861217e565b8160405283815286602085880101111561220157600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561223657600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561225b57600080fd5b61226786828701612194565b9150509250925092565b60008060006060848603121561228657600080fd5b61228f846120bb565b925060208401359150604084013567ffffffffffffffff81111561225b57600080fd5b6000806000606084860312156122c757600080fd5b833567ffffffffffffffff808211156122df57600080fd5b6122eb87838801612194565b9450602086013591508082111561230157600080fd5b61230d87838801612194565b9350604086013591508082111561232357600080fd5b5061226786828701612194565b60208082526022908201527f546865206d6178206c656e677468206f66206164647265737365732069732031604082015261030360f41b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff81036123b4576123b4612388565b60010192915050565b600181811c908216806123d157607f821691505b602082108103610f2a57634e487b7160e01b600052602260045260246000fd5b601f8211156106a857600081815260208120601f850160051c810160208610156124185750805b601f850160051c820191505b8181101561243757828155600101612424565b505050505050565b67ffffffffffffffff8311156124575761245761217e565b61246b8361246583546123bd565b836123f1565b6000601f84116001811461249f57600085156124875750838201355b600019600387901b1c1916600186901b178355610597565b600083815260209020601f19861690835b828110156124d057868501358255602094850194600190920191016124b0565b50868210156124ed5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60208082526010908201526f4164647265737320697320656d70747960801b604082015260600190565b60208082526021908201527f546865206163636f756e7420646f6573206e6f74206861766520616e792053426040820152601560fa1b606082015260800190565b815167ffffffffffffffff8111156125845761258461217e565b6125988161259284546123bd565b846123f1565b602080601f8311600181146125cd57600084156125b55750858301515b600019600386901b1c1916600185901b178555612437565b600085815260208120601f198616915b828110156125fc578886015182559484019460019091019084016125dd565b508582101561261a5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000835161263c81846020880161204b565b83519083019061265081836020880161204b565b01949350505050565b6000855161266b818460208a0161204b565b8083019050858152846020820152835161268c81604084016020880161204b565b016040019695505050505050565b600085516126ac818460208a0161204b565b80830190506bffffffffffffffffffffffff198660601b16815284601482015283516126df81603484016020880161204b565b016034019695505050505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161272581601785016020880161204b565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161275681602884016020880161204b565b01602801949350505050565b80820281158282048414176105de576105de612388565b808201808211156105de576105de612388565b60008161279b5761279b612388565b506000190190565b634e487b7160e01b600052602160045260246000fd5b818103818111156105de576105de612388565b634e487b7160e01b600052603160045260246000fdfe7613a25ecc738585a232ad50a301178f12b3ba8887d13e138b523c4269c47689a49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775a2646970667358221220ccb105cd4672e1de0db8db459251bfdcc43df83deae14de4ff0fb7375ed3fb1664736f6c63430008110033
Deployed Bytecode Sourcemap
461:8765:19:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3686:473;;;;;;:::i;:::-;;:::i;:::-;;8606:327;;;;;;:::i;:::-;;:::i;:::-;;;1090:14:22;;1083:22;1065:41;;1053:2;1038:18;8606:327:19;;;;;;;;785:27;;;:::i;:::-;;;;;;;:::i;7505:106::-;;;:::i;:::-;;;1919:25:22;;;1907:2;1892:18;7505:106:19;1773:177:22;4708:129:0;;;;;;:::i;:::-;4782:7;4808:12;;;:6;:12;;;;;:22;;;;4708:129;5133:145;;;;;;:::i;:::-;;:::i;1490:151:19:-;;;;;;:::i;:::-;;:::i;6242:214:0:-;;;;;;:::i;:::-;;:::i;1126:80:18:-;;;:::i;1858:84:3:-;1928:7;;;;1858:84;;7272:140:19;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3705:32:22;;;3687:51;;3675:2;3660:18;7272:140:19;3541:203:22;544:51:18;;;;;;;;;;;;;;;-1:-1:-1;;;544:51:18;;;;;2697:587:19;;;;;;:::i;:::-;;:::i;400:72:18:-;;-1:-1:-1;;;;;;;;;;;400:72:18;;6828:166:19;;;;;;:::i;:::-;;:::i;3339:286::-;;;;;;:::i;:::-;;:::i;7063:152::-;;;;;;:::i;:::-;;:::i;5571:671::-;;;;;;:::i;:::-;;:::i;1044:76:18:-;;;:::i;1100:39:19:-;;;;;;;3203:145:0;;;;;;:::i;:::-;;:::i;4489:323:19:-;;;;;;:::i;:::-;;:::i;838:29::-;;;:::i;2324:49:0:-;;2369:4;2324:49;;669:43:18;;;;;;;;;;;;;;;-1:-1:-1;;;669:43:18;;;;;1146:289:19;;;;;;:::i;:::-;;:::i;1835:147::-;;;;;;:::i;:::-;;:::i;2029:139::-;;;;;;:::i;:::-;;:::i;6308:461::-;;;;;;:::i;:::-;;:::i;478:60:18:-;;-1:-1:-1;;;;;;;;;;;478:60:18;;5558:147:0;;;;;;:::i;:::-;;:::i;890:26:19:-;;;:::i;620:43:18:-;;;;;;;;;;;;;;;-1:-1:-1;;;620:43:18;;;;;2221:417:19;;;;;;:::i;:::-;;:::i;3686:473::-;1482:19:3;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;2802:16:0::1;2813:4;2802:10;:16::i;:::-;3836:5:19::0;3880:3:::2;3866:17:::0;::::2;;3858:64;;;;-1:-1:-1::0;;;3858:64:19::2;;;;;;;:::i;:::-;;;;;;;;;3937:7;3932:221;3954:10;3950:1;:14;;;3932:221;;;3985:12;4000:5;;4006:1;4000:8;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;3985:23:::0;-1:-1:-1;;;;;;4026:18:19;::::2;::::0;;:47:::2;;-1:-1:-1::0;4049:24:19::2;:9;4068:4:::0;4049:18:::2;:24::i;:::-;4048:25;4026:47;4022:94;;;4093:8;;;4022:94;4129:13;4137:4;4129:7;:13::i;:::-;3971:182;3932:221;3966:3:::0;::::2;::::0;::::2;:::i;:::-;;;;3932:221;;;;3805:354;1511:1:3::1;3686:473:19::0;;:::o;8606:327::-;8731:4;-1:-1:-1;;;;;;8770:40:19;;-1:-1:-1;;;8770:40:19;;:104;;-1:-1:-1;;;;;;;8826:48:19;;-1:-1:-1;;;8826:48:19;8770:104;:156;;;;8890:36;8914:11;8890:23;:36::i;:::-;8751:175;8606:327;-1:-1:-1;;8606:327:19:o;785:27::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7505:106::-;7560:7;7586:18;:9;:16;:18::i;:::-;7579:25;;7505:106;:::o;5133:145:0:-;4782:7;4808:12;;;:6;:12;;;;;:22;;;2802:16;2813:4;2802:10;:16::i;:::-;5246:25:::1;5257:4;5263:7;5246:10;:25::i;:::-;5133:145:::0;;;:::o;1490:151:19:-;1482:19:3;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;2802:16:0::1;2813:4;2802:10;:16::i;:::-;1616:12:19::2;:18;1631:3:::0;;1616:12;:18:::2;:::i;:::-;;1511:1:3::1;1490:151:19::0;;:::o;6242:214:0:-;-1:-1:-1;;;;;6337:23:0;;929:10:5;6337:23:0;6329:83;;;;-1:-1:-1;;;6329:83:0;;9960:2:22;6329:83:0;;;9942:21:22;9999:2;9979:18;;;9972:30;10038:34;10018:18;;;10011:62;-1:-1:-1;;;10089:18:22;;;10082:45;10144:19;;6329:83:0;9758:411:22;6329:83:0;6423:26;6435:4;6441:7;6423:11;:26::i;:::-;6242:214;;:::o;1126:80:18:-;-1:-1:-1;;;;;;;;;;;2802:16:0;2813:4;2802:10;:16::i;:::-;1189:10:18::1;:8;:10::i;:::-;1126:80:::0;:::o;7272:140:19:-;7338:7;7364:41;7378:7;7364:41;;;;;;;;;;;;;-1:-1:-1;;;7364:41:19;;;:9;:13;;:41;;;;;:::i;2697:587::-;1482:19:3;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;2802:16:0::1;2813:4;2802:10;:16::i;:::-;2847:5:19::0;2891:3:::2;2877:17:::0;::::2;;2869:64;;;;-1:-1:-1::0;;;2869:64:19::2;;;;;;;:::i;:::-;2948:7;2943:335;2965:10;2961:1;:14;;;2943:335;;;2996:10;3009:5;;3015:1;3009:8;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2996:21:::0;-1:-1:-1;;;;;;3035:16:19;::::2;::::0;;:42:::2;;-1:-1:-1::0;3055:22:19::2;:9;3074:2:::0;3055:18:::2;:22::i;:::-;3031:89;;;3097:8;;;3031:89;3133:27;:15;1032:19:11::0;;1050:1;1032:19;;;945:123;3133:27:19::2;3191:15;918:14:11::0;3179:38:19::2;::::0;-1:-1:-1;;;;;3179:38:19;::::2;::::0;::::2;::::0;;;::::2;3231:36;3237:2;3241:25;:15;918:14:11::0;;827:112;3241:25:19::2;3231:5;:36::i;:::-;;2982:296;2943:335;2977:3:::0;::::2;::::0;::::2;:::i;:::-;;;;2943:335;;6828:166:::0;6894:7;;6932:23;:9;6949:5;6932:16;:23::i;:::-;6913:42;;;6972:7;:15;;6986:1;6972:15;;;6982:1;6972:15;6965:22;;;6828:166;-1:-1:-1;;;6828:166:19:o;3339:286::-;1482:19:3;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;2802:16:0::1;2813:4;2802:10;:16::i;:::-;-1:-1:-1::0;;;;;3476:18:19;::::2;3468:47;;;;-1:-1:-1::0;;;3468:47:19::2;;;;;;;:::i;:::-;3533:24;:9;3552:4:::0;3533:18:::2;:24::i;:::-;3525:70;;;;-1:-1:-1::0;;;3525:70:19::2;;;;;;;:::i;:::-;3605:13;3613:4;3605:7;:13::i;7063:152::-:0;7128:7;7154:54;7168:4;7154:54;;;;;;;;;;;;;;;;;:9;:13;;:54;;;;;:::i;5571:671::-;1482:19:3;:17;:19::i;:::-;5746:41:19::1;5757:8;5767;5777:9;5746:10;:41::i;:::-;5738:71;;;::::0;-1:-1:-1;;;5738:71:19;;11123:2:22;5738:71:19::1;::::0;::::1;11105:21:22::0;11162:2;11142:18;;;11135:30;-1:-1:-1;;;11181:18:22;;;11174:47;11238:18;;5738:71:19::1;10921:341:22::0;5738:71:19::1;929:10:5::0;5879:26:19::1;:9;929:10:5::0;5879:18:19::1;:26::i;:::-;5858:106;;;;-1:-1:-1::0;;;5858:106:19::1;;;;;;;:::i;:::-;6007:21;:9;6021:6:::0;6007:13:::1;:21::i;:::-;5995:8;:33;5974:100;;;::::0;-1:-1:-1;;;5974:100:19;;11469:2:22;5974:100:19::1;::::0;::::1;11451:21:22::0;11508:2;11488:18;;;11481:30;-1:-1:-1;;;11527:18:22;;;11520:50;11587:18;;5974:100:19::1;11267:344:22::0;5974:100:19::1;6084:24;:9;6101:6:::0;6084:16:::1;:24::i;:::-;-1:-1:-1::0;6118:26:19::1;:9;6135:8:::0;6118:16:::1;:26::i;:::-;-1:-1:-1::0;6160:22:19::1;::::0;6173:8;;-1:-1:-1;;;;;6160:22:19;::::1;::::0;::::1;::::0;;;::::1;6197:38;::::0;6226:8;;6222:1:::1;::::0;-1:-1:-1;;;;;6197:38:19;::::1;::::0;::::1;::::0;6222:1;;6197:38:::1;5705:537;5571:671:::0;;;:::o;1044:76:18:-;-1:-1:-1;;;;;;;;;;;2802:16:0;2813:4;2802:10;:16::i;:::-;1105:8:18::1;:6;:8::i;3203:145:0:-:0;3289:4;3312:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;3312:29:0;;;;;;;;;;;;;;;3203:145::o;4489:323:19:-;4627:7;1482:19:3;:17;:19::i;:::-;4677:36:19::1;4688:3;4693:8;4703:9;4677:10;:36::i;:::-;4669:45;;;::::0;::::1;;4724:27;:15;1032:19:11::0;;1050:1;1032:19;;;945:123;4724:27:19::1;4768:37;4774:3;4779:25;:15;918:14:11::0;;827:112;4768:37:19::1;4761:44:::0;4489:323;-1:-1:-1;;;;4489:323:19:o;838:29::-;;;;;;;:::i;1146:289::-;3268:19:2;3291:13;;;;;;3290:14;;3336:34;;;;-1:-1:-1;3354:12:2;;3369:1;3354:12;;;;:16;3336:34;3335:108;;;-1:-1:-1;3415:4:2;1476:19:4;:23;;;3376:66:2;;-1:-1:-1;3425:12:2;;;;;:17;3376:66;3314:201;;;;-1:-1:-1;;;3314:201:2;;11818:2:22;3314:201:2;;;11800:21:22;11857:2;11837:18;;;11830:30;11896:34;11876:18;;;11869:62;-1:-1:-1;;;11947:18:22;;;11940:44;12001:19;;3314:201:2;11616:410:22;3314:201:2;3525:12;:16;;-1:-1:-1;;3525:16:2;3540:1;3525:16;;;3551:65;;;;3585:13;:20;;-1:-1:-1;;3585:20:2;;;;;3551:65;1298:4:19::1;:12;1305:5:::0;1298:4;:12:::1;:::i;:::-;-1:-1:-1::0;1320:6:19::1;:16;1329:7:::0;1320:6;:16:::1;:::i;:::-;-1:-1:-1::0;1346:12:19::1;:28;1361:13:::0;1346:12;:28:::1;:::i;:::-;;1384:44;1405:10;1417;1384:20;:44::i;:::-;3640:14:2::0;3636:99;;;3686:5;3670:21;;-1:-1:-1;;3670:21:2;;;3710:14;;-1:-1:-1;13540:36:22;;3710:14:2;;13528:2:22;13513:18;3710:14:2;;;;;;;3258:483;1146:289:19;;;:::o;1835:147::-;1482:19:3;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;2802:16:0::1;2813:4;2802:10;:16::i;:::-;1959:6:19::2;:16;1968:7:::0;;1959:6;:16:::2;:::i;2029:139::-:0;1482:19:3;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;2802:16:0::1;2813:4;2802:10;:16::i;:::-;2149:4:19::2;:12;2156:5:::0;;2149:4;:12:::2;:::i;6308:461::-:0;6421:13;6471:27;:9;6490:7;6471:18;:27::i;:::-;6450:121;;;;-1:-1:-1;;;6450:121:19;;13789:2:22;6450:121:19;;;13771:21:22;13828:2;13808:18;;;13801:30;13867:34;13847:18;;;13840:62;-1:-1:-1;;;13918:18:22;;;13911:45;13973:19;;6450:121:19;13587:411:22;6450:121:19;6581:21;6605:10;:8;:10::i;:::-;6581:34;;6668:1;6650:7;6644:21;:25;:118;;;;;;;;;;;;;;;;;6712:7;6721:18;:7;:16;:18::i;:::-;6695:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;6644:118;6625:137;6308:461;-1:-1:-1;;;6308:461:19:o;5558:147:0:-;4782:7;4808:12;;;:6;:12;;;;;:22;;;2802:16;2813:4;2802:10;:16::i;:::-;5672:26:::1;5684:4;5690:7;5672:11;:26::i;890::19:-:0;;;;;;;:::i;2221:417::-;2352:7;1482:19:3;:17;:19::i;:::-;-1:-1:-1;;;;;;;;;;;2802:16:0::1;2813:4;2802:10;:16::i;:::-;-1:-1:-1::0;;;;;2383:17:19;::::2;2375:46;;;;-1:-1:-1::0;;;2375:46:19::2;;;;;;;:::i;:::-;2440:23;:9;2459:3:::0;2440:18:::2;:23::i;:::-;2439:24;2431:55;;;::::0;-1:-1:-1;;;2431:55:19;;14706:2:22;2431:55:19::2;::::0;::::2;14688:21:22::0;14745:2;14725:18;;;14718:30;-1:-1:-1;;;14764:18:22;;;14757:48;14822:18;;2431:55:19::2;14504:342:22::0;2431:55:19::2;2496:27;:15;1032:19:11::0;;1050:1;1032:19;;;945:123;2496:27:19::2;2551:15;918:14:11::0;2538:39:19::2;::::0;-1:-1:-1;;;;;2538:39:19;::::2;::::0;::::2;::::0;;;::::2;2594:37;2600:3;2605:25;:15;918:14:11::0;;827:112;2828:1:0::2;1511::3::1;2221:417:19::0;;;:::o;2010:106:3:-;1928:7;;;;2079:9;2071:38;;;;-1:-1:-1;;;2071:38:3;;15053:2:22;2071:38:3;;;15035:21:22;15092:2;15072:18;;;15065:30;-1:-1:-1;;;15111:18:22;;;15104:46;15167:18;;2071:38:3;14851:340:22;2071:38:3;2010:106::o;3642:103:0:-;3708:30;3719:4;929:10:5;3708::0;:30::i;12365:166:16:-;12449:4;12472:52;12481:3;-1:-1:-1;;;;;12501:21:16;;12472:8;:52::i;4236:247:19:-;4286:15;4304:19;:9;4318:4;4304:13;:19::i;:::-;4286:37;-1:-1:-1;4333:22:19;:9;4350:4;4333:16;:22::i;:::-;-1:-1:-1;4365:25:19;:9;4382:7;4365:16;:25::i;:::-;-1:-1:-1;4405:21:19;;4418:7;;-1:-1:-1;;;;;4405:21:19;;;;;;;;4441:35;;4468:7;;4464:1;;-1:-1:-1;;;;;4441:35:19;;;;;4464:1;;4441:35;4276:207;4236:247;:::o;2903:213:0:-;2988:4;-1:-1:-1;;;;;;3011:58:0;;-1:-1:-1;;;3011:58:0;;:98;;-1:-1:-1;;;;;;;;;;1168:51:7;;;3073:36:0;1060:166:7;12614:120:16;12683:7;12709:18;12716:3;12709:6;:18::i;7791:233:0:-;7874:22;7882:4;7888:7;7874;:22::i;:::-;7869:149;;7912:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;7912:29:0;;;;;;;;;:36;;-1:-1:-1;;7912:36:0;7944:4;7912:36;;;7994:12;929:10:5;;850:96;7994:12:0;-1:-1:-1;;;;;7967:40:0;7985:7;-1:-1:-1;;;;;7967:40:0;7979:4;7967:40;;;;;;;;;;7791:233;;:::o;8195:234::-;8278:22;8286:4;8292:7;8278;:22::i;:::-;8274:149;;;8348:5;8316:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;8316:29:0;;;;;;;;;;:37;;-1:-1:-1;;8316:37:0;;;8372:40;929:10:5;;8316:12:0;;8372:40;;8348:5;8372:40;8195:234;;:::o;2676:117:3:-;1729:16;:14;:16::i;:::-;2734:7:::1;:15:::0;;-1:-1:-1;;2734:15:3::1;::::0;;2764:22:::1;929:10:5::0;2773:12:3::1;2764:22;::::0;-1:-1:-1;;;;;3705:32:22;;;3687:51;;3675:2;3660:18;2764:22:3::1;;;;;;;2676:117::o:0;11193:240:16:-;11330:7;11380:43;11384:3;11404;11410:12;11380:3;:43::i;5071:344:19:-;5133:7;-1:-1:-1;;;;;5160:16:19;;5152:45;;;;-1:-1:-1;;;5152:45:19;;;;;;;:::i;:::-;5216:22;:9;5235:2;5216:18;:22::i;:::-;5215:23;5207:54;;;;-1:-1:-1;;;5207:54:19;;14706:2:22;5207:54:19;;;14688:21:22;14745:2;14725:18;;;14718:30;-1:-1:-1;;;14764:18:22;;;14757:48;14822:18;;5207:54:19;14504:342:22;5207:54:19;5272:26;:9;5286:2;5290:7;5272:13;:26::i;:::-;-1:-1:-1;5308:26:19;:9;5322:7;5331:2;5308:13;:26::i;:::-;-1:-1:-1;5350:33:19;;5375:7;;-1:-1:-1;;;;;5350:33:19;;;5367:1;;5350:33;;5367:1;;5350:33;-1:-1:-1;5401:7:19;5071:344;-1:-1:-1;5071:344:19:o;13444:238:16:-;13526:4;;;;13583:50;13590:3;-1:-1:-1;;;;;13610:21:16;;13583:6;:50::i;:::-;13551:82;;-1:-1:-1;13551:82:16;-1:-1:-1;;;13444:238:16;;;;;;:::o;14281:240::-;14418:7;14452:61;14456:3;-1:-1:-1;;;;;14476:21:16;;14500:12;14452:3;:61::i;8127:412:19:-;8260:4;8302:8;8284:15;:26;8276:62;;;;-1:-1:-1;;;8276:62:19;;15398:2:22;8276:62:19;;;15380:21:22;15437:2;15417:18;;;15410:30;-1:-1:-1;;;15456:18:22;;;15449:53;15519:18;;8276:62:19;15196:347:22;8276:62:19;8348:19;8410:10;;;;;;;;;;;;;-1:-1:-1;;;8410:10:19;;;8422:8;8432;8442:11;;;;;;;;;;;;;-1:-1:-1;;;8442:11:19;;;8393:61;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;8393:61:19;;;;;;;;;8370:94;;8393:61;8370:94;;;;;-1:-1:-1;8481:51:19;-1:-1:-1;;;;;;;;;;;8501:30:19;8370:94;8521:9;8501:19;:30::i;8481:51::-;8474:58;8127:412;-1:-1:-1;;;;;8127:412:19:o;13833:168:16:-;13912:7;13946:47;13950:3;-1:-1:-1;;;;;13970:21:16;;13946:3;:47::i;12129:157::-;12206:4;12229:50;12236:3;-1:-1:-1;;;;;12256:21:16;;12229:6;:50::i;9077:139::-;9154:4;9177:32;9184:3;9204;9177:6;:32::i;2429:115:3:-;1482:19;:17;:19::i;:::-;2488:7:::1;:14:::0;;-1:-1:-1;;2488:14:3::1;2498:4;2488:14;::::0;;2517:20:::1;2524:12;929:10:5::0;;850:96;7668:402:19;7796:4;7838:8;7820:15;:26;7812:62;;;;-1:-1:-1;;;7812:62:19;;15398:2:22;7812:62:19;;;15380:21:22;15437:2;15417:18;;;15410:30;-1:-1:-1;;;15456:18:22;;;15449:53;15519:18;;7812:62:19;15196:347:22;7812:62:19;7884:19;7946:10;;;;;;;;;;;;;-1:-1:-1;;;7946:10:19;;;7958:3;7963:8;7973:11;;;;;;;;;;;;;-1:-1:-1;;;7973:11:19;;;7929:56;;;;;;;;;;;:::i;719:319:18:-;5363:13:2;;;;;;;5355:69;;;;-1:-1:-1;;;5355:69:2;;17087:2:22;5355:69:2;;;17069:21:22;17126:2;17106:18;;;17099:30;17165:34;17145:18;;;17138:62;-1:-1:-1;;;17216:18:22;;;17209:41;17267:19;;5355:69:2;16885:407:22;5355:69:2;840:40:18::1;-1:-1:-1::0;;;;;;;;;;;869:10:18::1;840;:40::i;:::-;890:29;-1:-1:-1::0;;;;;;;;;;;913:5:18::1;890:10;:29::i;:::-;929:49;-1:-1:-1::0;;;;;;;;;;;443:29:18;929:13:::1;:49::i;:::-;988:43;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;988:13:18::1;:43::i;9295:148:16:-:0;9379:4;9402:34;9411:3;9431;9402:8;:34::i;1693:94:19:-;1736:13;1768:12;1761:19;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1693:94;:::o;415:696:12:-;471:13;520:14;537:17;548:5;537:10;:17::i;:::-;557:1;537:21;520:38;;572:20;606:6;595:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;595:18:12;-1:-1:-1;572:41:12;-1:-1:-1;733:28:12;;;749:2;733:28;788:280;-1:-1:-1;;819:5:12;-1:-1:-1;;;953:2:12;942:14;;937:30;819:5;924:44;1012:2;1003:11;;;-1:-1:-1;1032:21:12;788:280;1032:21;-1:-1:-1;1088:6:12;415:696;-1:-1:-1;;;415:696:12:o;4026:501:0:-;4114:22;4122:4;4128:7;4114;:22::i;:::-;4109:412;;4297:39;4328:7;4297:30;:39::i;:::-;4407:49;4446:4;4453:2;4407:30;:49::i;:::-;4204:274;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;4204:274:0;;;;;;;;;;-1:-1:-1;;;4152:358:0;;;;;;;:::i;3150:140:16:-;3237:4;3260:23;:3;3279;3260:18;:23::i;3380:123::-;3452:7;3478:18;:3;:16;:18::i;2188:106:3:-;1928:7;;;;2246:41;;;;-1:-1:-1;;;2246:41:3;;18448:2:22;2246:41:3;;;18430:21:22;18487:2;18467:18;;;18460:30;-1:-1:-1;;;18506:18:22;;;18499:50;18566:18;;2246:41:3;18246:344:22;5164:285:16;5304:7;5339:16;;;:11;;;:16;;;;;;5373:10;;;;:32;;;5387:18;5396:3;5401;5387:8;:18::i;:::-;5407:12;5365:55;;;;;-1:-1:-1;;;5365:55:16;;;;;;;;:::i;:::-;-1:-1:-1;5437:5:16;5164:285;-1:-1:-1;;;;5164:285:16:o;11758:212::-;11877:4;11900:63;11904:3;-1:-1:-1;;;;;11924:21:16;;11956:5;11900:3;:63::i;8706:212::-;8825:4;8848:63;8852:3;8872;-1:-1:-1;;;;;8886:23:16;;8848:3;:63::i;4188:298::-;4273:4;4314:16;;;:11;;;:16;;;;;;4273:4;;4314:16;4340:140;;4387:18;4396:3;4401;4387:8;:18::i;:::-;4379:39;-1:-1:-1;4415:1:16;;-1:-1:-1;4379:39:16;;-1:-1:-1;4379:39:16;4340:140;4457:4;;-1:-1:-1;4463:5:16;-1:-1:-1;4449:20:16;;3661:227:13;3739:7;3759:17;3778:18;3800:27;3811:4;3817:9;3800:10;:27::i;:::-;3758:69;;;;3837:18;3849:5;3837:11;:18::i;:::-;-1:-1:-1;3872:9:13;3661:227;-1:-1:-1;;;3661:227:13:o;4637:247:16:-;4719:7;4754:16;;;:11;;;:16;;;;;;4788:10;;;;:32;;;4802:18;4811:3;4816;4802:8;:18::i;:::-;4780:75;;;;-1:-1:-1;;;4780:75:16;;18797:2:22;4780:75:16;;;18779:21:22;18836:2;18816:18;;;18809:30;18875:32;18855:18;;;18848:60;18925:18;;4780:75:16;18595:354:22;2907:164:16;2987:4;3010:16;;;:11;;;:16;;;;;3003:23;;;3043:21;3010:3;3022;3043:16;:21::i;7141:110:0:-;7219:25;7230:4;7236:7;7219:10;:25::i;7376:247::-;7459:25;4808:12;;;:6;:12;;;;;;:22;;;;7515:34;;;;7564:52;;4808:22;;7515:34;;4808:22;;:12;;7564:52;;7459:25;7564:52;7449:174;7376:247;;:::o;9889:890:15:-;9942:7;;-1:-1:-1;;;10017:15:15;;10013:99;;-1:-1:-1;;;10052:15:15;;;-1:-1:-1;10095:2:15;10085:12;10013:99;10138:6;10129:5;:15;10125:99;;10173:6;10164:15;;;-1:-1:-1;10207:2:15;10197:12;10125:99;10250:6;10241:5;:15;10237:99;;10285:6;10276:15;;;-1:-1:-1;10319:2:15;10309:12;10237:99;10362:5;10353;:14;10349:96;;10396:5;10387:14;;;-1:-1:-1;10429:1:15;10419:11;10349:96;10471:5;10462;:14;10458:96;;10505:5;10496:14;;;-1:-1:-1;10538:1:15;10528:11;10458:96;10580:5;10571;:14;10567:96;;10614:5;10605:14;;;-1:-1:-1;10647:1:15;10637:11;10567:96;10689:5;10680;:14;10676:64;;10724:1;10714:11;10766:6;9889:890;-1:-1:-1;;9889:890:15:o;2146:149:6:-;2204:13;2236:52;-1:-1:-1;;;;;2248:22:6;;333:2;1557:437;1632:13;1657:19;1689:10;1693:6;1689:1;:10;:::i;:::-;:14;;1702:1;1689:14;:::i;:::-;1679:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1679:25:6;;1657:47;;-1:-1:-1;;;1714:6:6;1721:1;1714:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1714:15:6;;;;;;;;;-1:-1:-1;;;1739:6:6;1746:1;1739:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;1739:15:6;;;;;;;;-1:-1:-1;1769:9:6;1781:10;1785:6;1781:1;:10;:::i;:::-;:14;;1794:1;1781:14;:::i;:::-;1769:26;;1764:128;1801:1;1797;:5;1764:128;;;-1:-1:-1;;;1844:5:6;1852:3;1844:11;1835:21;;;;;;;:::i;:::-;;;;1823:6;1830:1;1823:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;1823:33:6;;;;;;;;-1:-1:-1;1880:1:6;1870:11;;;;;1804:3;;;:::i;:::-;;;1764:128;;;-1:-1:-1;1909:10:6;;1901:55;;;;-1:-1:-1;;;1901:55:6;;19600:2:22;1901:55:6;;;19582:21:22;;;19619:18;;;19612:30;19678:34;19658:18;;;19651:62;19730:18;;1901:55:6;19398:356:22;6412:138:17;6492:4;4343:19;;;:12;;;:19;;;;;;:24;;6515:28;4247:127;6631:115;6694:7;6720:19;6728:3;4537:18;;4455:107;2535:204:16;2657:4;2673:16;;;:11;;;:16;;;;;:24;;;2714:18;2673:3;2685;2714:13;:18::i;2145:730:13:-;2226:7;2235:12;2263:9;:16;2283:2;2263:22;2259:610;;2599:4;2584:20;;2578:27;2648:4;2633:20;;2627:27;2705:4;2690:20;;2684:27;2301:9;2676:36;2746:25;2757:4;2676:36;2578:27;2627;2746:10;:25::i;:::-;2739:32;;;;;;;;;2259:610;-1:-1:-1;2818:1:13;;-1:-1:-1;2822:35:13;2802:56;;570:511;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:441;;570:511;:::o;634:441::-;743:29;734:5;:38;;;;;;;;:::i;:::-;;730:345;;788:34;;-1:-1:-1;;;788:34:13;;20093:2:22;788:34:13;;;20075:21:22;20132:2;20112:18;;;20105:30;20171:26;20151:18;;;20144:54;20215:18;;788:34:13;19891:348:22;730:345:13;852:35;843:5;:44;;;;;;;;:::i;:::-;;839:236;;903:41;;-1:-1:-1;;;903:41:13;;20446:2:22;903:41:13;;;20428:21:22;20485:2;20465:18;;;20458:30;20524:33;20504:18;;;20497:61;20575:18;;903:41:13;20244:355:22;839:236:13;974:30;965:5;:39;;;;;;;;:::i;:::-;;961:114;;1020:44;;-1:-1:-1;;;1020:44:13;;20806:2:22;1020:44:13;;;20788:21:22;20845:2;20825:18;;;20818:30;20884:34;20864:18;;;20857:62;-1:-1:-1;;;20935:18:22;;;20928:32;20977:19;;1020:44:13;20604:398:22;6202:129:17;6275:4;6298:26;6306:3;6318:5;6298:7;:26::i;5911:123::-;5981:4;6004:23;6009:3;6021:5;6004:4;:23::i;5069:1494:13:-;5195:7;;6119:66;6106:79;;6102:161;;;-1:-1:-1;6217:1:13;;-1:-1:-1;6221:30:13;6201:51;;6102:161;6374:24;;;6357:14;6374:24;;;;;;;;;21234:25:22;;;21307:4;21295:17;;21275:18;;;21268:45;;;;21329:18;;;21322:34;;;21372:18;;;21365:34;;;6374:24:13;;21206:19:22;;6374:24:13;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6374:24:13;;-1:-1:-1;;6374:24:13;;;-1:-1:-1;;;;;;;6412:20:13;;6408:101;;6464:1;6468:29;6448:50;;;;;;;6408:101;6527:6;-1:-1:-1;6535:20:13;;-1:-1:-1;5069:1494:13;;;;;;;;:::o;2778:1388:17:-;2844:4;2981:19;;;:12;;;:19;;;;;;3015:15;;3011:1149;;3384:21;3408:14;3421:1;3408:10;:14;:::i;:::-;3456:18;;3384:38;;-1:-1:-1;3436:17:17;;3456:22;;3477:1;;3456:22;:::i;:::-;3436:42;;3510:13;3497:9;:26;3493:398;;3543:17;3563:3;:11;;3575:9;3563:22;;;;;;;;:::i;:::-;;;;;;;;;3543:42;;3714:9;3685:3;:11;;3697:13;3685:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3797:23;;;:12;;;:23;;;;;:36;;;3493:398;3969:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;4061:3;:12;;:19;4074:5;4061:19;;;;;;;;;;;4054:26;;;4102:4;4095:11;;;;;;;3011:1149;4144:5;4137:12;;;;;2206:404;2269:4;4343:19;;;:12;;;:19;;;;;;2285:319;;-1:-1:-1;2327:23:17;;;;;;;;:11;:23;;;;;;;;;;;;;2507:18;;2485:19;;;:12;;;:19;;;;;;:40;;;;2539:11;;2285:319;-1:-1:-1;2588:5:17;2581:12;;14:615:22;100:6;108;161:2;149:9;140:7;136:23;132:32;129:52;;;177:1;174;167:12;129:52;217:9;204:23;246:18;287:2;279:6;276:14;273:34;;;303:1;300;293:12;273:34;341:6;330:9;326:22;316:32;;386:7;379:4;375:2;371:13;367:27;357:55;;408:1;405;398:12;357:55;448:2;435:16;474:2;466:6;463:14;460:34;;;490:1;487;480:12;460:34;543:7;538:2;528:6;525:1;521:14;517:2;513:23;509:32;506:45;503:65;;;564:1;561;554:12;503:65;595:2;587:11;;;;;617:6;;-1:-1:-1;14:615:22;;-1:-1:-1;;;;14:615:22:o;634:286::-;692:6;745:2;733:9;724:7;720:23;716:32;713:52;;;761:1;758;751:12;713:52;787:23;;-1:-1:-1;;;;;;839:32:22;;829:43;;819:71;;886:1;883;876:12;1117:250;1202:1;1212:113;1226:6;1223:1;1220:13;1212:113;;;1302:11;;;1296:18;1283:11;;;1276:39;1248:2;1241:10;1212:113;;;-1:-1:-1;;1359:1:22;1341:16;;1334:27;1117:250::o;1372:396::-;1521:2;1510:9;1503:21;1484:4;1553:6;1547:13;1596:6;1591:2;1580:9;1576:18;1569:34;1612:79;1684:6;1679:2;1668:9;1664:18;1659:2;1651:6;1647:15;1612:79;:::i;:::-;1752:2;1731:15;-1:-1:-1;;1727:29:22;1712:45;;;;1759:2;1708:54;;1372:396;-1:-1:-1;;1372:396:22:o;1955:180::-;2014:6;2067:2;2055:9;2046:7;2042:23;2038:32;2035:52;;;2083:1;2080;2073:12;2035:52;-1:-1:-1;2106:23:22;;1955:180;-1:-1:-1;1955:180:22:o;2322:173::-;2390:20;;-1:-1:-1;;;;;2439:31:22;;2429:42;;2419:70;;2485:1;2482;2475:12;2419:70;2322:173;;;:::o;2500:254::-;2568:6;2576;2629:2;2617:9;2608:7;2604:23;2600:32;2597:52;;;2645:1;2642;2635:12;2597:52;2681:9;2668:23;2658:33;;2710:38;2744:2;2733:9;2729:18;2710:38;:::i;:::-;2700:48;;2500:254;;;;;:::o;2759:592::-;2830:6;2838;2891:2;2879:9;2870:7;2866:23;2862:32;2859:52;;;2907:1;2904;2897:12;2859:52;2947:9;2934:23;2976:18;3017:2;3009:6;3006:14;3003:34;;;3033:1;3030;3023:12;3003:34;3071:6;3060:9;3056:22;3046:32;;3116:7;3109:4;3105:2;3101:13;3097:27;3087:55;;3138:1;3135;3128:12;3087:55;3178:2;3165:16;3204:2;3196:6;3193:14;3190:34;;;3220:1;3217;3210:12;3190:34;3265:7;3260:2;3251:6;3247:2;3243:15;3239:24;3236:37;3233:57;;;3286:1;3283;3276:12;3749:186;3808:6;3861:2;3849:9;3840:7;3836:23;3832:32;3829:52;;;3877:1;3874;3867:12;3829:52;3900:29;3919:9;3900:29;:::i;3940:127::-;4001:10;3996:3;3992:20;3989:1;3982:31;4032:4;4029:1;4022:15;4056:4;4053:1;4046:15;4072:718;4114:5;4167:3;4160:4;4152:6;4148:17;4144:27;4134:55;;4185:1;4182;4175:12;4134:55;4221:6;4208:20;4247:18;4284:2;4280;4277:10;4274:36;;;4290:18;;:::i;:::-;4365:2;4359:9;4333:2;4419:13;;-1:-1:-1;;4415:22:22;;;4439:2;4411:31;4407:40;4395:53;;;4463:18;;;4483:22;;;4460:46;4457:72;;;4509:18;;:::i;:::-;4549:10;4545:2;4538:22;4584:2;4576:6;4569:18;4630:3;4623:4;4618:2;4610:6;4606:15;4602:26;4599:35;4596:55;;;4647:1;4644;4637:12;4596:55;4711:2;4704:4;4696:6;4692:17;4685:4;4677:6;4673:17;4660:54;4758:1;4751:4;4746:2;4738:6;4734:15;4730:26;4723:37;4778:6;4769:15;;;;;;4072:718;;;;:::o;4795:456::-;4881:6;4889;4897;4950:2;4938:9;4929:7;4925:23;4921:32;4918:52;;;4966:1;4963;4956:12;4918:52;5002:9;4989:23;4979:33;;5059:2;5048:9;5044:18;5031:32;5021:42;;5114:2;5103:9;5099:18;5086:32;5141:18;5133:6;5130:30;5127:50;;;5173:1;5170;5163:12;5127:50;5196:49;5237:7;5228:6;5217:9;5213:22;5196:49;:::i;:::-;5186:59;;;4795:456;;;;;:::o;5256:462::-;5342:6;5350;5358;5411:2;5399:9;5390:7;5386:23;5382:32;5379:52;;;5427:1;5424;5417:12;5379:52;5450:29;5469:9;5450:29;:::i;:::-;5440:39;;5526:2;5515:9;5511:18;5498:32;5488:42;;5581:2;5570:9;5566:18;5553:32;5608:18;5600:6;5597:30;5594:50;;;5640:1;5637;5630:12;5723:740;5830:6;5838;5846;5899:2;5887:9;5878:7;5874:23;5870:32;5867:52;;;5915:1;5912;5905:12;5867:52;5955:9;5942:23;5984:18;6025:2;6017:6;6014:14;6011:34;;;6041:1;6038;6031:12;6011:34;6064:49;6105:7;6096:6;6085:9;6081:22;6064:49;:::i;:::-;6054:59;;6166:2;6155:9;6151:18;6138:32;6122:48;;6195:2;6185:8;6182:16;6179:36;;;6211:1;6208;6201:12;6179:36;6234:51;6277:7;6266:8;6255:9;6251:24;6234:51;:::i;:::-;6224:61;;6338:2;6327:9;6323:18;6310:32;6294:48;;6367:2;6357:8;6354:16;6351:36;;;6383:1;6380;6373:12;6351:36;;6406:51;6449:7;6438:8;6427:9;6423:24;6406:51;:::i;6468:398::-;6670:2;6652:21;;;6709:2;6689:18;;;6682:30;6748:34;6743:2;6728:18;;6721:62;-1:-1:-1;;;6814:2:22;6799:18;;6792:32;6856:3;6841:19;;6468:398::o;6871:127::-;6932:10;6927:3;6923:20;6920:1;6913:31;6963:4;6960:1;6953:15;6987:4;6984:1;6977:15;7003:127;7064:10;7059:3;7055:20;7052:1;7045:31;7095:4;7092:1;7085:15;7119:4;7116:1;7109:15;7135:175;7172:3;7216:4;7209:5;7205:16;7245:4;7236:7;7233:17;7230:43;;7253:18;;:::i;:::-;7302:1;7289:15;;7135:175;-1:-1:-1;;7135:175:22:o;7315:380::-;7394:1;7390:12;;;;7437;;;7458:61;;7512:4;7504:6;7500:17;7490:27;;7458:61;7565:2;7557:6;7554:14;7534:18;7531:38;7528:161;;7611:10;7606:3;7602:20;7599:1;7592:31;7646:4;7643:1;7636:15;7674:4;7671:1;7664:15;7826:545;7928:2;7923:3;7920:11;7917:448;;;7964:1;7989:5;7985:2;7978:17;8034:4;8030:2;8020:19;8104:2;8092:10;8088:19;8085:1;8081:27;8075:4;8071:38;8140:4;8128:10;8125:20;8122:47;;;-1:-1:-1;8163:4:22;8122:47;8218:2;8213:3;8209:12;8206:1;8202:20;8196:4;8192:31;8182:41;;8273:82;8291:2;8284:5;8281:13;8273:82;;;8336:17;;;8317:1;8306:13;8273:82;;;8277:3;;;7826:545;;;:::o;8547:1206::-;8671:18;8666:3;8663:27;8660:53;;;8693:18;;:::i;:::-;8722:94;8812:3;8772:38;8804:4;8798:11;8772:38;:::i;:::-;8766:4;8722:94;:::i;:::-;8842:1;8867:2;8862:3;8859:11;8884:1;8879:616;;;;9539:1;9556:3;9553:93;;;-1:-1:-1;9612:19:22;;;9599:33;9553:93;-1:-1:-1;;8504:1:22;8500:11;;;8496:24;8492:29;8482:40;8528:1;8524:11;;;8479:57;9659:78;;8852:895;;8879:616;7773:1;7766:14;;;7810:4;7797:18;;-1:-1:-1;;8915:17:22;;;9016:9;9038:229;9052:7;9049:1;9046:14;9038:229;;;9141:19;;;9128:33;9113:49;;9248:4;9233:20;;;;9201:1;9189:14;;;;9068:12;9038:229;;;9042:3;9295;9286:7;9283:16;9280:159;;;9419:1;9415:6;9409:3;9403;9400:1;9396:11;9392:21;9388:34;9384:39;9371:9;9366:3;9362:19;9349:33;9345:79;9337:6;9330:95;9280:159;;;9482:1;9476:3;9473:1;9469:11;9465:19;9459:4;9452:33;8852:895;;8547:1206;;;:::o;10174:340::-;10376:2;10358:21;;;10415:2;10395:18;;;10388:30;-1:-1:-1;;;10449:2:22;10434:18;;10427:46;10505:2;10490:18;;10174:340::o;10519:397::-;10721:2;10703:21;;;10760:2;10740:18;;;10733:30;10799:34;10794:2;10779:18;;10772:62;-1:-1:-1;;;10865:2:22;10850:18;;10843:31;10906:3;10891:19;;10519:397::o;12031:1352::-;12157:3;12151:10;12184:18;12176:6;12173:30;12170:56;;;12206:18;;:::i;:::-;12235:97;12325:6;12285:38;12317:4;12311:11;12285:38;:::i;:::-;12279:4;12235:97;:::i;:::-;12387:4;;12451:2;12440:14;;12468:1;12463:663;;;;13170:1;13187:6;13184:89;;;-1:-1:-1;13239:19:22;;;13233:26;13184:89;-1:-1:-1;;8504:1:22;8500:11;;;8496:24;8492:29;8482:40;8528:1;8524:11;;;8479:57;13286:81;;12433:944;;12463:663;7773:1;7766:14;;;7810:4;7797:18;;-1:-1:-1;;12499:20:22;;;12617:236;12631:7;12628:1;12625:14;12617:236;;;12720:19;;;12714:26;12699:42;;12812:27;;;;12780:1;12768:14;;;;12647:19;;12617:236;;;12621:3;12881:6;12872:7;12869:19;12866:201;;;12942:19;;;12936:26;-1:-1:-1;;13025:1:22;13021:14;;;13037:3;13017:24;13013:37;13009:42;12994:58;12979:74;;12866:201;-1:-1:-1;;;;;13113:1:22;13097:14;;;13093:22;13080:36;;-1:-1:-1;12031:1352:22:o;14003:496::-;14182:3;14220:6;14214:13;14236:66;14295:6;14290:3;14283:4;14275:6;14271:17;14236:66;:::i;:::-;14365:13;;14324:16;;;;14387:70;14365:13;14324:16;14434:4;14422:17;;14387:70;:::i;:::-;14473:20;;14003:496;-1:-1:-1;;;;14003:496:22:o;15548:641::-;15783:3;15821:6;15815:13;15837:66;15896:6;15891:3;15884:4;15876:6;15872:17;15837:66;:::i;:::-;15934:6;15929:3;15925:16;15912:29;;15964:6;15957:5;15950:21;16005:6;15998:4;15991:5;15987:16;15980:32;16043:6;16037:13;16059:79;16129:8;16124:2;16117:5;16113:14;16106:4;16098:6;16094:17;16059:79;:::i;:::-;16158:20;16180:2;16154:29;;15548:641;-1:-1:-1;;;;;;15548:641:22:o;16194:686::-;16429:3;16467:6;16461:13;16483:66;16542:6;16537:3;16530:4;16522:6;16518:17;16483:66;:::i;:::-;16580:6;16575:3;16571:16;16558:29;;16635:26;16631:31;16622:6;16618:2;16614:15;16610:53;16603:5;16596:68;16696:6;16691:2;16684:5;16680:14;16673:30;16734:6;16728:13;16750:79;16820:8;16815:2;16808:5;16804:14;16797:4;16789:6;16785:17;16750:79;:::i;:::-;16849:20;16871:2;16845:29;;16194:686;-1:-1:-1;;;;;;16194:686:22:o;17429:812::-;17840:25;17835:3;17828:38;17810:3;17895:6;17889:13;17911:75;17979:6;17974:2;17969:3;17965:12;17958:4;17950:6;17946:17;17911:75;:::i;:::-;-1:-1:-1;;;18045:2:22;18005:16;;;18037:11;;;18030:40;18095:13;;18117:76;18095:13;18179:2;18171:11;;18164:4;18152:17;;18117:76;:::i;:::-;18213:17;18232:2;18209:26;;17429:812;-1:-1:-1;;;;17429:812:22:o;18954:168::-;19027:9;;;19058;;19075:15;;;19069:22;;19055:37;19045:71;;19096:18;;:::i;19127:125::-;19192:9;;;19213:10;;;19210:36;;;19226:18;;:::i;19257:136::-;19296:3;19324:5;19314:39;;19333:18;;:::i;:::-;-1:-1:-1;;;19369:18:22;;19257:136::o;19759:127::-;19820:10;19815:3;19811:20;19808:1;19801:31;19851:4;19848:1;19841:15;19875:4;19872:1;19865:15;21410:128;21477:9;;;21498:11;;;21495:37;;;21512:18;;:::i;21543:127::-;21604:10;21599:3;21595:20;21592:1;21585:31;21635:4;21632:1;21625:15;21659:4;21656:1;21649:15
Swarm Source
ipfs://ccb105cd4672e1de0db8db459251bfdcc43df83deae14de4ff0fb7375ed3fb16
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.