Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 535 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Submit Attestati... | 6714324 | 19 mins ago | IN | 0 ETH | 0.00102181 | ||||
Submit Attestati... | 6714157 | 1 hr ago | IN | 0 ETH | 0.00117649 | ||||
Submit Attestati... | 6714077 | 1 hr ago | IN | 0 ETH | 0.00141117 | ||||
Submit Attestati... | 6713927 | 1 hr ago | IN | 0 ETH | 0.00096936 | ||||
Submit Attestati... | 6713817 | 2 hrs ago | IN | 0 ETH | 0.00069687 | ||||
Submit Attestati... | 6713098 | 5 hrs ago | IN | 0 ETH | 0.00078733 | ||||
Submit Attestati... | 6713033 | 5 hrs ago | IN | 0 ETH | 0.00035082 | ||||
Submit Attestati... | 6712917 | 5 hrs ago | IN | 0 ETH | 0.00031588 | ||||
Submit Attestati... | 6712865 | 6 hrs ago | IN | 0 ETH | 0.00028156 | ||||
Submit Attestati... | 6712651 | 7 hrs ago | IN | 0 ETH | 0.00028862 | ||||
Submit Attestati... | 6712552 | 7 hrs ago | IN | 0 ETH | 0.00029993 | ||||
Submit Attestati... | 6712507 | 7 hrs ago | IN | 0 ETH | 0.00034268 | ||||
Submit Attestati... | 6712126 | 9 hrs ago | IN | 0 ETH | 0.00056395 | ||||
Submit Attestati... | 6712116 | 9 hrs ago | IN | 0 ETH | 0.00041177 | ||||
Submit Attestati... | 6712076 | 9 hrs ago | IN | 0 ETH | 0.0003031 | ||||
Submit Attestati... | 6712060 | 9 hrs ago | IN | 0 ETH | 0.00028335 | ||||
Submit Attestati... | 6712046 | 9 hrs ago | IN | 0 ETH | 0.00029104 | ||||
Submit Attestati... | 6712040 | 9 hrs ago | IN | 0 ETH | 0.00029656 | ||||
Submit Attestati... | 6711659 | 11 hrs ago | IN | 0 ETH | 0.00029933 | ||||
Submit Attestati... | 6711565 | 11 hrs ago | IN | 0 ETH | 0.00033301 | ||||
Submit Attestati... | 6711552 | 11 hrs ago | IN | 0 ETH | 0.00027744 | ||||
Submit Attestati... | 6711464 | 11 hrs ago | IN | 0 ETH | 0.00034383 | ||||
Submit Attestati... | 6711333 | 12 hrs ago | IN | 0 ETH | 0.00068073 | ||||
Submit Attestati... | 6711322 | 12 hrs ago | IN | 0 ETH | 0.00058163 | ||||
Submit Attestati... | 6711311 | 12 hrs ago | IN | 0 ETH | 0.00061524 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
ZkVerifyAttestation
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-08-26 */ // Sources flattened with hardhat v2.22.5 https://hardhat.org // SPDX-License-Identifier: AGPL-3.0 AND Apache-2.0 AND MIT // File @openzeppelin/contracts/access/[email protected] // Original license: 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 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] // Original license: SPDX_License_Identifier: MIT // 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] // Original license: 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); } // File @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // 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] // Original license: 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); } } } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // 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] // Original license: SPDX_License_Identifier: MIT // 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 contracts/interfaces/IZkVerifyAttestation.sol // Original license: SPDX_License_Identifier: AGPL-3.0 pragma solidity ^0.8.20; /** * @dev Define interface Horizen verifier */ interface IZkVerifyAttestation { function submitAttestation( uint256 _attestationId, bytes32 _proofsAttestation) external; function submitAttestationBatch( uint256[] calldata _attestationIds, bytes32[] calldata _proofsAttestation) external; function verifyProofAttestation( uint256 _attestationId, bytes32 _leaf, bytes32[] calldata _merklePath, uint256 _leafCount, uint256 _index) external returns (bool); } // File contracts/lib/Merkle.sol // Original license: SPDX_License_Identifier: Apache-2.0 // Adapted from Substrate's binary_merkle_tree (last updated v 15.0.0) (https://docs.rs/binary-merkle-tree/latest/binary_merkle_tree/) pragma solidity ^0.8.0; /** * @dev This function deals with verification of Merkle Tree proofs * Specifically for Substrate's binary-merkle-tree v15.0.0 */ library Merkle { /// @notice Guard error for empty proofs error IndexOutOfBounds(); function verifyProofKeccak( bytes32 root, bytes32[] calldata proof, uint256 numberOfLeaves, uint256 leafIndex, bytes32 leaf ) internal pure returns (bool) { if (leafIndex >= numberOfLeaves) { revert IndexOutOfBounds(); } bytes32 computedHash = keccak256(abi.encodePacked(leaf)); uint256 position = leafIndex; uint256 width = numberOfLeaves; uint256 limit = proof.length; for (uint256 i; i < limit;) { bytes32 proofElement = proof[i]; if (position % 2 == 1 || position + 1 == width) { computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); } else { computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); } position /= 2; width = (width - 1) / 2 + 1; unchecked { ++i; } } return computedHash == root; } } // File contracts/ZkVerifyAttestation.sol // Original license: SPDX_License_Identifier: Apache-2.0 pragma solidity 0.8.20; /** * @title ZkVerifyAttestation Contract * @notice It allows submitting and verifying attestation proofs coming from zkVerify chain. */ contract ZkVerifyAttestation is IZkVerifyAttestation, AccessControl { /// @dev Role required for operator to submit/verify proofs. bytes32 public constant OPERATOR = keccak256("OPERATOR"); /// @notice Latest valid attestationId for bridge events. uint256 public latestAttestationId; /// @notice Mapping of MC attestationIds to proofsAttestations. mapping(uint256 => bytes32) public proofsAttestations; bool public isEnforcingSequentialAttestations; /// @notice Emitted when a new attestation is posted. /// @param _attestationId Event attestationId. /// @param _proofsAttestation Aggregated proofs attestation. event AttestationPosted(uint256 indexed _attestationId, bytes32 indexed _proofsAttestation); /// @notice Posted _attestationId must be sequential. error InvalidAttestation(); /// @notice Batch submissions must have an equal number of ids to proof attestations. error InvalidBatchCounts(); /// @notice Prevent owner from handing over ownership error OwnerCannotRenounce(); /** * @notice Construct a new NewHorizenProofVerifier contract * @param _operator Operator for the contract */ constructor( address _operator ) { _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); // it is used as owner _grantRole(OPERATOR, _operator); } /** * @notice Submit Attestation for a monotonically increasing attestationId * @param _attestationId the id of the attestation from the NewHorizen Relayer * @param _proofsAttestation attestation of a set of proofs * @dev caller must have the OPERATOR role, admin can add caller via AccessControl.grantRole() */ function submitAttestation( uint256 _attestationId, bytes32 _proofsAttestation ) external onlyRole(OPERATOR) { // Optionally, check that the new _attestationId is sequential. if(isEnforcingSequentialAttestations && (_attestationId != latestAttestationId + 1)) { revert InvalidAttestation(); } latestAttestationId = _attestationId; proofsAttestations[_attestationId] = _proofsAttestation; emit AttestationPosted(_attestationId, _proofsAttestation); } /** * @notice Submit a Batch of attestations, useful if a relayer needs to catch up. * @param _attestationIds ids of attestations from the NewHorizen Relayer * @param _proofsAttestation a set of proofs * @dev caller must have the OPERATOR role, admin can add caller via AccessControl.grantRole() */ function submitAttestationBatch( uint256[] calldata _attestationIds, bytes32[] calldata _proofsAttestation ) external onlyRole(OPERATOR) { if(_attestationIds.length != _proofsAttestation.length) { revert InvalidBatchCounts(); } uint256 limit = _attestationIds.length; uint256 sequence = latestAttestationId; // Optionally, check that all new _attestationIds are sequential. if(isEnforcingSequentialAttestations) { for (uint256 i; i < limit;) { if (_attestationIds[i] != sequence + (i + 1)) { revert InvalidAttestation(); } unchecked { ++i; } } } for (uint256 i; i < limit;) { proofsAttestations[_attestationIds[i]] = _proofsAttestation[i]; emit AttestationPosted(_attestationIds[i], _proofsAttestation[i]); unchecked { ++i; } } latestAttestationId = _attestationIds[_attestationIds.length - 1]; } /** * @notice Verify a proof against a stored merkle tree * @param _attestationId the id of the attestation from the Horizen main chain * @param _leaf of the merkle tree * @param _merklePath path from leaf to root of the merkle tree * @param _leafCount the number of leaves in the merkle tree * @param _index the 0 indexed `index`'th leaf from the bottom left of the tree, see test cases. * @dev caller must have the OPERATOR role, admin can add caller via AccessControl.grantRole() */ function verifyProofAttestation( uint256 _attestationId, bytes32 _leaf, bytes32[] calldata _merklePath, uint256 _leafCount, uint256 _index ) external view returns (bool) { // AttestationId must have already been posted. if (_attestationId > latestAttestationId) { return false; } // Load the proofsAttestations at the given index from storage. bytes32 proofsAttestation = proofsAttestations[_attestationId]; // Verify the proofsAttestations/path. return Merkle.verifyProofKeccak(proofsAttestation, _merklePath, _leafCount, _index, _leaf); } /** * @notice Flip sequential enforcement for submitAttestation() * @dev caller must have the OPERATOR role */ function flipIsEnforcingSequentialAttestations() external onlyRole(OPERATOR) { isEnforcingSequentialAttestations = !isEnforcingSequentialAttestations; } /** * @notice prohibits owner to renounce its role with this override */ function renounceRole(bytes32 role, address account) public override { if(role == DEFAULT_ADMIN_ROLE) { revert OwnerCannotRenounce(); } super.renounceRole(role, account); } }
[{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"IndexOutOfBounds","type":"error"},{"inputs":[],"name":"InvalidAttestation","type":"error"},{"inputs":[],"name":"InvalidBatchCounts","type":"error"},{"inputs":[],"name":"OwnerCannotRenounce","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_attestationId","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"_proofsAttestation","type":"bytes32"}],"name":"AttestationPosted","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":"OPERATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipIsEnforcingSequentialAttestations","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":[],"name":"isEnforcingSequentialAttestations","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAttestationId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proofsAttestations","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"uint256","name":"_attestationId","type":"uint256"},{"internalType":"bytes32","name":"_proofsAttestation","type":"bytes32"}],"name":"submitAttestation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_attestationIds","type":"uint256[]"},{"internalType":"bytes32[]","name":"_proofsAttestation","type":"bytes32[]"}],"name":"submitAttestationBatch","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":"uint256","name":"_attestationId","type":"uint256"},{"internalType":"bytes32","name":"_leaf","type":"bytes32"},{"internalType":"bytes32[]","name":"_merklePath","type":"bytes32[]"},{"internalType":"uint256","name":"_leafCount","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"verifyProofAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50604051610f72380380610f7283398101604081905261002f91610109565b61003a60003361006a565b6100647f523a704056dcd17bcf83bed8b68c59416dac1119be77755efe3bde0a64e46e0c8261006a565b50610139565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610105576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556100c43390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60006020828403121561011b57600080fd5b81516001600160a01b038116811461013257600080fd5b9392505050565b610e2a806101486000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806391d1485411610097578063bd93187c11610066578063bd93187c146101fa578063d547741f14610207578063ddea78861461021a578063e0fec29a1461022d57600080fd5b806391d14854146101aa578063983d2737146101bd578063a217fddf146101d2578063b99047df146101da57600080fd5b806336568abe116100d357806336568abe14610168578063560f3ba41461017b57806357ae920d146101845780636736ec951461019757600080fd5b806301ffc9a7146100fa578063248a9ca3146101225780632f2ff15d14610153575b600080fd5b61010d610108366004610a76565b610235565b60405190151581526020015b60405180910390f35b610145610130366004610aa0565b60009081526020819052604090206001015490565b604051908152602001610119565b610166610161366004610ab9565b61026c565b005b610166610176366004610ab9565b610296565b61014560015481565b610166610192366004610b41565b6102c2565b6101666101a5366004610bad565b610457565b61010d6101b8366004610ab9565b6104f0565b610145600080516020610dd583398151915281565b610145600081565b6101456101e8366004610aa0565b60026020526000908152604090205481565b60035461010d9060ff1681565b610166610215366004610ab9565b610519565b61010d610228366004610bcf565b61053e565b61016661057d565b60006001600160e01b03198216637965db0b60e01b148061026657506301ffc9a760e01b6001600160e01b03198316145b92915050565b600082815260208190526040902060010154610287816105aa565b61029183836105b7565b505050565b816102b457604051631d88406560e01b815260040160405180910390fd5b6102be828261063b565b5050565b600080516020610dd58339815191526102da816105aa565b8382146102fa576040516373d99d3760e01b815260040160405180910390fd5b60015460035485919060ff161561036c5760005b8281101561036a57610321816001610c4a565b61032b9083610c4a565b88888381811061033d5761033d610c5d565b90506020020135146103625760405163bd8ba84d60e01b815260040160405180910390fd5b60010161030e565b505b60005b828110156104255785858281811061038957610389610c5d565b90506020020135600260008a8a858181106103a6576103a6610c5d565b905060200201358152602001908152602001600020819055508585828181106103d1576103d1610c5d565b905060200201358888838181106103ea576103ea610c5d565b905060200201357fe64e12e2dfd684ae91bf1a6c52fbf2af6986db5927d23f5b643e0d50f7de487860405160405180910390a360010161036f565b508686610433600182610c73565b81811061044257610442610c5d565b60200291909101356001555050505050505050565b600080516020610dd583398151915261046f816105aa565b60035460ff16801561048d57506001805461048991610c4a565b8314155b156104ab5760405163bd8ba84d60e01b815260040160405180910390fd5b600183905560008381526002602052604080822084905551839185917fe64e12e2dfd684ae91bf1a6c52fbf2af6986db5927d23f5b643e0d50f7de48789190a3505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600082815260208190526040902060010154610534816105aa565b61029183836106b6565b600060015487111561055257506000610573565b60008781526002602052604090205461056f81878787878c61071b565b9150505b9695505050505050565b600080516020610dd5833981519152610595816105aa565b506003805460ff19811660ff90911615179055565b6105b48133610868565b50565b6105c182826104f0565b6102be576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556105f73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b03811633146106b05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6102be82825b6106c082826104f0565b156102be576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600083831061073d57604051634e23d03560e01b815260040160405180910390fd5b60008260405160200161075291815260200190565b60408051601f198184030181529190528051602090910120905083858760005b818110156108585760008b8b8381811061078e5761078e610c5d565b9050602002013590506002856107a49190610c9c565b600114806107bb5750836107b9866001610c4a565b145b156107f157604080516020810183905290810187905260600160405160208183030381529060405280519060200120955061081e565b60408051602081018890529081018290526060016040516020818303038152906040528051906020012095505b610829600286610cb0565b94506002610838600186610c73565b6108429190610cb0565b61084d906001610c4a565b935050600101610772565b5050509714979650505050505050565b61087282826104f0565b6102be5761087f816108c1565b61088a8360206108d3565b60405160200161089b929190610ce8565b60408051601f198184030181529082905262461bcd60e51b82526106a791600401610d5d565b60606102666001600160a01b03831660145b606060006108e2836002610d90565b6108ed906002610c4a565b67ffffffffffffffff81111561090557610905610da7565b6040519080825280601f01601f19166020018201604052801561092f576020820181803683370190505b509050600360fc1b8160008151811061094a5761094a610c5d565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061097957610979610c5d565b60200101906001600160f81b031916908160001a905350600061099d846002610d90565b6109a8906001610c4a565b90505b6001811115610a20576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106109dc576109dc610c5d565b1a60f81b8282815181106109f2576109f2610c5d565b60200101906001600160f81b031916908160001a90535060049490941c93610a1981610dbd565b90506109ab565b508315610a6f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106a7565b9392505050565b600060208284031215610a8857600080fd5b81356001600160e01b031981168114610a6f57600080fd5b600060208284031215610ab257600080fd5b5035919050565b60008060408385031215610acc57600080fd5b8235915060208301356001600160a01b0381168114610aea57600080fd5b809150509250929050565b60008083601f840112610b0757600080fd5b50813567ffffffffffffffff811115610b1f57600080fd5b6020830191508360208260051b8501011115610b3a57600080fd5b9250929050565b60008060008060408587031215610b5757600080fd5b843567ffffffffffffffff80821115610b6f57600080fd5b610b7b88838901610af5565b90965094506020870135915080821115610b9457600080fd5b50610ba187828801610af5565b95989497509550505050565b60008060408385031215610bc057600080fd5b50508035926020909101359150565b60008060008060008060a08789031215610be857600080fd5b8635955060208701359450604087013567ffffffffffffffff811115610c0d57600080fd5b610c1989828a01610af5565b979a9699509760608101359660809091013595509350505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561026657610266610c34565b634e487b7160e01b600052603260045260246000fd5b8181038181111561026657610266610c34565b634e487b7160e01b600052601260045260246000fd5b600082610cab57610cab610c86565b500690565b600082610cbf57610cbf610c86565b500490565b60005b83811015610cdf578181015183820152602001610cc7565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351610d20816017850160208801610cc4565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351610d51816028840160208801610cc4565b01602801949350505050565b6020815260008251806020840152610d7c816040850160208701610cc4565b601f01601f19169190910160400192915050565b808202811582820484141761026657610266610c34565b634e487b7160e01b600052604160045260246000fd5b600081610dcc57610dcc610c34565b50600019019056fe523a704056dcd17bcf83bed8b68c59416dac1119be77755efe3bde0a64e46e0ca2646970667358221220a6ce0d3da08ed04e13e6271265f82e0e8abe106960f3e7ae0183c7d963c56ef764736f6c634300081400330000000000000000000000001ffd7c562335d06d5439e40ca3d5c04a708b63a5
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100f55760003560e01c806391d1485411610097578063bd93187c11610066578063bd93187c146101fa578063d547741f14610207578063ddea78861461021a578063e0fec29a1461022d57600080fd5b806391d14854146101aa578063983d2737146101bd578063a217fddf146101d2578063b99047df146101da57600080fd5b806336568abe116100d357806336568abe14610168578063560f3ba41461017b57806357ae920d146101845780636736ec951461019757600080fd5b806301ffc9a7146100fa578063248a9ca3146101225780632f2ff15d14610153575b600080fd5b61010d610108366004610a76565b610235565b60405190151581526020015b60405180910390f35b610145610130366004610aa0565b60009081526020819052604090206001015490565b604051908152602001610119565b610166610161366004610ab9565b61026c565b005b610166610176366004610ab9565b610296565b61014560015481565b610166610192366004610b41565b6102c2565b6101666101a5366004610bad565b610457565b61010d6101b8366004610ab9565b6104f0565b610145600080516020610dd583398151915281565b610145600081565b6101456101e8366004610aa0565b60026020526000908152604090205481565b60035461010d9060ff1681565b610166610215366004610ab9565b610519565b61010d610228366004610bcf565b61053e565b61016661057d565b60006001600160e01b03198216637965db0b60e01b148061026657506301ffc9a760e01b6001600160e01b03198316145b92915050565b600082815260208190526040902060010154610287816105aa565b61029183836105b7565b505050565b816102b457604051631d88406560e01b815260040160405180910390fd5b6102be828261063b565b5050565b600080516020610dd58339815191526102da816105aa565b8382146102fa576040516373d99d3760e01b815260040160405180910390fd5b60015460035485919060ff161561036c5760005b8281101561036a57610321816001610c4a565b61032b9083610c4a565b88888381811061033d5761033d610c5d565b90506020020135146103625760405163bd8ba84d60e01b815260040160405180910390fd5b60010161030e565b505b60005b828110156104255785858281811061038957610389610c5d565b90506020020135600260008a8a858181106103a6576103a6610c5d565b905060200201358152602001908152602001600020819055508585828181106103d1576103d1610c5d565b905060200201358888838181106103ea576103ea610c5d565b905060200201357fe64e12e2dfd684ae91bf1a6c52fbf2af6986db5927d23f5b643e0d50f7de487860405160405180910390a360010161036f565b508686610433600182610c73565b81811061044257610442610c5d565b60200291909101356001555050505050505050565b600080516020610dd583398151915261046f816105aa565b60035460ff16801561048d57506001805461048991610c4a565b8314155b156104ab5760405163bd8ba84d60e01b815260040160405180910390fd5b600183905560008381526002602052604080822084905551839185917fe64e12e2dfd684ae91bf1a6c52fbf2af6986db5927d23f5b643e0d50f7de48789190a3505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600082815260208190526040902060010154610534816105aa565b61029183836106b6565b600060015487111561055257506000610573565b60008781526002602052604090205461056f81878787878c61071b565b9150505b9695505050505050565b600080516020610dd5833981519152610595816105aa565b506003805460ff19811660ff90911615179055565b6105b48133610868565b50565b6105c182826104f0565b6102be576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556105f73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b03811633146106b05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b6102be82825b6106c082826104f0565b156102be576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600083831061073d57604051634e23d03560e01b815260040160405180910390fd5b60008260405160200161075291815260200190565b60408051601f198184030181529190528051602090910120905083858760005b818110156108585760008b8b8381811061078e5761078e610c5d565b9050602002013590506002856107a49190610c9c565b600114806107bb5750836107b9866001610c4a565b145b156107f157604080516020810183905290810187905260600160405160208183030381529060405280519060200120955061081e565b60408051602081018890529081018290526060016040516020818303038152906040528051906020012095505b610829600286610cb0565b94506002610838600186610c73565b6108429190610cb0565b61084d906001610c4a565b935050600101610772565b5050509714979650505050505050565b61087282826104f0565b6102be5761087f816108c1565b61088a8360206108d3565b60405160200161089b929190610ce8565b60408051601f198184030181529082905262461bcd60e51b82526106a791600401610d5d565b60606102666001600160a01b03831660145b606060006108e2836002610d90565b6108ed906002610c4a565b67ffffffffffffffff81111561090557610905610da7565b6040519080825280601f01601f19166020018201604052801561092f576020820181803683370190505b509050600360fc1b8160008151811061094a5761094a610c5d565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061097957610979610c5d565b60200101906001600160f81b031916908160001a905350600061099d846002610d90565b6109a8906001610c4a565b90505b6001811115610a20576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106109dc576109dc610c5d565b1a60f81b8282815181106109f2576109f2610c5d565b60200101906001600160f81b031916908160001a90535060049490941c93610a1981610dbd565b90506109ab565b508315610a6f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106a7565b9392505050565b600060208284031215610a8857600080fd5b81356001600160e01b031981168114610a6f57600080fd5b600060208284031215610ab257600080fd5b5035919050565b60008060408385031215610acc57600080fd5b8235915060208301356001600160a01b0381168114610aea57600080fd5b809150509250929050565b60008083601f840112610b0757600080fd5b50813567ffffffffffffffff811115610b1f57600080fd5b6020830191508360208260051b8501011115610b3a57600080fd5b9250929050565b60008060008060408587031215610b5757600080fd5b843567ffffffffffffffff80821115610b6f57600080fd5b610b7b88838901610af5565b90965094506020870135915080821115610b9457600080fd5b50610ba187828801610af5565b95989497509550505050565b60008060408385031215610bc057600080fd5b50508035926020909101359150565b60008060008060008060a08789031215610be857600080fd5b8635955060208701359450604087013567ffffffffffffffff811115610c0d57600080fd5b610c1989828a01610af5565b979a9699509760608101359660809091013595509350505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561026657610266610c34565b634e487b7160e01b600052603260045260246000fd5b8181038181111561026657610266610c34565b634e487b7160e01b600052601260045260246000fd5b600082610cab57610cab610c86565b500690565b600082610cbf57610cbf610c86565b500490565b60005b83811015610cdf578181015183820152602001610cc7565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351610d20816017850160208801610cc4565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351610d51816028840160208801610cc4565b01602801949350505050565b6020815260008251806020840152610d7c816040850160208701610cc4565b601f01601f19169190910160400192915050565b808202811582820484141761026657610266610c34565b634e487b7160e01b600052604160045260246000fd5b600081610dcc57610dcc610c34565b50600019019056fe523a704056dcd17bcf83bed8b68c59416dac1119be77755efe3bde0a64e46e0ca2646970667358221220a6ce0d3da08ed04e13e6271265f82e0e8abe106960f3e7ae0183c7d963c56ef764736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001ffd7c562335d06d5439e40ca3d5c04a708b63a5
-----Decoded View---------------
Arg [0] : _operator (address): 0x1fFD7C562335D06D5439E40Ca3d5c04a708B63A5
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000001ffd7c562335d06d5439e40ca3d5c04a708b63a5
Deployed Bytecode Sourcemap
32409:5436:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24175:204;;;;;;:::i;:::-;;:::i;:::-;;;470:14:1;;463:22;445:41;;433:2;418:18;24175:204:0;;;;;;;;25998:131;;;;;;:::i;:::-;26072:7;26099:12;;;;;;;;;;:22;;;;25998:131;;;;828:25:1;;;816:2;801:18;25998:131:0;682:177:1;26439:147:0;;;;;;:::i;:::-;;:::i;:::-;;37635:207;;;;;;:::i;:::-;;:::i;32676:34::-;;;;;;34989:1067;;;;;;:::i;:::-;;:::i;34125:529::-;;;;;;:::i;:::-;;:::i;24471:147::-;;;;;;:::i;:::-;;:::i;32550:56::-;;-1:-1:-1;;;;;;;;;;;32550:56:0;;23576:49;;23621:4;23576:49;;32786:53;;;;;;:::i;:::-;;;;;;;;;;;;;;32847:45;;;;;;;;;26879:149;;;;;;:::i;:::-;;:::i;36593:648::-;;;;;;:::i;:::-;;:::i;37378:163::-;;;:::i;24175:204::-;24260:4;-1:-1:-1;;;;;;24284:47:0;;-1:-1:-1;;;24284:47:0;;:87;;-1:-1:-1;;;;;;;;;;6177:40:0;;;24335:36;24277:94;24175:204;-1:-1:-1;;24175:204:0:o;26439:147::-;26072:7;26099:12;;;;;;;;;;:22;;;24067:16;24078:4;24067:10;:16::i;:::-;26553:25:::1;26564:4;26570:7;26553:10;:25::i;:::-;26439:147:::0;;;:::o;37635:207::-;37716:4;37713:81;;37763:21;;-1:-1:-1;;;37763:21:0;;;;;;;;;;;37713:81;37802:33;37821:4;37827:7;37802:18;:33::i;:::-;37635:207;;:::o;34989:1067::-;-1:-1:-1;;;;;;;;;;;24067:16:0;24078:4;24067:10;:16::i;:::-;35158:51;;::::1;35155:105;;35230:20;;-1:-1:-1::0;;;35230:20:0::1;;;;;;;;;;;35155:105;35336:19;::::0;35442:33:::1;::::0;35286:15;;35336:19;35442:33:::1;;35439:284;;;35494:9;35489:225;35509:5;35505:1;:9;35489:225;;;35570:5;:1:::0;35574::::1;35570:5;:::i;:::-;35558:18;::::0;:8;:18:::1;:::i;:::-;35536:15;;35552:1;35536:18;;;;;;;:::i;:::-;;;;;;;:40;35532:107;;35603:20;;-1:-1:-1::0;;;35603:20:0::1;;;;;;;;;;;35532:107;35683:3;;35489:225;;;;35439:284;35738:9;35733:241;35753:5;35749:1;:9;35733:241;;;35814:18;;35833:1;35814:21;;;;;;;:::i;:::-;;;;;;;35773:18;:38;35792:15;;35808:1;35792:18;;;;;;;:::i;:::-;;;;;;;35773:38;;;;;;;;;;;:62;;;;35890:18;;35909:1;35890:21;;;;;;;:::i;:::-;;;;;;;35870:15;;35886:1;35870:18;;;;;;;:::i;:::-;;;;;;;35852:60;;;;;;;;;;35949:3;;35733:241;;;-1:-1:-1::0;36006:15:0;;36022:26:::1;36047:1;36006:15:::0;36022:26:::1;:::i;:::-;36006:43;;;;;;;:::i;:::-;;;::::0;;;::::1;;35984:19;:65:::0;-1:-1:-1;;;;;;;;34989:1067:0:o;34125:529::-;-1:-1:-1;;;;;;;;;;;24067:16:0;24078:4;24067:10;:16::i;:::-;34337:33:::1;::::0;::::1;;:80:::0;::::1;;;-1:-1:-1::0;34393:19:0::1;::::0;;:23:::1;::::0;::::1;:::i;:::-;34375:14;:41;;34337:80;34334:134;;;34438:20;;-1:-1:-1::0;;;34438:20:0::1;;;;;;;;;;;34334:134;34478:19;:36:::0;;;34523:34:::1;::::0;;;:18:::1;:34;::::0;;;;;:55;;;34594:53;34560:18;;34500:14;;34594:53:::1;::::0;34523:34;34594:53:::1;34125:529:::0;;;:::o;24471:147::-;24557:4;24581:12;;;;;;;;;;;-1:-1:-1;;;;;24581:29:0;;;;;;;;;;;;;;;24471:147::o;26879:149::-;26072:7;26099:12;;;;;;;;;;:22;;;24067:16;24078:4;24067:10;:16::i;:::-;26994:26:::1;27006:4;27012:7;26994:11;:26::i;36593:648::-:0;36796:4;36889:19;;36872:14;:36;36868:76;;;-1:-1:-1;36929:5:0;36922:12;;36868:76;37025:25;37053:34;;;:18;:34;;;;;;37151:83;37053:34;37195:11;;37208:10;37220:6;37228:5;37151:24;:83::i;:::-;37144:90;;;36593:648;;;;;;;;;:::o;37378:163::-;-1:-1:-1;;;;;;;;;;;24067:16:0;24078:4;24067:10;:16::i;:::-;-1:-1:-1;37501:33:0::1;::::0;;-1:-1:-1;;37464:70:0;::::1;37501:33;::::0;;::::1;37500:34;37464:70;::::0;;37378:163::o;24922:105::-;24989:30;25000:4;4040:10;24989;:30::i;:::-;24922:105;:::o;29180:238::-;29264:22;29272:4;29278:7;29264;:22::i;:::-;29259:152;;29303:6;:12;;;;;;;;;;;-1:-1:-1;;;;;29303:29:0;;;;;;;;;:36;;-1:-1:-1;;29303:36:0;29335:4;29303:36;;;29386:12;4040:10;;3960:98;29386:12;-1:-1:-1;;;;;29359:40:0;29377:7;-1:-1:-1;;;;;29359:40:0;29371:4;29359:40;;;;;;;;;;29180:238;;:::o;27583:218::-;-1:-1:-1;;;;;27679:23:0;;4040:10;27679:23;27671:83;;;;-1:-1:-1;;;27671:83:0;;4438:2:1;27671:83:0;;;4420:21:1;4477:2;4457:18;;;4450:30;4516:34;4496:18;;;4489:62;-1:-1:-1;;;4567:18:1;;;4560:45;4622:19;;27671:83:0;;;;;;;;;27767:26;27779:4;27785:7;29598:239;29682:22;29690:4;29696:7;29682;:22::i;:::-;29678:152;;;29753:5;29721:12;;;;;;;;;;;-1:-1:-1;;;;;29721:29:0;;;;;;;;;;:37;;-1:-1:-1;;29721:37:0;;;29778:40;4040:10;;29721:12;;29778:40;;29753:5;29778:40;29598:239;;:::o;31064:1054::-;31263:4;31299:14;31286:9;:27;31282:85;;31337:18;;-1:-1:-1;;;31337:18:0;;;;;;;;;;;31282:85;31379:20;31429:4;31412:22;;;;;;4781:19:1;;4825:2;4816:12;;4652:182;31412:22:0;;;;-1:-1:-1;;31412:22:0;;;;;;;;;31402:33;;31412:22;31402:33;;;;;-1:-1:-1;31467:9:0;31503:14;31546:5;31448:16;31569:502;31589:5;31585:1;:9;31569:502;;;31612:20;31635:5;;31641:1;31635:8;;;;;;;:::i;:::-;;;;;;;31612:31;;31675:1;31664:8;:12;;;;:::i;:::-;31680:1;31664:17;:42;;;-1:-1:-1;31701:5:0;31685:12;:8;31696:1;31685:12;:::i;:::-;:21;31664:42;31660:264;;;31752:44;;;;;;5245:19:1;;;5280:12;;;5273:28;;;5317:12;;31752:44:0;;;;;;;;;;;;31742:55;;;;;;31727:70;;31660:264;;;31863:44;;;;;;5245:19:1;;;5280:12;;;5273:28;;;5317:12;;31863:44:0;;;;;;;;;;;;31853:55;;;;;;31838:70;;31660:264;31940:13;31952:1;31940:13;;:::i;:::-;;-1:-1:-1;31990:1:0;31977:9;31985:1;31977:5;:9;:::i;:::-;31976:15;;;;:::i;:::-;:19;;31994:1;31976:19;:::i;:::-;31968:27;-1:-1:-1;;32041:3:0;;31569:502;;;-1:-1:-1;;;32090:20:0;;;31064:1054;-1:-1:-1;;;;;;;31064:1054:0:o;25317:492::-;25406:22;25414:4;25420:7;25406;:22::i;:::-;25401:401;;25594:28;25614:7;25594:19;:28::i;:::-;25695:38;25723:4;25730:2;25695:19;:38::i;:::-;25499:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;25499:257:0;;;;;;;;;;-1:-1:-1;;;25445:345:0;;;;;;;:::i;21385:151::-;21443:13;21476:52;-1:-1:-1;;;;;21488:22:0;;19540:2;20781:447;20856:13;20882:19;20914:10;20918:6;20914:1;:10;:::i;:::-;:14;;20927:1;20914:14;:::i;:::-;20904:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20904:25:0;;20882:47;;-1:-1:-1;;;20940:6:0;20947:1;20940:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;20940:15:0;;;;;;;;;-1:-1:-1;;;20966:6:0;20973:1;20966:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;20966:15:0;;;;;;;;-1:-1:-1;20997:9:0;21009:10;21013:6;21009:1;:10;:::i;:::-;:14;;21022:1;21009:14;:::i;:::-;20997:26;;20992:131;21029:1;21025;:5;20992:131;;;-1:-1:-1;;;21073:5:0;21081:3;21073:11;21064:21;;;;;;;:::i;:::-;;;;21052:6;21059:1;21052:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;21052:33:0;;;;;;;;-1:-1:-1;21110:1:0;21100:11;;;;;21032:3;;;:::i;:::-;;;20992:131;;;-1:-1:-1;21141:10:0;;21133:55;;;;-1:-1:-1;;;21133:55:0;;7586:2:1;21133:55:0;;;7568:21:1;;;7605:18;;;7598:30;7664:34;7644:18;;;7637:62;7716:18;;21133:55:0;7384:356:1;21133:55:0;21213:6;20781:447;-1:-1:-1;;;20781:447:0:o;14:286:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:1;;209:43;;199:71;;266:1;263;256:12;497:180;556:6;609:2;597:9;588:7;584:23;580:32;577:52;;;625:1;622;615:12;577:52;-1:-1:-1;648:23:1;;497:180;-1:-1:-1;497:180:1:o;864:354::-;932:6;940;993:2;981:9;972:7;968:23;964:32;961:52;;;1009:1;1006;999:12;961:52;1032:23;;;-1:-1:-1;1105:2:1;1090:18;;1077:32;-1:-1:-1;;;;;1138:31:1;;1128:42;;1118:70;;1184:1;1181;1174:12;1118:70;1207:5;1197:15;;;864:354;;;;;:::o;1405:367::-;1468:8;1478:6;1532:3;1525:4;1517:6;1513:17;1509:27;1499:55;;1550:1;1547;1540:12;1499:55;-1:-1:-1;1573:20:1;;1616:18;1605:30;;1602:50;;;1648:1;1645;1638:12;1602:50;1685:4;1677:6;1673:17;1661:29;;1745:3;1738:4;1728:6;1725:1;1721:14;1713:6;1709:27;1705:38;1702:47;1699:67;;;1762:1;1759;1752:12;1699:67;1405:367;;;;;:::o;1777:773::-;1899:6;1907;1915;1923;1976:2;1964:9;1955:7;1951:23;1947:32;1944:52;;;1992:1;1989;1982:12;1944:52;2032:9;2019:23;2061:18;2102:2;2094:6;2091:14;2088:34;;;2118:1;2115;2108:12;2088:34;2157:70;2219:7;2210:6;2199:9;2195:22;2157:70;:::i;:::-;2246:8;;-1:-1:-1;2131:96:1;-1:-1:-1;2334:2:1;2319:18;;2306:32;;-1:-1:-1;2350:16:1;;;2347:36;;;2379:1;2376;2369:12;2347:36;;2418:72;2482:7;2471:8;2460:9;2456:24;2418:72;:::i;:::-;1777:773;;;;-1:-1:-1;2509:8:1;-1:-1:-1;;;;1777:773:1:o;2555:248::-;2623:6;2631;2684:2;2672:9;2663:7;2659:23;2655:32;2652:52;;;2700:1;2697;2690:12;2652:52;-1:-1:-1;;2723:23:1;;;2793:2;2778:18;;;2765:32;;-1:-1:-1;2555:248:1:o;2993:711::-;3115:6;3123;3131;3139;3147;3155;3208:3;3196:9;3187:7;3183:23;3179:33;3176:53;;;3225:1;3222;3215:12;3176:53;3261:9;3248:23;3238:33;;3318:2;3307:9;3303:18;3290:32;3280:42;;3373:2;3362:9;3358:18;3345:32;3400:18;3392:6;3389:30;3386:50;;;3432:1;3429;3422:12;3386:50;3471:70;3533:7;3524:6;3513:9;3509:22;3471:70;:::i;:::-;2993:711;;;;-1:-1:-1;3560:8:1;3642:2;3627:18;;3614:32;;3693:3;3678:19;;;3665:33;;-1:-1:-1;2993:711:1;-1:-1:-1;;;;2993:711:1:o;3709:127::-;3770:10;3765:3;3761:20;3758:1;3751:31;3801:4;3798:1;3791:15;3825:4;3822:1;3815:15;3841:125;3906:9;;;3927:10;;;3924:36;;;3940:18;;:::i;3971:127::-;4032:10;4027:3;4023:20;4020:1;4013:31;4063:4;4060:1;4053:15;4087:4;4084:1;4077:15;4103:128;4170:9;;;4191:11;;;4188:37;;;4205:18;;:::i;4839:127::-;4900:10;4895:3;4891:20;4888:1;4881:31;4931:4;4928:1;4921:15;4955:4;4952:1;4945:15;4971:112;5003:1;5029;5019:35;;5034:18;;:::i;:::-;-1:-1:-1;5068:9:1;;4971:112::o;5340:120::-;5380:1;5406;5396:35;;5411:18;;:::i;:::-;-1:-1:-1;5445:9:1;;5340:120::o;5465:250::-;5550:1;5560:113;5574:6;5571:1;5568:13;5560:113;;;5650:11;;;5644:18;5631:11;;;5624:39;5596:2;5589:10;5560:113;;;-1:-1:-1;;5707:1:1;5689:16;;5682:27;5465:250::o;5720:812::-;6131:25;6126:3;6119:38;6101:3;6186:6;6180:13;6202:75;6270:6;6265:2;6260:3;6256:12;6249:4;6241:6;6237:17;6202:75;:::i;:::-;-1:-1:-1;;;6336:2:1;6296:16;;;6328:11;;;6321:40;6386:13;;6408:76;6386:13;6470:2;6462:11;;6455:4;6443:17;;6408:76;:::i;:::-;6504:17;6523:2;6500:26;;5720:812;-1:-1:-1;;;;5720:812:1:o;6537:396::-;6686:2;6675:9;6668:21;6649:4;6718:6;6712:13;6761:6;6756:2;6745:9;6741:18;6734:34;6777:79;6849:6;6844:2;6833:9;6829:18;6824:2;6816:6;6812:15;6777:79;:::i;:::-;6917:2;6896:15;-1:-1:-1;;6892:29:1;6877:45;;;;6924:2;6873:54;;6537:396;-1:-1:-1;;6537:396:1:o;6938:168::-;7011:9;;;7042;;7059:15;;;7053:22;;7039:37;7029:71;;7080:18;;:::i;7111:127::-;7172:10;7167:3;7163:20;7160:1;7153:31;7203:4;7200:1;7193:15;7227:4;7224:1;7217:15;7243:136;7282:3;7310:5;7300:39;;7319:18;;:::i;:::-;-1:-1:-1;;;7355:18:1;;7243:136::o
Swarm Source
ipfs://a6ce0d3da08ed04e13e6271265f82e0e8abe106960f3e7ae0183c7d963c56ef7
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.