Overview
APE Balance
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 10 from a total of 10 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Grant Role | 11015555 | 14 hrs ago | IN | 0 APE | 0.00131114 | ||||
Grant Role | 11015514 | 14 hrs ago | IN | 0 APE | 0.00131114 | ||||
Grant Role | 11015494 | 14 hrs ago | IN | 0 APE | 0.00131114 | ||||
Grant Role | 10921553 | 2 days ago | IN | 0 APE | 0.00131086 | ||||
Deploy | 10921239 | 2 days ago | IN | 0 APE | 0.04144632 | ||||
Deploy | 10921238 | 2 days ago | IN | 0 APE | 0.13047291 | ||||
Deploy | 10564535 | 9 days ago | IN | 0 APE | 0.08087368 | ||||
Grant Role | 10564493 | 9 days ago | IN | 0 APE | 0.00131117 | ||||
Grant Role | 10564472 | 9 days ago | IN | 0 APE | 0.00068529 | ||||
Grant Role | 10558111 | 9 days ago | IN | 0 APE | 0.00130141 |
Latest 3 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
10921239 | 2 days ago | Contract Creation | 0 APE | |||
10921238 | 2 days ago | Contract Creation | 0 APE | |||
10564535 | 9 days ago | Contract Creation | 0 APE |
Loading...
Loading
Contract Name:
AppHub
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at apescan.io on 2025-02-25 */ // SPDX-License-Identifier: MIT AND UNLICENSED // // OpenZeppelin and ERC-6956 are licensed under MIT // Note ERC-6956 is authored by us (authenticvision.com) // // All other contracts are UNLICENSED, visit metaanchor.io for licensing information // // Meta Anchor (TM), Authentic Vision (TM) and Digital Soul (TM) are Registered Trademarks // and will be denoted as MetaAnchor, AuthenticVision and DigitalSoul subsequently. // Sources flattened with hardhat v2.12.6 https://hardhat.org // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @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; } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/utils/introspection/[email protected] // 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); } // File @openzeppelin/contracts/utils/introspection/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File @openzeppelin/contracts/utils/math/[email protected] // 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); } } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @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); } } // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @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 AccessControl is Context, IAccessControl, ERC165 { 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(IAccessControl).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 ", Strings.toHexString(account), " is missing role ", Strings.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()); } } } // File @openzeppelin/contracts/utils/introspection/[email protected] // OpenZeppelin Contracts (last updated v4.8.2) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.0; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface. */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. * * _Available since v3.4._ */ function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * * Some precompiled contracts will falsely indicate support for a given interface, so caution * should be exercised when using this function. * * Interface identification is specified in ERC-165. */ function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } } // File contracts/DeployerContract.sol pragma solidity ^0.8.18; /** * @title Interface for contracts featuring cascade-verification of the deployment origination * @author [email protected] * @notice Allows cascade-verification of a deployment origination across multiple DeployerContracts * @dev Contracts implementing this interface must take as the first constructor-parameter the address of the * `DeployerContract` */ interface IDeployedContract { /** * @notice Indicates whether addr has been directly or indirectly deployed by this contract * @dev Indirect deployment means e.g. by deploying through a contract that has been deployed by this contract * * @param addr Address of the deployed contract requesting initArgs * @return hasDeployedAddr abi-encoded init args */ function hasDeployed(address addr) external view returns (bool hasDeployedAddr); /** * Returns the deployer of a particular contract. Can be EOA or Contract Account */ function deployedBy() external view returns (address deployer); } /** * @title Predictable-Deployment contract of origin-verifyable contracts * @author [email protected] * @notice Deploys contracts implementing IDeployedContract based on passed bytecode and constructorArgs and allows to trace their origin * across multiple Deployercontracts * * @dev Has a static deployment salt, which shall only be changed in absolute emergencies. * The root contract is typically deployed by the Nonce=0 of an account on different blockchains. * This ensures that all contracts can be cascade-verified to originate from one well-known and trusted * source, e.g. an AppHub for a company. * */ abstract contract DeployerContract is IDeployedContract { mapping (address => address) private _deployedContractsWithOperator; IDeployedContract[] public deployedContracts; address public deployedBy; bytes32 private _salt; /** * @notice Emits when a contract is deployed through `deploy()` * @param deployedAddress Address of the just deployed contract * @param operator The operator initiating the deployment */ event ContractDeployed(address deployedAddress, address operator); /** * @notice Emits (in emergencies), when salt is updated. * @param newSalt The new salt used for new deployments * @param oldSalt The old salt, has been used for previous deployments * @param maintainer Initiator of the salt update */ event DeploymentSaltUpdate(bytes32 newSalt, bytes32 oldSalt, address maintainer); /** * @notice Indicates whether `addr` can use the `deploy()` function. * @dev To be overwritten by extending contracts, typically by only authorizing a specific role. * @param addr The address in question */ function canDeploy(address addr) public virtual returns (bool); modifier onlyDeployer() { require(canDeploy(msg.sender), "msg.sender must be deployer"); _; } /** * Returns the predicted address (with the current `_salt`) for a provided bytecode and constructorArgs * @param bytecode The bytecode to be deployed * @param constructorArgs abi-encoded constructor args, accepted by the constructor of the contract in bytecode */ function getAddress( bytes memory bytecode, bytes memory constructorArgs ) public view returns (address) { uint actualSalt = uint(_salt); bytes32 hash = keccak256( abi.encodePacked(bytes1(0xff), address(this), actualSalt, keccak256(_assembleByteCodeAndArgs(bytecode, constructorArgs))) ); // NOTE: cast last 20 bytes of hash to address return address(uint160(uint(hash))); } /** * @notice Like `getAddress(bytes,bytes)`, but for constructors not taking additional arguments (additional to deployer address) * @param bytecode Bytecode to be deployed */ function getAddress( bytes memory bytecode ) public view returns (address) { return getAddress(bytecode, abi.encode(address(this))); } /** * @notice Indicates whether a contract at `addr` directly or indirectly has been deployed through this contract * @param addr Address of the contract in question * @dev This function is typically cascade-called from parent DeployerContracts */ function hasDeployed(address addr) public view returns (bool hasDeployedAddr) { if(_deployedContractsWithOperator[addr] != address(0)) { return true; } for(uint i=0; i<deployedContracts.length; i++) { if(deployedContracts[i].hasDeployed(addr)) { return true; } } return false; } /** * @dev Internhal helper to pack bytecode and constructor args. Ensurs the first constructor argument is the deployer, i.e. address(this) * @param byteCode Bytecode excl constructor args * @param constructorArgs ABI-encoded, expected to have the address of this contract encoded as first argument */ function _assembleByteCodeAndArgs(bytes memory byteCode, bytes memory constructorArgs) internal view returns (bytes memory bytecodeWithArgs) { (address deployerAddress) = abi.decode(constructorArgs, (address)); require(deployerAddress == address(this), "First constructor arg must be address of this contract"); return abi.encodePacked(byteCode, constructorArgs); } /** * @notice Deploys bytecode of IDeployedContract-implementing contract with constructor args * @param byteCode Bytecode of contract implementing IDeployedContract * @param constructorArgs ABI-encoded constructor args, first argument must be address of this contract * @dev Emits ContractDeployed * Throws if bytecode does not implement IDeployedContract * Throws if `deployedBy()` of the deployed contract does not indicate this contract as deployer, * hence `hasDeployed()` mechanism would fail */ function deploy(bytes memory byteCode, bytes memory constructorArgs) public onlyDeployer() { // verify first argument of constructorArgs is address(this) address addr = _deployBinary(_assembleByteCodeAndArgs(byteCode, constructorArgs), _salt); // verify the contract implements IDeployedContract require(ERC165Checker.supportsInterface(addr, type(IDeployedContract).interfaceId), "Can only deploy contracts implementing IDeployedContract interface"); // verify contract claims this contract as deployer require(IDeployedContract(addr).deployedBy() == address(this), "Deployed contract must return this contract in getDeployer()"); emit ContractDeployed(addr, msg.sender); _deployedContractsWithOperator[addr] = msg.sender; deployedContracts.push(IDeployedContract(addr)); } /** * @notice Like deploy(bytes,bytes), but adds address(this) as only constructor argument * @param byteCode Bytecode of contract implementing IDeployedContract */ function deploy(bytes memory byteCode) public onlyDeployer() { deploy(byteCode, abi.encode(address(this))); } /** * @notice Updates the deployment salt - do only use in absolut emergencies! * @dev This shall not be used at all and is just for emergencies and major fuckups. As soon * as the salt is updated, it can happen that the same contract / same version / same constructorArgs * can be re-deployed to a different address. */ function updateDeploymentSalt(bytes32 newSalt) public onlyDeployer() { emit DeploymentSaltUpdate(_salt, newSalt, msg.sender); _salt = newSalt; } /** * @param bytecode Bytecode + packed constructorArgs of contract implementing IDeployedContract * @param salt The deployment salt. * @dev Isolated function to actually deploy contracts (can be used by extending contracts) * inspired by https://solidity-by-example.org/app/create2/ * Salt is taken as parameter to also allow deploying contracts with an "old" salt in case of * emergency salt-upgrade. */ function _deployBinary(bytes memory bytecode, bytes32 salt) internal virtual onlyDeployer() returns (address) { address addr; uint actualSalt = uint(salt); /* NOTE: How to call create2 create2(v, p, n, s) create new contract with code at memory p to p + n and send v wei and return the new address where new address = first 20 bytes of keccak256(0xff + address(this) + s + keccak256(mem[p…(p+n))) s = big-endian 256-bit value */ assembly { addr := create2( callvalue(), // wei sent with current call // Actual code starts after skipping the first 32 bytes add(bytecode, 0x20), mload(bytecode), // Load the size of code contained in the first 32 bytes actualSalt // Salt from function arguments ) if iszero(extcodesize(addr)) { revert(0, 0) } } return addr; } constructor() { deployedBy = msg.sender; } } // File contracts/AppHub.sol pragma solidity ^0.8.18; /** * @title AuthenticVision MetaAnchor AppHub * @author [email protected] * @notice Used to manage roles and verify a deployed contract originates directly or indirectly from this AppHub. * @dev This can be seen as the "AuthenticVision root certificate". All contracts deployed by Authentic Vision * will have `hasDeployed(address)==true`. Only these contracts originate from Authentic Vision. * * This AppHub will be deployed at the same address in all Blockchains we support. * * Visit authenticvision.com for contact and further information */ contract AppHub is AccessControl, DeployerContract { /** * @notice DEPLOYER_ROLE can deploy new MetaAnchor-Contracts from MetaAnchorFactory * @return Role hash, as should be passed to hasRole(), grantRole() */ bytes32 public constant DEPLOYER_ROLE = keccak256("DEPLOYER_ROLE"); /** * @notice FACTORY_DEPLOYER_ROLE can deploy factories (via AppHub) */ bytes32 public constant FACTORY_DEPLOYER_ROLE = keccak256("FACTORY_DEPLOYER_ROLE"); /** * @notice FACTORY_MAINTAINER_ROLE can maintain factories, e.g. add providers, remove registrations, .. */ bytes32 public constant FACTORY_MAINTAINER_ROLE = keccak256("FACTORY_MAINTAINER_ROLE"); /** * @notice MAINTAINER_ROLE can maintain MetaAnchor-Contracts, e.g. updateValidAnchors(), configurations, owners, etc. */ bytes32 public constant MAINTAINER_ROLE = keccak256("MAINTAINER_ROLE"); /** * @notice Signatures for ORACLE_ROLE will be accepted for ERC-6956 attestations */ bytes32 public constant ORACLE_ROLE = keccak256("ORACLE_ROLE"); /** * @notice PAUSER_ROLE has permission to pause contracts */ bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); /** * @notice REGISTRAR_ROLE can register (and unregister their own) contracts for deployment */ bytes32 public constant REGISTRAR_ROLE = keccak256("REGISTRAR_ROLE"); /** * @notice Overrides authorization functionality from `DeployerContract` to allow only FACTORY_DEPLOYER_ROLE accounts * @param addr Account address in equestion * @return addrIsDeployer true indicates this account can deploy contracts via `deploy()` method */ function canDeploy(address addr) public view override(DeployerContract) returns (bool addrIsDeployer) { return hasRole(FACTORY_DEPLOYER_ROLE, addr); } constructor() { _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"deployedAddress","type":"address"},{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"ContractDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"newSalt","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"oldSalt","type":"bytes32"},{"indexed":false,"internalType":"address","name":"maintainer","type":"address"}],"name":"DeploymentSaltUpdate","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"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPLOYER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FACTORY_DEPLOYER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FACTORY_MAINTAINER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAINTAINER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTRAR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"canDeploy","outputs":[{"internalType":"bool","name":"addrIsDeployer","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"byteCode","type":"bytes"}],"name":"deploy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"byteCode","type":"bytes"},{"internalType":"bytes","name":"constructorArgs","type":"bytes"}],"name":"deploy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deployedBy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deployedContracts","outputs":[{"internalType":"contract IDeployedContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"bytecode","type":"bytes"},{"internalType":"bytes","name":"constructorArgs","type":"bytes"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"bytecode","type":"bytes"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"address","name":"addr","type":"address"}],"name":"hasDeployed","outputs":[{"internalType":"bool","name":"hasDeployedAddr","type":"bool"}],"stateMutability":"view","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":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"newSalt","type":"bytes32"}],"name":"updateDeploymentSalt","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50600380546001600160a01b0319163390811790915561003290600090610037565b6100d6565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166100d2576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556100913390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6112c6806100e56000396000f3fe608060405234801561001057600080fd5b506004361061011c5760003560e01c80627743601461012157806301ffc9a71461013657806307e2cea51461015e5780631f21cc9114610193578063248a9ca3146101b357806329fe274f146101c65780632f2ff15d146101d957806336568abe146101ec57806344d01fd1146101ff578063569e0d291461022657806360fe0bdf146102395780637c6e42f41461024c57806391d148541461025f5780639ad1ee1014610272578063a217fddf14610285578063bc3ef3c01461028d578063c47cf5de146102a0578063d547741f146102b3578063db9bd42c146102c6578063e63ab1e9146102db578063ecd0026114610302578063f68e955314610329578063f874225414610350575b600080fd5b61013461012f366004610f29565b610377565b005b610149610144366004610f65565b6103d1565b60405190151581526020015b60405180910390f35b6101857f68e79a7bf1e0bc45d0a330c573bc367f9cf464fd326078812f301165fbda4ef181565b604051908152602001610155565b6003546101a6906001600160a01b031681565b6040516101559190610f8f565b6101856101c1366004610fa3565b610408565b6101496101d4366004610fd1565b61041d565b6101346101e7366004610fee565b61050a565b6101346101fa366004610fee565b61052b565b6101857fa4c23fbdf7b47e131467038825c29083fa0078286002513daa4fb6f766a56ca781565b610149610234366004610fd1565b6105a9565b61013461024736600461101e565b6105c3565b6101a661025a36600461101e565b61081f565b61014961026d366004610fee565b6108a3565b6101a6610280366004610fa3565b6108cc565b610185600081565b61013461029b366004610fa3565b6108f6565b6101a66102ae366004610f29565b610961565b6101346102c1366004610fee565b61098c565b61018560008051602061127183398151915281565b6101857f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6101857ffc425f2263d0df187444b70e47283d622c70181c5baebb1306a01edba1ce184c81565b6101857fedcc084d3dcd65a1f7f23c65c46722faca6953d28e43150a467cf43e5c30923881565b6101857f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab9581565b610380336105a9565b6103a55760405162461bcd60e51b815260040161039c90611081565b60405180910390fd5b6103ce81306040516020016103ba9190610f8f565b6040516020818303038152906040526105c3565b50565b60006001600160e01b03198216637965db0b60e01b148061040257506301ffc9a760e01b6001600160e01b03198316145b92915050565b60009081526020819052604090206001015490565b6001600160a01b038181166000908152600160205260408120549091161561044757506001919050565b60005b6002548110156105015760028181548110610467576104676110b6565b6000918252602090912001546040516329fe274f60e01b81526001600160a01b03909116906329fe274f906104a0908690600401610f8f565b602060405180830381865afa1580156104bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e191906110cc565b156104ef5750600192915050565b806104f981611104565b91505061044a565b50600092915050565b61051382610408565b61051c816109a8565b61052683836109b2565b505050565b6001600160a01b038116331461059b5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161039c565b6105a58282610a36565b5050565b6000610402600080516020611271833981519152836108a3565b6105cc336105a9565b6105e85760405162461bcd60e51b815260040161039c90611081565b60006105ff6105f78484610a9b565b600454610b57565b905061061281631b6ff5ef60e11b610ba2565b61068f5760405162461bcd60e51b815260206004820152604260248201527f43616e206f6e6c79206465706c6f7920636f6e74726163747320696d706c656d60448201527f656e74696e6720494465706c6f796564436f6e747261637420696e7465726661606482015261636560f01b608482015260a40161039c565b306001600160a01b0316816001600160a01b0316631f21cc916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fb919061111d565b6001600160a01b0316146107765760405162461bcd60e51b815260206004820152603c60248201527f4465706c6f79656420636f6e7472616374206d7573742072657475726e20746860448201527b697320636f6e747261637420696e206765744465706c6f796572282960201b606482015260840161039c565b604080516001600160a01b03831681523360208201527f33c981baba081f8fd2c52ac6ad1ea95b6814b4376640f55689051f6584729688910160405180910390a16001600160a01b03166000818152600160208190526040822080546001600160a01b031990811633179091556002805492830181559092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01805490911690911790555050565b600454600090816001600160f81b0319308361083b8888610a9b565b805160209182012060405161088295949392016001600160f81b031994909416845260609290921b6001600160601b03191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012095945050505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600281815481106108dc57600080fd5b6000918252602090912001546001600160a01b0316905081565b6108ff336105a9565b61091b5760405162461bcd60e51b815260040161039c90611081565b60045460408051918252602082018390523382820152517fe36534ece9f01369394e4f79bb091d49758b24bb6e6e7b75898659314de34f7b9181900360600190a1600455565b600061040282306040516020016109789190610f8f565b60405160208183030381529060405261081f565b61099582610408565b61099e816109a8565b6105268383610a36565b6103ce8133610bc5565b6109bc82826108a3565b6105a5576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556109f23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b610a4082826108a3565b156105a5576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6060600082806020019051810190610ab3919061111d565b90506001600160a01b0381163014610b2c5760405162461bcd60e51b815260206004820152603660248201527f466972737420636f6e7374727563746f7220617267206d757374206265206164604482015275191c995cdcc81bd9881d1a1a5cc818dbdb9d1c9858dd60521b606482015260840161039c565b8383604051602001610b3f92919061115e565b60405160208183030381529060405291505092915050565b6000610b62336105a9565b610b7e5760405162461bcd60e51b815260040161039c90611081565b8251600090839081906020870134f59150813b610b9a57600080fd5b509392505050565b6000610bad83610c1e565b8015610bbe5750610bbe8383610c51565b9392505050565b610bcf82826108a3565b6105a557610bdc81610cda565b610be7836020610cec565b604051602001610bf892919061118d565b60408051601f198184030181529082905262461bcd60e51b825261039c916004016111fc565b6000610c31826301ffc9a760e01b610c51565b80156104025750610c4a826001600160e01b0319610c51565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d91506000519050828015610cc3575060208210155b8015610ccf5750600081115b979650505050505050565b60606104026001600160a01b03831660145b60606000610cfb83600261122f565b610d06906002611246565b6001600160401b03811115610d1d57610d1d610e87565b6040519080825280601f01601f191660200182016040528015610d47576020820181803683370190505b509050600360fc1b81600081518110610d6257610d626110b6565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610d9157610d916110b6565b60200101906001600160f81b031916908160001a9053506000610db584600261122f565b610dc0906001611246565b90505b6001811115610e38576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110610df457610df46110b6565b1a60f81b828281518110610e0a57610e0a6110b6565b60200101906001600160f81b031916908160001a90535060049490941c93610e3181611259565b9050610dc3565b508315610bbe5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161039c565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610eae57600080fd5b81356001600160401b0380821115610ec857610ec8610e87565b604051601f8301601f19908116603f01168101908282118183101715610ef057610ef0610e87565b81604052838152866020858801011115610f0957600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215610f3b57600080fd5b81356001600160401b03811115610f5157600080fd5b610f5d84828501610e9d565b949350505050565b600060208284031215610f7757600080fd5b81356001600160e01b031981168114610bbe57600080fd5b6001600160a01b0391909116815260200190565b600060208284031215610fb557600080fd5b5035919050565b6001600160a01b03811681146103ce57600080fd5b600060208284031215610fe357600080fd5b8135610bbe81610fbc565b6000806040838503121561100157600080fd5b82359150602083013561101381610fbc565b809150509250929050565b6000806040838503121561103157600080fd5b82356001600160401b038082111561104857600080fd5b61105486838701610e9d565b9350602085013591508082111561106a57600080fd5b5061107785828601610e9d565b9150509250929050565b6020808252601b908201527a36b9b39739b2b73232b91036bab9ba103132903232b83637bcb2b960291b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156110de57600080fd5b81518015158114610bbe57600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611116576111166110ee565b5060010190565b60006020828403121561112f57600080fd5b8151610bbe81610fbc565b60005b8381101561115557818101518382015260200161113d565b50506000910152565b6000835161117081846020880161113a565b83519083019061118481836020880161113a565b01949350505050565b76020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8152600083516111bf81601785016020880161113a565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516111f081602884016020880161113a565b01602801949350505050565b602081526000825180602084015261121b81604085016020870161113a565b601f01601f19169190910160400192915050565b8082028115828204841417610402576104026110ee565b80820180821115610402576104026110ee565b600081611268576112686110ee565b50600019019056fe04c9af967d21e6282dc31b054f3b8130ec8bf568c07df77a8a68591ccb1b1c30a264697066735822122006b37aaca2c5d398b920d9a265ebca2afe0bae1b70c00243fb7b322a9034121d64736f6c63430008120033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061011c5760003560e01c80627743601461012157806301ffc9a71461013657806307e2cea51461015e5780631f21cc9114610193578063248a9ca3146101b357806329fe274f146101c65780632f2ff15d146101d957806336568abe146101ec57806344d01fd1146101ff578063569e0d291461022657806360fe0bdf146102395780637c6e42f41461024c57806391d148541461025f5780639ad1ee1014610272578063a217fddf14610285578063bc3ef3c01461028d578063c47cf5de146102a0578063d547741f146102b3578063db9bd42c146102c6578063e63ab1e9146102db578063ecd0026114610302578063f68e955314610329578063f874225414610350575b600080fd5b61013461012f366004610f29565b610377565b005b610149610144366004610f65565b6103d1565b60405190151581526020015b60405180910390f35b6101857f68e79a7bf1e0bc45d0a330c573bc367f9cf464fd326078812f301165fbda4ef181565b604051908152602001610155565b6003546101a6906001600160a01b031681565b6040516101559190610f8f565b6101856101c1366004610fa3565b610408565b6101496101d4366004610fd1565b61041d565b6101346101e7366004610fee565b61050a565b6101346101fa366004610fee565b61052b565b6101857fa4c23fbdf7b47e131467038825c29083fa0078286002513daa4fb6f766a56ca781565b610149610234366004610fd1565b6105a9565b61013461024736600461101e565b6105c3565b6101a661025a36600461101e565b61081f565b61014961026d366004610fee565b6108a3565b6101a6610280366004610fa3565b6108cc565b610185600081565b61013461029b366004610fa3565b6108f6565b6101a66102ae366004610f29565b610961565b6101346102c1366004610fee565b61098c565b61018560008051602061127183398151915281565b6101857f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b6101857ffc425f2263d0df187444b70e47283d622c70181c5baebb1306a01edba1ce184c81565b6101857fedcc084d3dcd65a1f7f23c65c46722faca6953d28e43150a467cf43e5c30923881565b6101857f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab9581565b610380336105a9565b6103a55760405162461bcd60e51b815260040161039c90611081565b60405180910390fd5b6103ce81306040516020016103ba9190610f8f565b6040516020818303038152906040526105c3565b50565b60006001600160e01b03198216637965db0b60e01b148061040257506301ffc9a760e01b6001600160e01b03198316145b92915050565b60009081526020819052604090206001015490565b6001600160a01b038181166000908152600160205260408120549091161561044757506001919050565b60005b6002548110156105015760028181548110610467576104676110b6565b6000918252602090912001546040516329fe274f60e01b81526001600160a01b03909116906329fe274f906104a0908690600401610f8f565b602060405180830381865afa1580156104bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104e191906110cc565b156104ef5750600192915050565b806104f981611104565b91505061044a565b50600092915050565b61051382610408565b61051c816109a8565b61052683836109b2565b505050565b6001600160a01b038116331461059b5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b606482015260840161039c565b6105a58282610a36565b5050565b6000610402600080516020611271833981519152836108a3565b6105cc336105a9565b6105e85760405162461bcd60e51b815260040161039c90611081565b60006105ff6105f78484610a9b565b600454610b57565b905061061281631b6ff5ef60e11b610ba2565b61068f5760405162461bcd60e51b815260206004820152604260248201527f43616e206f6e6c79206465706c6f7920636f6e74726163747320696d706c656d60448201527f656e74696e6720494465706c6f796564436f6e747261637420696e7465726661606482015261636560f01b608482015260a40161039c565b306001600160a01b0316816001600160a01b0316631f21cc916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fb919061111d565b6001600160a01b0316146107765760405162461bcd60e51b815260206004820152603c60248201527f4465706c6f79656420636f6e7472616374206d7573742072657475726e20746860448201527b697320636f6e747261637420696e206765744465706c6f796572282960201b606482015260840161039c565b604080516001600160a01b03831681523360208201527f33c981baba081f8fd2c52ac6ad1ea95b6814b4376640f55689051f6584729688910160405180910390a16001600160a01b03166000818152600160208190526040822080546001600160a01b031990811633179091556002805492830181559092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace01805490911690911790555050565b600454600090816001600160f81b0319308361083b8888610a9b565b805160209182012060405161088295949392016001600160f81b031994909416845260609290921b6001600160601b03191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012095945050505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600281815481106108dc57600080fd5b6000918252602090912001546001600160a01b0316905081565b6108ff336105a9565b61091b5760405162461bcd60e51b815260040161039c90611081565b60045460408051918252602082018390523382820152517fe36534ece9f01369394e4f79bb091d49758b24bb6e6e7b75898659314de34f7b9181900360600190a1600455565b600061040282306040516020016109789190610f8f565b60405160208183030381529060405261081f565b61099582610408565b61099e816109a8565b6105268383610a36565b6103ce8133610bc5565b6109bc82826108a3565b6105a5576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556109f23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b610a4082826108a3565b156105a5576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6060600082806020019051810190610ab3919061111d565b90506001600160a01b0381163014610b2c5760405162461bcd60e51b815260206004820152603660248201527f466972737420636f6e7374727563746f7220617267206d757374206265206164604482015275191c995cdcc81bd9881d1a1a5cc818dbdb9d1c9858dd60521b606482015260840161039c565b8383604051602001610b3f92919061115e565b60405160208183030381529060405291505092915050565b6000610b62336105a9565b610b7e5760405162461bcd60e51b815260040161039c90611081565b8251600090839081906020870134f59150813b610b9a57600080fd5b509392505050565b6000610bad83610c1e565b8015610bbe5750610bbe8383610c51565b9392505050565b610bcf82826108a3565b6105a557610bdc81610cda565b610be7836020610cec565b604051602001610bf892919061118d565b60408051601f198184030181529082905262461bcd60e51b825261039c916004016111fc565b6000610c31826301ffc9a760e01b610c51565b80156104025750610c4a826001600160e01b0319610c51565b1592915050565b604080516001600160e01b03198316602480830191909152825180830390910181526044909101909152602080820180516001600160e01b03166301ffc9a760e01b178152825160009392849283928392918391908a617530fa92503d91506000519050828015610cc3575060208210155b8015610ccf5750600081115b979650505050505050565b60606104026001600160a01b03831660145b60606000610cfb83600261122f565b610d06906002611246565b6001600160401b03811115610d1d57610d1d610e87565b6040519080825280601f01601f191660200182016040528015610d47576020820181803683370190505b509050600360fc1b81600081518110610d6257610d626110b6565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610d9157610d916110b6565b60200101906001600160f81b031916908160001a9053506000610db584600261122f565b610dc0906001611246565b90505b6001811115610e38576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110610df457610df46110b6565b1a60f81b828281518110610e0a57610e0a6110b6565b60200101906001600160f81b031916908160001a90535060049490941c93610e3181611259565b9050610dc3565b508315610bbe5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161039c565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610eae57600080fd5b81356001600160401b0380821115610ec857610ec8610e87565b604051601f8301601f19908116603f01168101908282118183101715610ef057610ef0610e87565b81604052838152866020858801011115610f0957600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215610f3b57600080fd5b81356001600160401b03811115610f5157600080fd5b610f5d84828501610e9d565b949350505050565b600060208284031215610f7757600080fd5b81356001600160e01b031981168114610bbe57600080fd5b6001600160a01b0391909116815260200190565b600060208284031215610fb557600080fd5b5035919050565b6001600160a01b03811681146103ce57600080fd5b600060208284031215610fe357600080fd5b8135610bbe81610fbc565b6000806040838503121561100157600080fd5b82359150602083013561101381610fbc565b809150509250929050565b6000806040838503121561103157600080fd5b82356001600160401b038082111561104857600080fd5b61105486838701610e9d565b9350602085013591508082111561106a57600080fd5b5061107785828601610e9d565b9150509250929050565b6020808252601b908201527a36b9b39739b2b73232b91036bab9ba103132903232b83637bcb2b960291b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156110de57600080fd5b81518015158114610bbe57600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611116576111166110ee565b5060010190565b60006020828403121561112f57600080fd5b8151610bbe81610fbc565b60005b8381101561115557818101518382015260200161113d565b50506000910152565b6000835161117081846020880161113a565b83519083019061118481836020880161113a565b01949350505050565b76020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8152600083516111bf81601785016020880161113a565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516111f081602884016020880161113a565b01602801949350505050565b602081526000825180602084015261121b81604085016020870161113a565b601f01601f19169190910160400192915050565b8082028115828204841417610402576104026110ee565b80820180821115610402576104026110ee565b600081611268576112686110ee565b50600019019056fe04c9af967d21e6282dc31b054f3b8130ec8bf568c07df77a8a68591ccb1b1c30a264697066735822122006b37aaca2c5d398b920d9a265ebca2afe0bae1b70c00243fb7b322a9034121d64736f6c63430008120033
Deployed Bytecode Sourcemap
45329:1917:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42390:131;;;;;;:::i;:::-;;:::i;:::-;;24208:204;;;;;;:::i;:::-;;:::i;:::-;;;1650:14:1;;1643:22;1625:41;;1613:2;1598:18;24208:204:0;;;;;;;;46331:62;;46369:24;46331:62;;;;;1823:25:1;;;1811:2;1796:18;46331:62:0;1677:177:1;37059:25:0;;;;;-1:-1:-1;;;;;37059:25:0;;;;;;;;;;:::i;26031:131::-;;;;;;:::i;:::-;;:::i;39621:388::-;;;;;;:::i;:::-;;:::i;26472:147::-;;;;;;:::i;:::-;;:::i;27616:218::-;;;;;;:::i;:::-;;:::i;45928:86::-;;45978:36;45928:86;;47008:158;;;;;;:::i;:::-;;:::i;41329:865::-;;;;;;:::i;:::-;;:::i;38504:462::-;;;;;;:::i;:::-;;:::i;24504:147::-;;;;;;:::i;:::-;;:::i;37006:44::-;;;;;;:::i;:::-;;:::i;23609:49::-;;23654:4;23609:49;;42896:168;;;;;;:::i;:::-;;:::i;39174:162::-;;;;;;:::i;:::-;;:::i;26912:149::-;;;;;;:::i;:::-;;:::i;45718:82::-;;-1:-1:-1;;;;;;;;;;;45718:82:0;;46474:62;;46512:24;46474:62;;45559:66;;45599:26;45559:66;;46651:68;;46692:27;46651:68;;46156:70;;46198:28;46156:70;;42390:131;38127:21;38137:10;38127:9;:21::i;:::-;38119:61;;;;-1:-1:-1;;;38119:61:0;;;;;;;:::i;:::-;;;;;;;;;42462:43:::1;42469:8;42498:4;42479:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;42462:6;:43::i;:::-;42390:131:::0;:::o;24208:204::-;24293:4;-1:-1:-1;;;;;;24317:47:0;;-1:-1:-1;;;24317:47:0;;:87;;-1:-1:-1;;;;;;;;;;6357:40:0;;;24368:36;24310:94;24208:204;-1:-1:-1;;24208:204:0:o;26031:131::-;26105:7;26132:12;;;;;;;;;;:22;;;;26031:131::o;39621:388::-;-1:-1:-1;;;;;39713:36:0;;;39677:20;39713:36;;;:30;:36;;;;;;39677:20;;39713:36;:50;39710:93;;-1:-1:-1;39787:4:0;;39621:388;-1:-1:-1;39621:388:0:o;39710:93::-;39819:6;39815:162;39831:17;:24;39829:26;;39815:162;;;39880:17;39898:1;39880:20;;;;;;;;:::i;:::-;;;;;;;;;;;:38;;-1:-1:-1;;;39880:38:0;;-1:-1:-1;;;;;39880:20:0;;;;:32;;:38;;39913:4;;39880:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39877:89;;;-1:-1:-1;39946:4:0;;39621:388;-1:-1:-1;;39621:388:0:o;39877:89::-;39857:3;;;;:::i;:::-;;;;39815:162;;;-1:-1:-1;39996:5:0;;39621:388;-1:-1:-1;;39621:388:0:o;26472:147::-;26555:18;26568:4;26555:12;:18::i;:::-;24100:16;24111:4;24100:10;:16::i;:::-;26586:25:::1;26597:4;26603:7;26586:10;:25::i;:::-;26472:147:::0;;;:::o;27616:218::-;-1:-1:-1;;;;;27712:23:0;;4318:10;27712:23;27704:83;;;;-1:-1:-1;;;27704:83:0;;5167:2:1;27704:83:0;;;5149:21:1;5206:2;5186:18;;;5179:30;5245:34;5225:18;;;5218:62;-1:-1:-1;;;5296:18:1;;;5289:45;5351:19;;27704:83:0;4965:411:1;27704:83:0;27800:26;27812:4;27818:7;27800:11;:26::i;:::-;27616:218;;:::o;47008:158::-;47089:19;47124:36;-1:-1:-1;;;;;;;;;;;47155:4:0;47124:7;:36::i;41329:865::-;38127:21;38137:10;38127:9;:21::i;:::-;38119:61;;;;-1:-1:-1;;;38119:61:0;;;;;;;:::i;:::-;41501:12:::1;41516:73;41530:51;41555:8;41565:15;41530:24;:51::i;:::-;41583:5;;41516:13;:73::i;:::-;41501:88;;41671:74;41703:4;-1:-1:-1::0;;;41671:31:0::1;:74::i;:::-;41663:153;;;::::0;-1:-1:-1;;;41663:153:0;;5583:2:1;41663:153:0::1;::::0;::::1;5565:21:1::0;5622:2;5602:18;;;5595:30;5661:34;5641:18;;;5634:62;5732:34;5712:18;;;5705:62;-1:-1:-1;;;5783:19:1;;;5776:33;5826:19;;41663:153:0::1;5381:470:1::0;41663:153:0::1;41946:4;-1:-1:-1::0;;;;;41898:53:0::1;41916:4;-1:-1:-1::0;;;;;41898:34:0::1;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;41898:53:0::1;;41890:126;;;::::0;-1:-1:-1;;;41890:126:0;;6314:2:1;41890:126:0::1;::::0;::::1;6296:21:1::0;6353:2;6333:18;;;6326:30;6392:34;6372:18;;;6365:62;-1:-1:-1;;;6443:18:1;;;6436:58;6511:19;;41890:126:0::1;6112:424:1::0;41890:126:0::1;42034:34;::::0;;-1:-1:-1;;;;;6771:15:1;;6753:34;;42057:10:0::1;6818:2:1::0;6803:18;;6796:43;42034:34:0::1;::::0;6688:18:1;42034:34:0::1;;;;;;;-1:-1:-1::0;;;;;42079:36:0::1;;::::0;;;:30:::1;:36;::::0;;;;;;:49;;-1:-1:-1;;;;;;42079:49:0;;::::1;42118:10;42079:49;::::0;;;42139:17:::1;:47:::0;;;;::::1;::::0;;;;;;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;41329:865:0:o;38504:462::-;38666:5;;38623:7;;;-1:-1:-1;;;;;;38761:4:0;38666:5;38790:51;38815:8;38825:15;38790:24;:51::i;:::-;38780:62;;;;;;;38722:121;;;;;;;;-1:-1:-1;;;;;;7073:26:1;;;;7061:39;;7162:2;7133:15;;;;-1:-1:-1;;;;;;7129:45:1;7170:1;7116:11;;7109:66;7200:2;7191:12;;7184:28;7237:2;7228:12;;7221:28;7274:2;7265:12;;6850:433;38722:121:0;;;;;;;-1:-1:-1;;38722:121:0;;;;;;38698:156;;38722:121;38698:156;;;;;38504:462;-1:-1:-1;;;;;38504:462:0:o;24504:147::-;24590:4;24614:12;;;;;;;;;;;-1:-1:-1;;;;;24614:29:0;;;;;;;;;;;;;;;24504:147::o;37006:44::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37006:44:0;;-1:-1:-1;37006:44:0;:::o;42896:168::-;38127:21;38137:10;38127:9;:21::i;:::-;38119:61;;;;-1:-1:-1;;;38119:61:0;;;;;;;:::i;:::-;43003:5:::1;::::0;42982:48:::1;::::0;;7490:25:1;;;7546:2;7531:18;;7524:34;;;43019:10:0::1;7574:18:1::0;;;7567:60;42982:48:0;::::1;::::0;;;;7478:2:1;42982:48:0;;::::1;43041:5;:15:::0;42896:168::o;39174:162::-;39254:7;39281:47;39292:8;39321:4;39302:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;39281:10;:47::i;26912:149::-;26996:18;27009:4;26996:12;:18::i;:::-;24100:16;24111:4;24100:10;:16::i;:::-;27027:26:::1;27039:4;27045:7;27027:11;:26::i;24955:105::-:0;25022:30;25033:4;4318:10;25022;:30::i;29213:238::-;29297:22;29305:4;29311:7;29297;:22::i;:::-;29292:152;;29336:6;:12;;;;;;;;;;;-1:-1:-1;;;;;29336:29:0;;;;;;;;;:36;;-1:-1:-1;;29336:36:0;29368:4;29336:36;;;29419:12;4318:10;;4238:98;29419:12;-1:-1:-1;;;;;29392:40:0;29410:7;-1:-1:-1;;;;;29392:40:0;29404:4;29392:40;;;;;;;;;;29213:238;;:::o;29631:239::-;29715:22;29723:4;29729:7;29715;:22::i;:::-;29711:152;;;29786:5;29754:12;;;;;;;;;;;-1:-1:-1;;;;;29754:29:0;;;;;;;;;;:37;;-1:-1:-1;;29754:37:0;;;29811:40;4318:10;;29754:12;;29811:40;;29786:5;29811:40;29631:239;;:::o;40349:397::-;40459:29;40502:23;40540:15;40529:38;;;;;;;;;;;;:::i;:::-;40501:66;-1:-1:-1;;;;;;40586:32:0;;40613:4;40586:32;40578:99;;;;-1:-1:-1;;;40578:99:0;;8104:2:1;40578:99:0;;;8086:21:1;8143:2;8123:18;;;8116:30;8182:34;8162:18;;;8155:62;-1:-1:-1;;;8233:18:1;;;8226:52;8295:19;;40578:99:0;7902:418:1;40578:99:0;40712:8;40722:15;40695:43;;;;;;;;;:::i;:::-;;;;;;;;;;;;;40688:50;;;40349:397;;;;:::o;43540:1059::-;43641:7;38127:21;38137:10;38127:9;:21::i;:::-;38119:61;;;;-1:-1:-1;;;38119:61:0;;;;;;;:::i;:::-;44318:15;;43661:12:::1;::::0;43709:4;;;;44294::::1;44280:19:::0;::::1;44147:11;44121:345;44113:353;;44504:4;44492:17;44482:75;;44540:1;44537::::0;44530:12:::1;44482:75;-1:-1:-1::0;44587:4:0;43540:1059;-1:-1:-1;;;43540:1059:0:o;31285:285::-;31372:4;31481:23;31496:7;31481:14;:23::i;:::-;:81;;;;;31508:54;31541:7;31550:11;31508:32;:54::i;:::-;31474:88;31285:285;-1:-1:-1;;;31285:285:0:o;25350:492::-;25439:22;25447:4;25453:7;25439;:22::i;:::-;25434:401;;25627:28;25647:7;25627:19;:28::i;:::-;25728:38;25756:4;25763:2;25728:19;:38::i;:::-;25532:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;25532:257:0;;;;;;;;;;-1:-1:-1;;;25478:345:0;;;;;;;:::i;30626:433::-;30690:4;30901:68;30934:7;-1:-1:-1;;;30901:32:0;:68::i;:::-;:150;;;;-1:-1:-1;30987:64:0;31020:7;-1:-1:-1;;;;;;30987:32:0;:64::i;:::-;30986:65;30881:170;30626:433;-1:-1:-1;;30626:433:0:o;34438:662::-;34611:71;;;-1:-1:-1;;;;;;10457:33:1;;34611:71:0;;;;10439:52:1;;;;34611:71:0;;;;;;;;;;10412:18:1;;;;34611:71:0;;;;;;;;;-1:-1:-1;;;;;34611:71:0;-1:-1:-1;;;34611:71:0;;;34897:20;;34540:4;;34611:71;34540:4;;;;;;34611:71;34540:4;;34897:20;34862:7;34855:5;34844:86;34833:97;;34958:16;34944:30;;35009:4;35003:11;34988:26;;35044:7;:29;;;;;35069:4;35055:10;:18;;35044:29;:48;;;;;35091:1;35077:11;:15;35044:48;35037:55;34438:662;-1:-1:-1;;;;;;;34438:662:0:o;21467:151::-;21525:13;21558:52;-1:-1:-1;;;;;21570:22:0;;19622:2;20863:447;20938:13;20964:19;20996:10;21000:6;20996:1;:10;:::i;:::-;:14;;21009:1;20996:14;:::i;:::-;-1:-1:-1;;;;;20986:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20986:25:0;;20964:47;;-1:-1:-1;;;21022:6:0;21029:1;21022:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;21022:15:0;;;;;;;;;-1:-1:-1;;;21048:6:0;21055:1;21048:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;21048:15:0;;;;;;;;-1:-1:-1;21079:9:0;21091:10;21095:6;21091:1;:10;:::i;:::-;:14;;21104:1;21091:14;:::i;:::-;21079:26;;21074:131;21111:1;21107;:5;21074:131;;;-1:-1:-1;;;21155:5:0;21163:3;21155:11;21146:21;;;;;;;:::i;:::-;;;;21134:6;21141:1;21134:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;21134:33:0;;;;;;;;-1:-1:-1;21192:1:0;21182:11;;;;;21114:3;;;:::i;:::-;;;21074:131;;;-1:-1:-1;21223:10:0;;21215:55;;;;-1:-1:-1;;;21215:55:0;;11148:2:1;21215:55:0;;;11130:21:1;;;11167:18;;;11160:30;11226:34;11206:18;;;11199:62;11278:18;;21215:55:0;10946:356:1;14:127;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:718;188:5;241:3;234:4;226:6;222:17;218:27;208:55;;259:1;256;249:12;208:55;282:20;;-1:-1:-1;;;;;351:10:1;;;348:36;;;364:18;;:::i;:::-;439:2;433:9;407:2;493:13;;-1:-1:-1;;489:22:1;;;513:2;485:31;481:40;469:53;;;537:18;;;557:22;;;534:46;531:72;;;583:18;;:::i;:::-;623:10;619:2;612:22;658:2;650:6;643:18;704:3;697:4;692:2;684:6;680:15;676:26;673:35;670:55;;;721:1;718;711:12;670:55;785:2;778:4;770:6;766:17;759:4;751:6;747:17;734:54;832:1;825:4;820:2;812:6;808:15;804:26;797:37;852:6;843:15;;;;;;146:718;;;;:::o;869:320::-;937:6;990:2;978:9;969:7;965:23;961:32;958:52;;;1006:1;1003;996:12;958:52;1033:23;;-1:-1:-1;;;;;1068:30:1;;1065:50;;;1111:1;1108;1101:12;1065:50;1134:49;1175:7;1166:6;1155:9;1151:22;1134:49;:::i;:::-;1124:59;869:320;-1:-1:-1;;;;869:320:1:o;1194:286::-;1252:6;1305:2;1293:9;1284:7;1280:23;1276:32;1273:52;;;1321:1;1318;1311:12;1273:52;1347:23;;-1:-1:-1;;;;;;1399:32:1;;1389:43;;1379:71;;1446:1;1443;1436:12;1859:203;-1:-1:-1;;;;;2023:32:1;;;;2005:51;;1993:2;1978:18;;1859:203::o;2067:180::-;2126:6;2179:2;2167:9;2158:7;2154:23;2150:32;2147:52;;;2195:1;2192;2185:12;2147:52;-1:-1:-1;2218:23:1;;2067:180;-1:-1:-1;2067:180:1:o;2252:131::-;-1:-1:-1;;;;;2327:31:1;;2317:42;;2307:70;;2373:1;2370;2363:12;2388:247;2447:6;2500:2;2488:9;2479:7;2475:23;2471:32;2468:52;;;2516:1;2513;2506:12;2468:52;2555:9;2542:23;2574:31;2599:5;2574:31;:::i;2640:315::-;2708:6;2716;2769:2;2757:9;2748:7;2744:23;2740:32;2737:52;;;2785:1;2782;2775:12;2737:52;2821:9;2808:23;2798:33;;2881:2;2870:9;2866:18;2853:32;2894:31;2919:5;2894:31;:::i;:::-;2944:5;2934:15;;;2640:315;;;;;:::o;2960:539::-;3046:6;3054;3107:2;3095:9;3086:7;3082:23;3078:32;3075:52;;;3123:1;3120;3113:12;3075:52;3150:23;;-1:-1:-1;;;;;3222:14:1;;;3219:34;;;3249:1;3246;3239:12;3219:34;3272:49;3313:7;3304:6;3293:9;3289:22;3272:49;:::i;:::-;3262:59;;3374:2;3363:9;3359:18;3346:32;3330:48;;3403:2;3393:8;3390:16;3387:36;;;3419:1;3416;3409:12;3387:36;;3442:51;3485:7;3474:8;3463:9;3459:24;3442:51;:::i;:::-;3432:61;;;2960:539;;;;;:::o;3923:351::-;4125:2;4107:21;;;4164:2;4144:18;;;4137:30;-1:-1:-1;;;4198:2:1;4183:18;;4176:57;4265:2;4250:18;;3923:351::o;4279:127::-;4340:10;4335:3;4331:20;4328:1;4321:31;4371:4;4368:1;4361:15;4395:4;4392:1;4385:15;4411:277;4478:6;4531:2;4519:9;4510:7;4506:23;4502:32;4499:52;;;4547:1;4544;4537:12;4499:52;4579:9;4573:16;4632:5;4625:13;4618:21;4611:5;4608:32;4598:60;;4654:1;4651;4644:12;4693:127;4754:10;4749:3;4745:20;4742:1;4735:31;4785:4;4782:1;4775:15;4809:4;4806:1;4799:15;4825:135;4864:3;4885:17;;;4882:43;;4905:18;;:::i;:::-;-1:-1:-1;4952:1:1;4941:13;;4825:135::o;5856:251::-;5926:6;5979:2;5967:9;5958:7;5954:23;5950:32;5947:52;;;5995:1;5992;5985:12;5947:52;6027:9;6021:16;6046:31;6071:5;6046:31;:::i;8325:250::-;8410:1;8420:113;8434:6;8431:1;8428:13;8420:113;;;8510:11;;;8504:18;8491:11;;;8484:39;8456:2;8449:10;8420:113;;;-1:-1:-1;;8567:1:1;8549:16;;8542:27;8325:250::o;8580:492::-;8755:3;8793:6;8787:13;8809:66;8868:6;8863:3;8856:4;8848:6;8844:17;8809:66;:::i;:::-;8938:13;;8897:16;;;;8960:70;8938:13;8897:16;9007:4;8995:17;;8960:70;:::i;:::-;9046:20;;8580:492;-1:-1:-1;;;;8580:492:1:o;9077:812::-;-1:-1:-1;;;9483:3:1;9476:38;9458:3;9543:6;9537:13;9559:75;9627:6;9622:2;9617:3;9613:12;9606:4;9598:6;9594:17;9559:75;:::i;:::-;-1:-1:-1;;;9693:2:1;9653:16;;;9685:11;;;9678:40;9743:13;;9765:76;9743:13;9827:2;9819:11;;9812:4;9800:17;;9765:76;:::i;:::-;9861:17;9880:2;9857:26;;9077:812;-1:-1:-1;;;;9077:812:1:o;9894:396::-;10043:2;10032:9;10025:21;10006:4;10075:6;10069:13;10118:6;10113:2;10102:9;10098:18;10091:34;10134:79;10206:6;10201:2;10190:9;10186:18;10181:2;10173:6;10169:15;10134:79;:::i;:::-;10274:2;10253:15;-1:-1:-1;;10249:29:1;10234:45;;;;10281:2;10230:54;;9894:396;-1:-1:-1;;9894:396:1:o;10502:168::-;10575:9;;;10606;;10623:15;;;10617:22;;10603:37;10593:71;;10644:18;;:::i;10675:125::-;10740:9;;;10761:10;;;10758:36;;;10774:18;;:::i;10805:136::-;10844:3;10872:5;10862:39;;10881:18;;:::i;:::-;-1:-1:-1;;;10917:18:1;;10805:136::o
Swarm Source
ipfs://06b37aaca2c5d398b920d9a265ebca2afe0bae1b70c00243fb7b322a9034121d
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.