Source Code
Overview
ETH Balance
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 2239026 | 711 days ago | 0.002 ETH | ||||
| 2238969 | 711 days ago | 0 ETH | ||||
| 2238969 | 711 days ago | 0 ETH | ||||
| 2238969 | 711 days ago | 0 ETH | ||||
| 2238969 | 711 days ago | 0 ETH | ||||
| 2238969 | 711 days ago | 0 ETH | ||||
| 2238968 | 711 days ago | 0 ETH | ||||
| 2238956 | 711 days ago | 0 ETH | ||||
| 2238956 | 711 days ago | 0 ETH | ||||
| 2238924 | 711 days ago | 0.005 ETH | ||||
| 2238862 | 711 days ago | 0 ETH | ||||
| 2238861 | 711 days ago | 0 ETH | ||||
| 2238682 | 711 days ago | 0 ETH | ||||
| 2238682 | 711 days ago | 0 ETH | ||||
| 2238682 | 711 days ago | 0 ETH | ||||
| 2238682 | 711 days ago | 0 ETH | ||||
| 2238681 | 711 days ago | 0 ETH | ||||
| 2238573 | 711 days ago | 0 ETH | ||||
| 2238573 | 711 days ago | 0 ETH | ||||
| 2238573 | 711 days ago | 0 ETH | ||||
| 2238573 | 711 days ago | 0 ETH | ||||
| 2238573 | 711 days ago | 0 ETH | ||||
| 2238573 | 711 days ago | 0 ETH | ||||
| 2238573 | 711 days ago | 0 ETH | ||||
| 2238573 | 711 days ago | 0 ETH |
Loading...
Loading
Contract Name:
L2MessageService
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at lineascan.build/ on 2023-07-18 */ // Sources flattened with hardhat v2.16.1 https://hardhat.org // File @openzeppelin/contracts-upgradeable/access/[email protected] // SPDX-License-Identifier: AGPL-3.0 // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File @openzeppelin/contracts-upgradeable/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File @openzeppelin/contracts-upgradeable/proxy/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } } // File @openzeppelin/contracts-upgradeable/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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File @openzeppelin/contracts-upgradeable/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 IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File @openzeppelin/contracts-upgradeable/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 ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; } // File @openzeppelin/contracts-upgradeable/utils/math/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 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 256, 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 << 3) < value ? 1 : 0); } } } // File @openzeppelin/contracts-upgradeable/utils/math/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File @openzeppelin/contracts-upgradeable/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } // File @openzeppelin/contracts-upgradeable/access/[email protected] // OpenZeppelin Contracts (last updated v4.9.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: * * ```solidity * 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}: * * ```solidity * 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. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal onlyInitializing { } function __AccessControl_init_unchained() internal onlyInitializing { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(account), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File @openzeppelin/contracts-upgradeable/security/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; } // File contracts/interfaces/IL2MessageManager.sol pragma solidity ^0.8.19; interface IL2MessageManager { /** * @dev Emitted when L1->L2 message hashes have been added to L2 storage. */ event L1L2MessageHashesAddedToInbox(bytes32[] messageHashes); /** * @dev Thrown when the message hashes list length is higher than one hundred. */ error MessageHashesListLengthHigherThanOneHundred(uint256 length); /** * @dev Thrown when the message hashes array is empty. */ error EmptyMessageHashesArray(); /** * @dev Thrown when the message does not exist or has already been claimed. */ error MessageDoesNotExistOrHasAlreadyBeenClaimed(); /** * @notice Anchor L1-> L2 message hashes. * @param _messageHashes New message hashes to anchor on L2. */ function addL1L2MessageHashes(bytes32[] calldata _messageHashes) external; } // File contracts/interfaces/IPauseManager.sol pragma solidity ^0.8.19; interface IPauseManager { /** * @dev Thrown when a specific pause type is paused. */ error IsPaused(bytes32 pauseType); /** * @dev Thrown when a specific pause type is not paused and expected to be. */ error IsNotPaused(bytes32 pauseType); /** * @dev Emitted when a pause type is paused. */ event Paused(address messageSender, bytes32 pauseType); /** * @dev Emitted when a pause type is unpaused. */ event UnPaused(address messageSender, bytes32 pauseType); } // File contracts/messageService/lib/PauseManager.sol pragma solidity ^0.8.19; /** * @title Contract to manage cross-chain function pausing. * @author ConsenSys Software Inc. */ abstract contract PauseManager is Initializable, IPauseManager, AccessControlUpgradeable { bytes32 public constant PAUSE_MANAGER_ROLE = keccak256("PAUSE_MANAGER_ROLE"); bytes32 public constant GENERAL_PAUSE_TYPE = keccak256("GENERAL_PAUSE_TYPE"); bytes32 public constant L1_L2_PAUSE_TYPE = keccak256("L1_L2_PAUSE_TYPE"); bytes32 public constant L2_L1_PAUSE_TYPE = keccak256("L2_L1_PAUSE_TYPE"); bytes32 public constant PROVING_SYSTEM_PAUSE_TYPE = keccak256("PROVING_SYSTEM_PAUSE_TYPE"); mapping(bytes32 => bool) public pauseTypeStatuses; uint256[10] private _gap; /** * @dev Modifier to make a function callable only when the type is not paused. * * Requirements: * * - The type must not be paused. */ modifier whenTypeNotPaused(bytes32 _pauseType) { _requireTypeNotPaused(_pauseType); _; } /** * @dev Modifier to make a function callable only when the type is paused. * * Requirements: * * - The type must not be paused. */ modifier whenTypePaused(bytes32 _pauseType) { _requireTypePaused(_pauseType); _; } /** * @dev Throws if the type is not paused. * @param _pauseType The keccak256 pause type being checked, */ function _requireTypePaused(bytes32 _pauseType) internal view virtual { if (!pauseTypeStatuses[_pauseType]) { revert IsNotPaused(_pauseType); } } /** * @dev Throws if the type is paused. * @param _pauseType The keccak256 pause type being checked, */ function _requireTypeNotPaused(bytes32 _pauseType) internal view virtual { if (pauseTypeStatuses[_pauseType]) { revert IsPaused(_pauseType); } } /** * @notice Pauses functionality by specific type. * @dev Requires PAUSE_MANAGER_ROLE. * @param _pauseType keccak256 pause type. **/ function pauseByType(bytes32 _pauseType) external whenTypeNotPaused(_pauseType) onlyRole(PAUSE_MANAGER_ROLE) { pauseTypeStatuses[_pauseType] = true; emit Paused(_msgSender(), _pauseType); } /** * @notice Unpauses functionality by specific type. * @dev Requires PAUSE_MANAGER_ROLE. * @param _pauseType keccak256 pause type. **/ function unPauseByType(bytes32 _pauseType) external whenTypePaused(_pauseType) onlyRole(PAUSE_MANAGER_ROLE) { pauseTypeStatuses[_pauseType] = false; emit UnPaused(_msgSender(), _pauseType); } } // File contracts/messageService/l2/L2MessageManager.sol pragma solidity ^0.8.19; /** * @title Contract to manage cross-chain message hashes storage and statuses on L2. * @author ConsenSys Software Inc. */ abstract contract L2MessageManager is Initializable, PauseManager, IL2MessageManager { uint8 public constant INBOX_STATUS_UNKNOWN = 0; uint8 public constant INBOX_STATUS_RECEIVED = 1; uint8 public constant INBOX_STATUS_CLAIMED = 2; /// @dev There is a uint232 worth of storage layout here bytes32 public constant L1_L2_MESSAGE_SETTER_ROLE = keccak256("L1_L2_MESSAGE_SETTER_ROLE"); /** * @dev Mapping to store L1->L2 message hashes status. * @dev messageHash => messageStatus (0: unknown, 1: received, 2: claimed). */ mapping(bytes32 => uint256) public inboxL1L2MessageStatus; /// @dev Keep free storage slots for future implementation updates to avoid storage collision. // ******************************************************************************************* // NB: THIS GAP HAS BEEN PUSHED OUT IN FAVOUR OF THE GAP INSIDE THE REENTRANCY CODE //uint256[50] private __gap; // NB: DO NOT USE THIS GAP // ******************************************************************************************* /** * @notice Initialises L2 message manager contract. * @param _l1l2MessageSetter The address owning the L1_L2_MESSAGE_SETTER_ROLE role. **/ function __L2MessageManager_init(address _l1l2MessageSetter) internal onlyInitializing { _grantRole(L1_L2_MESSAGE_SETTER_ROLE, _l1l2MessageSetter); } /** * @notice Add a cross-chain L1->L2 message hashes in storage. * @dev Only address that has the role 'L1_L2_MESSAGE_SETTER_ROLE' are allowed to call this function. * @param _messageHashes Message hashes array. */ function addL1L2MessageHashes(bytes32[] calldata _messageHashes) external onlyRole(L1_L2_MESSAGE_SETTER_ROLE) { uint256 messageHashesLength = _messageHashes.length; if (messageHashesLength > 100) { revert MessageHashesListLengthHigherThanOneHundred(messageHashesLength); } for (uint256 i; i < messageHashesLength; ) { bytes32 messageHash = _messageHashes[i]; if (inboxL1L2MessageStatus[messageHash] == INBOX_STATUS_UNKNOWN) { inboxL1L2MessageStatus[messageHash] = INBOX_STATUS_RECEIVED; } unchecked { i++; } } emit L1L2MessageHashesAddedToInbox(_messageHashes); } /** * @notice Update the status of L1->L2 message when a user claim a message on L2. * @param _messageHash Hash of the message. */ function _updateL1L2MessageStatusToClaimed(bytes32 _messageHash) internal { if (inboxL1L2MessageStatus[_messageHash] != INBOX_STATUS_RECEIVED) { revert MessageDoesNotExistOrHasAlreadyBeenClaimed(); } inboxL1L2MessageStatus[_messageHash] = INBOX_STATUS_CLAIMED; } } // File contracts/interfaces/IGenericErrors.sol pragma solidity ^0.8.19; interface IGenericErrors { /** * @dev Thrown when a parameter is the zero address. */ error ZeroAddressNotAllowed(); } // File contracts/interfaces/IMessageService.sol pragma solidity ^0.8.19; interface IMessageService { /** * @dev Emitted when a message is sent. * @dev We include the message hash to save hashing costs on the rollup. */ event MessageSent( address indexed _from, address indexed _to, uint256 _fee, uint256 _value, uint256 _nonce, bytes _calldata, bytes32 indexed _messageHash ); /** * @dev Emitted when a message is claimed. */ event MessageClaimed(bytes32 indexed _messageHash); /** * @dev Thrown when fees are lower than the minimum fee. */ error FeeTooLow(); /** * @dev Thrown when fees are lower than value. */ error ValueShouldBeGreaterThanFee(); /** * @dev Thrown when the value sent is less than the fee. * @dev Value to forward on is msg.value - _fee. */ error ValueSentTooLow(); /** * @dev Thrown when the destination address reverts. */ error MessageSendingFailed(address destination); /** * @dev Thrown when the destination address reverts. */ error FeePaymentFailed(address recipient); /** * @notice Sends a message for transporting from the given chain. * @dev This function should be called with a msg.value = _value + _fee. The fee will be paid on the destination chain. * @param _to The destination address on the destination chain. * @param _fee The message service fee on the origin chain. * @param _calldata The calldata used by the destination message service to call the destination contract. */ function sendMessage(address _to, uint256 _fee, bytes calldata _calldata) external payable; /** * @notice Deliver a message to the destination chain. * @notice Is called automatically by the Postman, dApp or end user. * @param _from The msg.sender calling the origin message service. * @param _to The destination address on the destination chain. * @param _value The value to be transferred to the destination address. * @param _fee The message service fee on the origin chain. * @param _feeRecipient Address that will receive the fees. * @param _calldata The calldata used by the destination message service to call/forward to the destination contract. * @param _nonce Unique message number. */ function claimMessage( address _from, address _to, uint256 _fee, uint256 _value, address payable _feeRecipient, bytes calldata _calldata, uint256 _nonce ) external; /** * @notice Returns the original sender of the message on the origin layer. * @return The original sender of the message on the origin layer. */ function sender() external view returns (address); } // File contracts/messageService/lib/Codec.sol pragma solidity ^0.8.19; /** * @title Decoding functions for message service anchoring and bytes slicing. * @author ConsenSys Software Inc. * @notice You can use this to slice bytes and extract anchoring hashes from calldata. **/ library CodecV2 { /** * @notice Decodes a collection of bytes32 (hashes) from the calldata of a transaction. * @dev Extracts and decodes skipping the function selector (selector is expected in the input). * @dev A check beforehand must be performed to confirm this is the correct type of transaction. * @param _calldataWithSelector The calldata for the transaction. * @return bytes32[] - array of message hashes. **/ function _extractXDomainAddHashes(bytes memory _calldataWithSelector) internal pure returns (bytes32[] memory) { assembly { let len := sub(mload(_calldataWithSelector), 4) _calldataWithSelector := add(_calldataWithSelector, 0x4) mstore(_calldataWithSelector, len) } return abi.decode(_calldataWithSelector, (bytes32[])); } } // File contracts/interfaces/IRateLimiter.sol pragma solidity ^0.8.19; interface IRateLimiter { /** * @dev Thrown when an amount breaches the limit in the period. */ error RateLimitExceeded(); /** * @dev Thrown when the period is initialised to zero. */ error PeriodIsZero(); /** * @dev Thrown when the limit is initialised to zero. */ error LimitIsZero(); /** * @dev Emitted when the amount in the period is reset to zero. */ event AmountUsedInPeriodReset(address indexed resettingAddress); /** * @dev Emitted when the limit is changed. * @dev If the current used amount is higher than the new limit, the used amount is lowered to the limit. */ event LimitAmountChanged( address indexed amountChangeBy, uint256 amount, bool amountUsedLoweredToLimit, bool usedAmountResetToZero ); /** * @notice Resets the rate limit amount to the amount specified. * @param _amount New message hashes. */ function resetRateLimitAmount(uint256 _amount) external; /** * @notice Resets the amount used in the period to zero. */ function resetAmountUsedInPeriod() external; } // File contracts/messageService/lib/RateLimiter.sol pragma solidity ^0.8.19; /** * @title Rate Limiter by period and amount using the block timestamp. * @author ConsenSys Software Inc. * @notice You can use this control numeric limits over a period using timestamp. **/ contract RateLimiter is Initializable, IRateLimiter, AccessControlUpgradeable { bytes32 public constant RATE_LIMIT_SETTER_ROLE = keccak256("RATE_LIMIT_SETTER_ROLE"); uint256 public periodInSeconds; // how much time before limit resets. uint256 public limitInWei; // max ether to withdraw per period. // @dev Public for ease of consumption. // @notice The time at which the current period ends at. uint256 public currentPeriodEnd; // @dev Public for ease of consumption. // @notice Amounts already withdrawn this period. uint256 public currentPeriodAmountInWei; uint256[10] private _gap; /** * @notice Initialises the limits and period for the rate limiter. * @param _periodInSeconds The length of the period in seconds. * @param _limitInWei The limit allowed in the period in Wei. **/ function __RateLimiter_init(uint256 _periodInSeconds, uint256 _limitInWei) internal onlyInitializing { if (_periodInSeconds == 0) { revert PeriodIsZero(); } if (_limitInWei == 0) { revert LimitIsZero(); } periodInSeconds = _periodInSeconds; limitInWei = _limitInWei; currentPeriodEnd = block.timestamp + _periodInSeconds; } /** * @notice Increments the amount used in the period. * @dev The amount determining logic is external to this (e.g. fees are included when calling here). * @dev Reverts if the limit is breached. * @param _usedAmount The amount used to be added. **/ function _addUsedAmount(uint256 _usedAmount) internal { uint256 currentPeriodAmountTemp; if (currentPeriodEnd < block.timestamp) { currentPeriodEnd = block.timestamp + periodInSeconds; currentPeriodAmountTemp = _usedAmount; } else { currentPeriodAmountTemp = currentPeriodAmountInWei + _usedAmount; } if (currentPeriodAmountTemp > limitInWei) { revert RateLimitExceeded(); } currentPeriodAmountInWei = currentPeriodAmountTemp; } /** * @notice Resets the rate limit amount. * @dev If the used amount is higher, it is set to the limit to avoid confusion/issues. * @dev Only the RATE_LIMIT_SETTER_ROLE is allowed to execute this function. * @dev Emits the LimitAmountChanged event. * @dev usedLimitAmountToSet will use the default value of zero if period has expired * @param _amount The amount to reset the limit to. **/ function resetRateLimitAmount(uint256 _amount) external onlyRole(RATE_LIMIT_SETTER_ROLE) { uint256 usedLimitAmountToSet; bool amountUsedLoweredToLimit; bool usedAmountResetToZero; if (currentPeriodEnd < block.timestamp) { currentPeriodEnd = block.timestamp + periodInSeconds; usedAmountResetToZero = true; } else { if (_amount < currentPeriodAmountInWei) { usedLimitAmountToSet = _amount; amountUsedLoweredToLimit = true; } } limitInWei = _amount; if (usedAmountResetToZero || amountUsedLoweredToLimit) { currentPeriodAmountInWei = usedLimitAmountToSet; } emit LimitAmountChanged(_msgSender(), _amount, amountUsedLoweredToLimit, usedAmountResetToZero); } /** * @notice Resets the amount used to zero. * @dev Only the RATE_LIMIT_SETTER_ROLE is allowed to execute this function. * @dev Emits the AmountUsedInPeriodReset event. **/ function resetAmountUsedInPeriod() external onlyRole(RATE_LIMIT_SETTER_ROLE) { currentPeriodAmountInWei = 0; emit AmountUsedInPeriodReset(_msgSender()); } } // File contracts/messageService/l2/L2MessageService.sol pragma solidity ^0.8.19; /** * @title Contract to manage cross-chain messaging on L2. * @author ConsenSys Software Inc. */ contract L2MessageService is Initializable, RateLimiter, L2MessageManager, ReentrancyGuardUpgradeable, IMessageService, IGenericErrors { // Keep free storage slots for future implementation updates to avoid storage collision. uint256[50] private __gap_L2MessageService; bytes32 public constant MINIMUM_FEE_SETTER_ROLE = keccak256("MINIMUM_FEE_SETTER_ROLE"); address private _messageSender; // @dev initialise to save user cost with existing slot. uint256 public nextMessageNumber; // @dev initialise minimumFeeInWei variable. uint256 public minimumFeeInWei; // @dev adding these should not affect storage as they are constants and are store in bytecode uint256 private constant REFUND_OVERHEAD_IN_GAS = 47500; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /** * @notice Initialises underlying message service dependencies. * @param _securityCouncil The address owning the security council role. * @param _l1l2MessageSetter The address owning the add L1L2MessageHashes functionality. * @param _rateLimitPeriod The period to rate limit against. * @param _rateLimitAmount The limit allowed for withdrawing the period. **/ function initialize( address _securityCouncil, address _l1l2MessageSetter, uint256 _rateLimitPeriod, uint256 _rateLimitAmount ) public initializer { if (_securityCouncil == address(0)) { revert ZeroAddressNotAllowed(); } if (_l1l2MessageSetter == address(0)) { revert ZeroAddressNotAllowed(); } __ERC165_init(); __Context_init(); __AccessControl_init(); __RateLimiter_init(_rateLimitPeriod, _rateLimitAmount); __L2MessageManager_init(_l1l2MessageSetter); nextMessageNumber = 1; _grantRole(DEFAULT_ADMIN_ROLE, _securityCouncil); _grantRole(MINIMUM_FEE_SETTER_ROLE, _securityCouncil); _grantRole(RATE_LIMIT_SETTER_ROLE, _securityCouncil); _grantRole(PAUSE_MANAGER_ROLE, _securityCouncil); _messageSender = address(123456789); } /** * @notice Adds a message for sending cross-chain and emits a relevant event. * @dev The message number is preset and only incremented at the end if successful for the next caller. * @param _to The address the message is intended for. * @param _fee The fee being paid for the message delivery. * @param _calldata The calldata to pass to the recipient. **/ function sendMessage(address _to, uint256 _fee, bytes calldata _calldata) external payable { _requireTypeNotPaused(L2_L1_PAUSE_TYPE); _requireTypeNotPaused(GENERAL_PAUSE_TYPE); if (_to == address(0)) { revert ZeroAddressNotAllowed(); } if (_fee > msg.value) { revert ValueSentTooLow(); } uint256 coinbaseFee = minimumFeeInWei; if (_fee < coinbaseFee) { revert FeeTooLow(); } uint256 postmanFee; uint256 valueSent; unchecked { postmanFee = _fee - coinbaseFee; valueSent = msg.value - _fee; } uint256 messageNumber = nextMessageNumber; /// @dev Rate limit and revert is in the rate limiter. _addUsedAmount(valueSent + postmanFee); bytes32 messageHash = keccak256(abi.encode(msg.sender, _to, postmanFee, valueSent, messageNumber, _calldata)); nextMessageNumber++; (bool success, ) = block.coinbase.call{ value: coinbaseFee }(""); if (!success) { revert FeePaymentFailed(block.coinbase); } emit MessageSent(msg.sender, _to, postmanFee, valueSent, messageNumber, _calldata, messageHash); } /** * @notice Claims and delivers a cross-chain message. * @dev _feeRecipient Can be set to address(0) to receive as msg.sender. * @dev messageSender Is set temporarily when claiming and reset post. * @param _from The address of the original sender. * @param _to The address the message is intended for. * @param _fee The fee being paid for the message delivery. * @param _value The value to be transferred to the destination address. * @param _feeRecipient The recipient for the fee. * @param _calldata The calldata to pass to the recipient. * @param _nonce The unique auto generated message number used when sending the message. **/ function claimMessage( address _from, address _to, uint256 _fee, uint256 _value, address payable _feeRecipient, bytes calldata _calldata, uint256 _nonce ) external nonReentrant distributeFees(_fee, _to, _calldata, _feeRecipient) { _requireTypeNotPaused(L1_L2_PAUSE_TYPE); _requireTypeNotPaused(GENERAL_PAUSE_TYPE); bytes32 messageHash = keccak256(abi.encode(_from, _to, _fee, _value, _nonce, _calldata)); /// @dev Status check and revert is in the message manager. _updateL1L2MessageStatusToClaimed(messageHash); _messageSender = _from; (bool callSuccess, bytes memory returnData) = _to.call{ value: _value }(_calldata); if (!callSuccess) { if (returnData.length > 0) { assembly { let data_size := mload(returnData) revert(add(32, returnData), data_size) } } else { revert MessageSendingFailed(_to); } } _messageSender = address(123456789); emit MessageClaimed(messageHash); } /** * @notice The Fee Manager sets a minimum fee to address DOS protection. * @param _feeInWei New minimum fee in Wei. **/ function setMinimumFee(uint256 _feeInWei) external onlyRole(MINIMUM_FEE_SETTER_ROLE) { minimumFeeInWei = _feeInWei; } /** * @dev The _messageSender address is set temporarily when claiming. * @return _messageSender address. **/ function sender() external view returns (address) { return _messageSender; } /** * @notice Function to receive funds for liquidity purposes. **/ receive() external payable virtual {} /** * @notice The unspent fee is refunded if applicable. * @param _feeInWei The fee paid for delivery in Wei. * @param _to The recipient of the message and gas refund. * @param _calldata The calldata of the message. **/ modifier distributeFees( uint256 _feeInWei, address _to, bytes calldata _calldata, address _feeRecipient ) { //pre-execution uint256 startingGas = gasleft(); _; //post-execution // we have a fee if (_feeInWei > 0) { // default postman fee uint256 deliveryFee = _feeInWei; // do we have empty calldata? if (_calldata.length == 0) { bool isDestinationEOA; assembly { isDestinationEOA := iszero(extcodesize(_to)) } // are we calling an EOA if (isDestinationEOA) { // initial + cost to call and refund minus gasleft deliveryFee = (startingGas + REFUND_OVERHEAD_IN_GAS - gasleft()) * tx.gasprice; if (_feeInWei > deliveryFee) { payable(_to).send(_feeInWei - deliveryFee); } else { deliveryFee = _feeInWei; } } } address feeReceiver = _feeRecipient == address(0) ? msg.sender : _feeRecipient; bool callSuccess = payable(feeReceiver).send(deliveryFee); if (!callSuccess) { revert FeePaymentFailed(feeReceiver); } } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EmptyMessageHashesArray","type":"error"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"FeePaymentFailed","type":"error"},{"inputs":[],"name":"FeeTooLow","type":"error"},{"inputs":[{"internalType":"bytes32","name":"pauseType","type":"bytes32"}],"name":"IsNotPaused","type":"error"},{"inputs":[{"internalType":"bytes32","name":"pauseType","type":"bytes32"}],"name":"IsPaused","type":"error"},{"inputs":[],"name":"LimitIsZero","type":"error"},{"inputs":[],"name":"MessageDoesNotExistOrHasAlreadyBeenClaimed","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"MessageHashesListLengthHigherThanOneHundred","type":"error"},{"inputs":[{"internalType":"address","name":"destination","type":"address"}],"name":"MessageSendingFailed","type":"error"},{"inputs":[],"name":"PeriodIsZero","type":"error"},{"inputs":[],"name":"RateLimitExceeded","type":"error"},{"inputs":[],"name":"ValueSentTooLow","type":"error"},{"inputs":[],"name":"ValueShouldBeGreaterThanFee","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"resettingAddress","type":"address"}],"name":"AmountUsedInPeriodReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[]","name":"messageHashes","type":"bytes32[]"}],"name":"L1L2MessageHashesAddedToInbox","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"amountChangeBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"amountUsedLoweredToLimit","type":"bool"},{"indexed":false,"internalType":"bool","name":"usedAmountResetToZero","type":"bool"}],"name":"LimitAmountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_messageHash","type":"bytes32"}],"name":"MessageClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_nonce","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_calldata","type":"bytes"},{"indexed":true,"internalType":"bytes32","name":"_messageHash","type":"bytes32"}],"name":"MessageSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"messageSender","type":"address"},{"indexed":false,"internalType":"bytes32","name":"pauseType","type":"bytes32"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"messageSender","type":"address"},{"indexed":false,"internalType":"bytes32","name":"pauseType","type":"bytes32"}],"name":"UnPaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GENERAL_PAUSE_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INBOX_STATUS_CLAIMED","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INBOX_STATUS_RECEIVED","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INBOX_STATUS_UNKNOWN","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L1_L2_MESSAGE_SETTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L1_L2_PAUSE_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"L2_L1_PAUSE_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_FEE_SETTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROVING_SYSTEM_PAUSE_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RATE_LIMIT_SETTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_messageHashes","type":"bytes32[]"}],"name":"addL1L2MessageHashes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"address payable","name":"_feeRecipient","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"claimMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentPeriodAmountInWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPeriodEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"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":"","type":"bytes32"}],"name":"inboxL1L2MessageStatus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_securityCouncil","type":"address"},{"internalType":"address","name":"_l1l2MessageSetter","type":"address"},{"internalType":"uint256","name":"_rateLimitPeriod","type":"uint256"},{"internalType":"uint256","name":"_rateLimitAmount","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"limitInWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumFeeInWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextMessageNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_pauseType","type":"bytes32"}],"name":"pauseByType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"pauseTypeStatuses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodInSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"resetAmountUsedInPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"resetRateLimitAmount","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":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"sendMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feeInWei","type":"uint256"}],"name":"setMinimumFee","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":"_pauseType","type":"bytes32"}],"name":"unPauseByType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6125a080620000f36000396000f3fe6080604052600436106102535760003560e01c806391f7b90111610138578063bcbd6fcd116100b0578063cc5782f61161007f578063d84f91e811610064578063d84f91e81461073a578063eb990c591461076e578063f4b476e11461078e57600080fd5b8063cc5782f6146106ea578063d547741f1461071a57600080fd5b8063bcbd6fcd14610656578063bf3e75051461068a578063c0729ab1146106be578063c1dc0f07146106d457600080fd5b8063ad422ff011610107578063b45a4f2c116100ec578063b45a4f2c146105eb578063b4a5a4b71461060b578063b837dbe91461063f57600080fd5b8063ad422ff0146105c0578063aea4f745146105d657600080fd5b806391f7b9011461054f5780639f3ce55a14610564578063a217fddf14610577578063abd6230d1461058c57600080fd5b8063557eac73116101cb57806374377a341161019a5780638264bd821161017f5780638264bd82146104c557806389945883146104e557806391d14854146104fc57600080fd5b806374377a341461047c5780637d1e8c55146104b057600080fd5b8063557eac73146103dc57806358794456146103fc57806367e404ce146104125780636a6379671461044857600080fd5b8063248a9ca31161022257806336568abe1161020757806336568abe1461037557806348922ab714610395578063491e0936146103bc57600080fd5b8063248a9ca3146103255780632f2ff15d1461035557600080fd5b806301ffc9a71461025f5780630f6893ca1461029457806311314d0f146102cf578063182a75061461030357600080fd5b3661025a57005b600080fd5b34801561026b57600080fd5b5061027f61027a366004611f65565b6107ae565b60405190151581526020015b60405180910390f35b3480156102a057600080fd5b506102c16102af366004611fa7565b60b06020526000908152604090205481565b60405190815260200161028b565b3480156102db57600080fd5b506102c17f9a80e24e463f00a8763c4dcec6a92d07d33272fa5db895d8589be70dccb002df81565b34801561030f57600080fd5b5061032361031e366004611fa7565b610847565b005b34801561033157600080fd5b506102c1610340366004611fa7565b60009081526065602052604090206001015490565b34801561036157600080fd5b50610323610370366004611fe2565b610878565b34801561038157600080fd5b50610323610390366004611fe2565b6108a2565b3480156103a157600080fd5b506103aa600181565b60405160ff909116815260200161028b565b3480156103c857600080fd5b506103236103d736600461205b565b61095a565b3480156103e857600080fd5b506103236103f7366004611fa7565b610ccf565b34801561040857600080fd5b506102c160995481565b34801561041e57600080fd5b506101155460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161028b565b34801561045457600080fd5b506102c17f06193bb948d6b7a6fcbe51c193ccf2183bb5d979b6ae5d3a6971b8851461d3b081565b34801561048857600080fd5b506102c17f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd6741581565b3480156104bc57600080fd5b506103aa600081565b3480156104d157600080fd5b506103236104e0366004611fa7565b610d97565b3480156104f157600080fd5b506102c16101175481565b34801561050857600080fd5b5061027f610517366004611fe2565b600091825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561055b57600080fd5b506103aa600281565b6103236105723660046120f1565b610e5d565b34801561058357600080fd5b506102c1600081565b34801561059857600080fd5b506102c17f21ea2f4fee4bcb623de15ac222ea5c1464307d884f23394b78ddc07f9c9c7cd881565b3480156105cc57600080fd5b506102c160985481565b3480156105e257600080fd5b506103236110fe565b3480156105f757600080fd5b50610323610606366004611fa7565b61115a565b34801561061757600080fd5b506102c17f3a56b1bd788a764cbd923badb6d0719f21f520455285bf6877e636d08708878d81565b34801561064b57600080fd5b506102c16101165481565b34801561066257600080fd5b506102c17fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba281565b34801561069657600080fd5b506102c17f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b3480156106ca57600080fd5b506102c1609a5481565b3480156106e057600080fd5b506102c160975481565b3480156106f657600080fd5b5061027f610705366004611fa7565b60a56020526000908152604090205460ff1681565b34801561072657600080fd5b50610323610735366004611fe2565b6111e9565b34801561074657600080fd5b506102c17f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a2681565b34801561077a57600080fd5b5061032361078936600461214d565b61120e565b34801561079a57600080fd5b506103236107a9366004612193565b61151f565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061084157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b7fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba26108718161162a565b5061011755565b6000828152606560205260409020600101546108938161162a565b61089d8383611637565b505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461094c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b610956828261172b565b5050565b6109626117e6565b858784848760005a90506109957f9a80e24e463f00a8763c4dcec6a92d07d33272fa5db895d8589be70dccb002df611859565b6109be7f06193bb948d6b7a6fcbe51c193ccf2183bb5d979b6ae5d3a6971b8851461d3b0611859565b60008e8e8e8e8b8e8e6040516020016109dd9796959493929190612251565b6040516020818303038152906040528051906020012090506109fe816118a5565b8e61011560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d604051610a6b9291906122aa565b60006040518083038185875af1925050503d8060008114610aa8576040519150601f19603f3d011682016040523d82523d6000602084013e610aad565b606091505b509150915081610b1757805115610ac75780518082602001fd5b8f6040517f54613443000000000000000000000000000000000000000000000000000000008152600401610943919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b61011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd1517905560405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e90600090a2505086159050610cb557856000849003610c0157853b158015610bff573a5a610b9c61b98c866122e9565b610ba691906122fc565b610bb0919061230f565b915081881115610bfb5773ffffffffffffffffffffffffffffffffffffffff87166108fc610bde848b6122fc565b6040518115909202916000818181858888f1935050505050610bff565b8791505b505b600073ffffffffffffffffffffffffffffffffffffffff841615610c255783610c27565b335b905060008173ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050905080610cb1576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610943565b5050505b505050505050610cc5600160b155565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d82610cf98161162a565b6000806000426099541015610d2057609754610d1590426122e9565b609955506001610d32565b609a54851015610d3257849250600191505b60988590558080610d405750815b15610d4b57609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b80610da181611859565b7f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a26610dcb8161162a565b600083815260a56020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557fc343aefb875672fb1857ecda2bdf9fa822ff1e924e3714f6a3d88c5199dee261610e2a3390565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252602082018690520160405180910390a1505050565b610e867f21ea2f4fee4bcb623de15ac222ea5c1464307d884f23394b78ddc07f9c9c7cd8611859565b610eaf7f06193bb948d6b7a6fcbe51c193ccf2183bb5d979b6ae5d3a6971b8851461d3b0611859565b73ffffffffffffffffffffffffffffffffffffffff8416610efc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34831115610f36576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101175480841015610f74576040517f732f941300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61011654818503903486900390610f93610f8e84846122e9565b611901565b600033898585858b8b604051602001610fb29796959493929190612251565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012061011680549192506000610ffb83612326565b9091555050604051600090419087908381818185875af1925050503d8060008114611042576040519150601f19603f3d011682016040523d82523d6000602084013e611047565b606091505b5050905080611084576040517fa57c4df4000000000000000000000000000000000000000000000000000000008152416004820152602401610943565b818a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8888888e8e6040516110ea95949392919061235e565b60405180910390a450505050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d826111288161162a565b6000609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b8061116481611977565b7f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a2661118e8161162a565b600083815260a56020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557fb54c82d9fabaaa460c07181bb36c08c0e72d79293e77a42ac273c81d2a54281b33610e2a565b6000828152606560205260409020600101546112048161162a565b61089d838361172b565b600054610100900460ff161580801561122e5750600054600160ff909116105b806112485750303b158015611248575060005460ff166001145b6112d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610943565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561133257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b73ffffffffffffffffffffffffffffffffffffffff851661137f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166113cc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d46119c2565b6113dc6119c2565b6113e46119c2565b6113ee8383611a5b565b6113f784611b81565b600161011655611408600086611637565b6114327fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba286611637565b61145c7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8286611637565b6114867f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a2686611637565b61011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd15179055801561151857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b7f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd674156115498161162a565b816064811115611588576040517f3b17443400000000000000000000000000000000000000000000000000000000815260048101829052602401610943565b60005b818110156115ea5760008585838181106115a7576115a761238f565b905060200201359050600060ff1660b0600083815260200190815260200160002054036115e157600081815260b060205260409020600190555b5060010161158b565b507f9995fb3da0c2de4012f2b814b6fc29ce7507571dcb20b8d0bd38621a842df1eb848460405161161c9291906123be565b60405180910390a150505050565b6116348133611c42565b50565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661095657600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556116cd3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff161561095657600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600260b15403611852576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610943565b600260b155565b600081815260a5602052604090205460ff1615611634576040517f8698dd2b00000000000000000000000000000000000000000000000000000000815260048101829052602401610943565b600081815260b060205260409020546001146118ed576040517fa273b9e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600090815260b06020526040902060029055565b60004260995410156119245760975461191a90426122e9565b6099555080611935565b81609a5461193291906122e9565b90505b609854811115611971576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a5550565b600081815260a5602052604090205460ff16611634576040517f15d8d2e100000000000000000000000000000000000000000000000000000000815260048101829052602401610943565b600054610100900460ff16611a59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610943565b565b600054610100900460ff16611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610943565b81600003611b2c576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611b66576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60978290556098819055611b7a82426122e9565b6099555050565b600054610100900460ff16611c18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610943565b6116347f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd6741582611637565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661095657611c8281611cfc565b611c8d836020611d1b565b604051602001611c9e929190612434565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610943916004016124b5565b606061084173ffffffffffffffffffffffffffffffffffffffff831660145b60606000611d2a83600261230f565b611d359060026122e9565b67ffffffffffffffff811115611d4d57611d4d612506565b6040519080825280601f01601f191660200182016040528015611d77576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611dae57611dae61238f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611e1157611e1161238f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611e4d84600261230f565b611e589060016122e9565b90505b6001811115611ef5577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611e9957611e9961238f565b1a60f81b828281518110611eaf57611eaf61238f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611eee81612535565b9050611e5b565b508315611f5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610943565b9392505050565b600060208284031215611f7757600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611f5e57600080fd5b600060208284031215611fb957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461163457600080fd5b60008060408385031215611ff557600080fd5b82359150602083013561200781611fc0565b809150509250929050565b60008083601f84011261202457600080fd5b50813567ffffffffffffffff81111561203c57600080fd5b60208301915083602082850101111561205457600080fd5b9250929050565b60008060008060008060008060e0898b03121561207757600080fd5b883561208281611fc0565b9750602089013561209281611fc0565b9650604089013595506060890135945060808901356120b081611fc0565b935060a089013567ffffffffffffffff8111156120cc57600080fd5b6120d88b828c01612012565b999c989b50969995989497949560c00135949350505050565b6000806000806060858703121561210757600080fd5b843561211281611fc0565b935060208501359250604085013567ffffffffffffffff81111561213557600080fd5b61214187828801612012565b95989497509550505050565b6000806000806080858703121561216357600080fd5b843561216e81611fc0565b9350602085013561217e81611fc0565b93969395505050506040820135916060013590565b600080602083850312156121a657600080fd5b823567ffffffffffffffff808211156121be57600080fd5b818501915085601f8301126121d257600080fd5b8135818111156121e157600080fd5b8660208260051b85010111156121f657600080fd5b60209290920196919550909350505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401525086604083015285606083015284608083015260c060a083015261229d60c083018486612208565b9998505050505050505050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610841576108416122ba565b81810381811115610841576108416122ba565b8082028115828204841417610841576108416122ba565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612357576123576122ba565b5060010190565b858152846020820152836040820152608060608201526000612384608083018486612208565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156123f757600080fd5b8260051b80856040850137919091016040019392505050565b60005b8381101561242b578181015183820152602001612413565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161246c816017850160208801612410565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516124a9816028840160208801612410565b01602801949350505050565b60208152600082518060208401526124d4816040850160208701612410565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600081612544576125446122ba565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212203c1e23193a3a3d14166e51b9c2b8e6595df00bbebec7495efaec76ae5ace8ff464736f6c63430008130033
Deployed Bytecode
0x6080604052600436106102535760003560e01c806391f7b90111610138578063bcbd6fcd116100b0578063cc5782f61161007f578063d84f91e811610064578063d84f91e81461073a578063eb990c591461076e578063f4b476e11461078e57600080fd5b8063cc5782f6146106ea578063d547741f1461071a57600080fd5b8063bcbd6fcd14610656578063bf3e75051461068a578063c0729ab1146106be578063c1dc0f07146106d457600080fd5b8063ad422ff011610107578063b45a4f2c116100ec578063b45a4f2c146105eb578063b4a5a4b71461060b578063b837dbe91461063f57600080fd5b8063ad422ff0146105c0578063aea4f745146105d657600080fd5b806391f7b9011461054f5780639f3ce55a14610564578063a217fddf14610577578063abd6230d1461058c57600080fd5b8063557eac73116101cb57806374377a341161019a5780638264bd821161017f5780638264bd82146104c557806389945883146104e557806391d14854146104fc57600080fd5b806374377a341461047c5780637d1e8c55146104b057600080fd5b8063557eac73146103dc57806358794456146103fc57806367e404ce146104125780636a6379671461044857600080fd5b8063248a9ca31161022257806336568abe1161020757806336568abe1461037557806348922ab714610395578063491e0936146103bc57600080fd5b8063248a9ca3146103255780632f2ff15d1461035557600080fd5b806301ffc9a71461025f5780630f6893ca1461029457806311314d0f146102cf578063182a75061461030357600080fd5b3661025a57005b600080fd5b34801561026b57600080fd5b5061027f61027a366004611f65565b6107ae565b60405190151581526020015b60405180910390f35b3480156102a057600080fd5b506102c16102af366004611fa7565b60b06020526000908152604090205481565b60405190815260200161028b565b3480156102db57600080fd5b506102c17f9a80e24e463f00a8763c4dcec6a92d07d33272fa5db895d8589be70dccb002df81565b34801561030f57600080fd5b5061032361031e366004611fa7565b610847565b005b34801561033157600080fd5b506102c1610340366004611fa7565b60009081526065602052604090206001015490565b34801561036157600080fd5b50610323610370366004611fe2565b610878565b34801561038157600080fd5b50610323610390366004611fe2565b6108a2565b3480156103a157600080fd5b506103aa600181565b60405160ff909116815260200161028b565b3480156103c857600080fd5b506103236103d736600461205b565b61095a565b3480156103e857600080fd5b506103236103f7366004611fa7565b610ccf565b34801561040857600080fd5b506102c160995481565b34801561041e57600080fd5b506101155460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161028b565b34801561045457600080fd5b506102c17f06193bb948d6b7a6fcbe51c193ccf2183bb5d979b6ae5d3a6971b8851461d3b081565b34801561048857600080fd5b506102c17f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd6741581565b3480156104bc57600080fd5b506103aa600081565b3480156104d157600080fd5b506103236104e0366004611fa7565b610d97565b3480156104f157600080fd5b506102c16101175481565b34801561050857600080fd5b5061027f610517366004611fe2565b600091825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561055b57600080fd5b506103aa600281565b6103236105723660046120f1565b610e5d565b34801561058357600080fd5b506102c1600081565b34801561059857600080fd5b506102c17f21ea2f4fee4bcb623de15ac222ea5c1464307d884f23394b78ddc07f9c9c7cd881565b3480156105cc57600080fd5b506102c160985481565b3480156105e257600080fd5b506103236110fe565b3480156105f757600080fd5b50610323610606366004611fa7565b61115a565b34801561061757600080fd5b506102c17f3a56b1bd788a764cbd923badb6d0719f21f520455285bf6877e636d08708878d81565b34801561064b57600080fd5b506102c16101165481565b34801561066257600080fd5b506102c17fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba281565b34801561069657600080fd5b506102c17f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b3480156106ca57600080fd5b506102c1609a5481565b3480156106e057600080fd5b506102c160975481565b3480156106f657600080fd5b5061027f610705366004611fa7565b60a56020526000908152604090205460ff1681565b34801561072657600080fd5b50610323610735366004611fe2565b6111e9565b34801561074657600080fd5b506102c17f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a2681565b34801561077a57600080fd5b5061032361078936600461214d565b61120e565b34801561079a57600080fd5b506103236107a9366004612193565b61151f565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061084157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b7fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba26108718161162a565b5061011755565b6000828152606560205260409020600101546108938161162a565b61089d8383611637565b505050565b73ffffffffffffffffffffffffffffffffffffffff8116331461094c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b610956828261172b565b5050565b6109626117e6565b858784848760005a90506109957f9a80e24e463f00a8763c4dcec6a92d07d33272fa5db895d8589be70dccb002df611859565b6109be7f06193bb948d6b7a6fcbe51c193ccf2183bb5d979b6ae5d3a6971b8851461d3b0611859565b60008e8e8e8e8b8e8e6040516020016109dd9796959493929190612251565b6040516020818303038152906040528051906020012090506109fe816118a5565b8e61011560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d604051610a6b9291906122aa565b60006040518083038185875af1925050503d8060008114610aa8576040519150601f19603f3d011682016040523d82523d6000602084013e610aad565b606091505b509150915081610b1757805115610ac75780518082602001fd5b8f6040517f54613443000000000000000000000000000000000000000000000000000000008152600401610943919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b61011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd1517905560405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e90600090a2505086159050610cb557856000849003610c0157853b158015610bff573a5a610b9c61b98c866122e9565b610ba691906122fc565b610bb0919061230f565b915081881115610bfb5773ffffffffffffffffffffffffffffffffffffffff87166108fc610bde848b6122fc565b6040518115909202916000818181858888f1935050505050610bff565b8791505b505b600073ffffffffffffffffffffffffffffffffffffffff841615610c255783610c27565b335b905060008173ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050905080610cb1576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610943565b5050505b505050505050610cc5600160b155565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d82610cf98161162a565b6000806000426099541015610d2057609754610d1590426122e9565b609955506001610d32565b609a54851015610d3257849250600191505b60988590558080610d405750815b15610d4b57609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b80610da181611859565b7f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a26610dcb8161162a565b600083815260a56020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557fc343aefb875672fb1857ecda2bdf9fa822ff1e924e3714f6a3d88c5199dee261610e2a3390565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252602082018690520160405180910390a1505050565b610e867f21ea2f4fee4bcb623de15ac222ea5c1464307d884f23394b78ddc07f9c9c7cd8611859565b610eaf7f06193bb948d6b7a6fcbe51c193ccf2183bb5d979b6ae5d3a6971b8851461d3b0611859565b73ffffffffffffffffffffffffffffffffffffffff8416610efc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34831115610f36576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101175480841015610f74576040517f732f941300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61011654818503903486900390610f93610f8e84846122e9565b611901565b600033898585858b8b604051602001610fb29796959493929190612251565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012061011680549192506000610ffb83612326565b9091555050604051600090419087908381818185875af1925050503d8060008114611042576040519150601f19603f3d011682016040523d82523d6000602084013e611047565b606091505b5050905080611084576040517fa57c4df4000000000000000000000000000000000000000000000000000000008152416004820152602401610943565b818a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8888888e8e6040516110ea95949392919061235e565b60405180910390a450505050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d826111288161162a565b6000609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b8061116481611977565b7f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a2661118e8161162a565b600083815260a56020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557fb54c82d9fabaaa460c07181bb36c08c0e72d79293e77a42ac273c81d2a54281b33610e2a565b6000828152606560205260409020600101546112048161162a565b61089d838361172b565b600054610100900460ff161580801561122e5750600054600160ff909116105b806112485750303b158015611248575060005460ff166001145b6112d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610943565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561133257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b73ffffffffffffffffffffffffffffffffffffffff851661137f576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166113cc576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113d46119c2565b6113dc6119c2565b6113e46119c2565b6113ee8383611a5b565b6113f784611b81565b600161011655611408600086611637565b6114327fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba286611637565b61145c7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8286611637565b6114867f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a2686611637565b61011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd15179055801561151857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b7f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd674156115498161162a565b816064811115611588576040517f3b17443400000000000000000000000000000000000000000000000000000000815260048101829052602401610943565b60005b818110156115ea5760008585838181106115a7576115a761238f565b905060200201359050600060ff1660b0600083815260200190815260200160002054036115e157600081815260b060205260409020600190555b5060010161158b565b507f9995fb3da0c2de4012f2b814b6fc29ce7507571dcb20b8d0bd38621a842df1eb848460405161161c9291906123be565b60405180910390a150505050565b6116348133611c42565b50565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661095657600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556116cd3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff161561095657600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600260b15403611852576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610943565b600260b155565b600081815260a5602052604090205460ff1615611634576040517f8698dd2b00000000000000000000000000000000000000000000000000000000815260048101829052602401610943565b600081815260b060205260409020546001146118ed576040517fa273b9e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600090815260b06020526040902060029055565b60004260995410156119245760975461191a90426122e9565b6099555080611935565b81609a5461193291906122e9565b90505b609854811115611971576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a5550565b600081815260a5602052604090205460ff16611634576040517f15d8d2e100000000000000000000000000000000000000000000000000000000815260048101829052602401610943565b600054610100900460ff16611a59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610943565b565b600054610100900460ff16611af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610943565b81600003611b2c576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611b66576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60978290556098819055611b7a82426122e9565b6099555050565b600054610100900460ff16611c18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610943565b6116347f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd6741582611637565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661095657611c8281611cfc565b611c8d836020611d1b565b604051602001611c9e929190612434565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610943916004016124b5565b606061084173ffffffffffffffffffffffffffffffffffffffff831660145b60606000611d2a83600261230f565b611d359060026122e9565b67ffffffffffffffff811115611d4d57611d4d612506565b6040519080825280601f01601f191660200182016040528015611d77576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611dae57611dae61238f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611e1157611e1161238f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611e4d84600261230f565b611e589060016122e9565b90505b6001811115611ef5577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611e9957611e9961238f565b1a60f81b828281518110611eaf57611eaf61238f565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611eee81612535565b9050611e5b565b508315611f5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610943565b9392505050565b600060208284031215611f7757600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611f5e57600080fd5b600060208284031215611fb957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461163457600080fd5b60008060408385031215611ff557600080fd5b82359150602083013561200781611fc0565b809150509250929050565b60008083601f84011261202457600080fd5b50813567ffffffffffffffff81111561203c57600080fd5b60208301915083602082850101111561205457600080fd5b9250929050565b60008060008060008060008060e0898b03121561207757600080fd5b883561208281611fc0565b9750602089013561209281611fc0565b9650604089013595506060890135945060808901356120b081611fc0565b935060a089013567ffffffffffffffff8111156120cc57600080fd5b6120d88b828c01612012565b999c989b50969995989497949560c00135949350505050565b6000806000806060858703121561210757600080fd5b843561211281611fc0565b935060208501359250604085013567ffffffffffffffff81111561213557600080fd5b61214187828801612012565b95989497509550505050565b6000806000806080858703121561216357600080fd5b843561216e81611fc0565b9350602085013561217e81611fc0565b93969395505050506040820135916060013590565b600080602083850312156121a657600080fd5b823567ffffffffffffffff808211156121be57600080fd5b818501915085601f8301126121d257600080fd5b8135818111156121e157600080fd5b8660208260051b85010111156121f657600080fd5b60209290920196919550909350505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b600073ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401525086604083015285606083015284608083015260c060a083015261229d60c083018486612208565b9998505050505050505050565b8183823760009101908152919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610841576108416122ba565b81810381811115610841576108416122ba565b8082028115828204841417610841576108416122ba565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612357576123576122ba565b5060010190565b858152846020820152836040820152608060608201526000612384608083018486612208565b979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156123f757600080fd5b8260051b80856040850137919091016040019392505050565b60005b8381101561242b578181015183820152602001612413565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161246c816017850160208801612410565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516124a9816028840160208801612410565b01602801949350505050565b60208152600082518060208401526124d4816040850160208701612410565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600081612544576125446122ba565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea26469706673582212203c1e23193a3a3d14166e51b9c2b8e6595df00bbebec7495efaec76ae5ace8ff464736f6c63430008130033
Deployed Bytecode Sourcemap
70304:7474:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44005:215;;;;;;;;;;-1:-1:-1;44005:215:0;;;;;:::i;:::-;;:::i;:::-;;;516:14:1;;509:22;491:41;;479:2;464:18;44005:215:0;;;;;;;;58722:57;;;;;;;;;;-1:-1:-1;58722:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;874:25:1;;;862:2;847:18;58722:57:0;728:177:1;55755:72:0;;;;;;;;;;;;55798:29;55755:72;;75862:125;;;;;;;;;;-1:-1:-1;75862:125:0;;;;;:::i;:::-;;:::i;:::-;;45861:131;;;;;;;;;;-1:-1:-1;45861:131:0;;;;;:::i;:::-;45935:7;45962:12;;;:6;:12;;;;;:22;;;;45861:131;46302:147;;;;;;;;;;-1:-1:-1;46302:147:0;;;;;:::i;:::-;;:::i;47446:218::-;;;;;;;;;;-1:-1:-1;47446:218:0;;;;;:::i;:::-;;:::i;58307:47::-;;;;;;;;;;;;58353:1;58307:47;;;;;1928:4:1;1916:17;;;1898:36;;1886:2;1871:18;58307:47:0;1756:184:1;74666:1052:0;;;;;;;;;;-1:-1:-1;74666:1052:0;;;;;:::i;:::-;;:::i;68952:768::-;;;;;;;;;;-1:-1:-1;68952:768:0;;;;;:::i;:::-;;:::i;66938:31::-;;;;;;;;;;;;;;;;76118:84;;;;;;;;;;-1:-1:-1;76182:14:0;;76118:84;;76182:14;;;;3490:74:1;;3478:2;3463:18;76118:84:0;3344:226:1;55674:76:0;;;;;;;;;;;;55719:31;55674:76;;58474:90;;;;;;;;;;;;58526:38;58474:90;;58256:46;;;;;;;;;;;;58301:1;58256:46;;57364:202;;;;;;;;;;-1:-1:-1;57364:202:0;;;;;:::i;:::-;;:::i;70881:30::-;;;;;;;;;;;;;;;;44312:147;;;;;;;;;;-1:-1:-1;44312:147:0;;;;;:::i;:::-;44398:4;44422:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;;;;44312:147;58359:46;;;;;;;;;;;;58404:1;58359:46;;72817:1161;;;;;;:::i;:::-;;:::i;43406:49::-;;;;;;;;;;-1:-1:-1;43406:49:0;43451:4;43406:49;;55832:72;;;;;;;;;;;;55875:29;55832:72;;66766:25;;;;;;;;;;;;;;;;69919:169;;;;;;;;;;;;;:::i;57728:204::-;;;;;;;;;;-1:-1:-1;57728:204:0;;;;;:::i;:::-;;:::i;55909:90::-;;;;;;;;;;;;55961:38;55909:90;;70794:32;;;;;;;;;;;;;;;;70604:86;;;;;;;;;;;;70654:36;70604:86;;66602:84;;;;;;;;;;;;66651:35;66602:84;;67072:39;;;;;;;;;;;;;;;;66693:30;;;;;;;;;;;;;;;;56006:49;;;;;;;;;;-1:-1:-1;56006:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;46742:149;;;;;;;;;;-1:-1:-1;46742:149:0;;;;;:::i;:::-;;:::i;55591:76::-;;;;;;;;;;;;55636:31;55591:76;;71575:850;;;;;;;;;;-1:-1:-1;71575:850:0;;;;;:::i;:::-;;:::i;59786:662::-;;;;;;;;;;-1:-1:-1;59786:662:0;;;;;:::i;:::-;;:::i;44005:215::-;44090:4;44114:58;;;44129:43;44114:58;;:98;;-1:-1:-1;23227:36:0;23212:51;;;;44176:36;44107:105;44005:215;-1:-1:-1;;44005:215:0:o;75862:125::-;70654:36;43897:16;43908:4;43897:10;:16::i;:::-;-1:-1:-1;75954:15:0::1;:27:::0;75862:125::o;46302:147::-;45935:7;45962:12;;;:6;:12;;;;;:22;;;43897:16;43908:4;43897:10;:16::i;:::-;46416:25:::1;46427:4;46433:7;46416:10;:25::i;:::-;46302:147:::0;;;:::o;47446:218::-;47542:23;;;20637:10;47542:23;47534:83;;;;;;;5544:2:1;47534:83:0;;;5526:21:1;5583:2;5563:18;;;5556:30;5622:34;5602:18;;;5595:62;5693:17;5673:18;;;5666:45;5728:19;;47534:83:0;;;;;;;;;47630:26;47642:4;47648:7;47630:11;:26::i;:::-;47446:218;;:::o;74666:1052::-;52586:21;:19;:21::i;:::-;74896:4:::1;74902:3;74907:9;;74918:13;76731:19;76753:9;76731:31;;74940:39:::2;55798:29;74940:21;:39::i;:::-;74986:41;55719:31;74986:21;:41::i;:::-;75036:19;75079:5;75086:3;75091:4;75097:6;75105;75113:9;;75068:55;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;75058:66;;;;;;75036:88;;75198:46;75232:11;75198:33;:46::i;:::-;75270:5;75253:14;;:22;;;;;;;;;;;;;;;;;;75285:16;75303:23:::0;75330:3:::2;:8;;75347:6;75356:9;;75330:36;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75284:82;;;;75378:11;75373:257;;75404:17:::0;;:21;75400:223:::2;;75483:10;75477:17;75534:9;75521:10;75517:2;75513:19;75506:38;75400:223;75609:3;75588:25;;;;;;;;;;3520:42:1::0;3508:55;;;;3490:74;;3478:2;3463:18;;3344:226;75400:223:0::2;75638:14;:35:::0;;;::::2;75663:9;75638:35;::::0;;75685:27:::2;::::0;75700:11;;75685:27:::2;::::0;75638:14:::2;::::0;75685:27:::2;-1:-1:-1::0;;76827:13:0;;;-1:-1:-1;76823:947:0::1;;76903:9:::0;76881:19:::1;76964:21:::0;;;76960:563:::1;;77081:16:::0;::::1;77074:24;77155:359:::0;::::1;;;77319:11;77306:9;77267:36;71066:5;77267:11:::0;:36:::1;:::i;:::-;:48;;;;:::i;:::-;77266:64;;;;:::i;:::-;77252:78;;77361:11;77349:9;:23;77345:158;;;77389:17;::::0;::::1;:42;77407:23;77419:11:::0;77407:9;:23:::1;:::i;:::-;77389:42;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;77345:158;;;77480:9;77466:23;;77345:158;76987:536;76960:563;77533:19;77555:27;::::0;::::1;::::0;:56:::1;;77598:13;77555:56;;;77585:10;77555:56;77533:78;;77622:16;77649:11;77641:25;;:38;77667:11;77641:38;;;;;;;;;;;;;;;;;;;;;;;77622:57;;77693:11;77688:75;;77724:29;::::0;::::1;::::0;;3520:42:1;3508:55;;77724:29:0::1;::::0;::::1;3490:74:1::0;3463:18;;77724:29:0::1;3344:226:1::0;77688:75:0::1;76842:928;;;76823:947;76703:1072;52618:1;;;;;52630:20:::0;51847:1;53150:7;:22;52967:213;52630:20;74666:1052;;;;;;;;:::o;68952:768::-;66651:35;43897:16;43908:4;43897:10;:16::i;:::-;69048:28:::1;69083:29:::0;69119:26:::1;69177:15;69158:16;;:34;69154:301;;;69240:15;::::0;69222:33:::1;::::0;:15:::1;:33;:::i;:::-;69203:16;:52:::0;-1:-1:-1;69288:4:0::1;69154:301;;;69329:24;;69319:7;:34;69315:133;;;69389:7;69366:30;;69434:4;69407:31;;69315:133;69463:10;:20:::0;;;69496:21;;:49:::1;;;69521:24;69496:49;69492:119;;;69556:24;:47:::0;;;69492:119:::1;69624:90;::::0;;7866:25:1;;;7934:14;;7927:22;7922:2;7907:18;;7900:50;7993:14;;7986:22;7966:18;;;7959:50;69624:90:0;;20637:10;;69624:90:::1;::::0;;;;;7854:2:1;69624:90:0;;::::1;69041:679;;;68952:768:::0;;:::o;57364:202::-;57432:10;56312:33;56334:10;56312:21;:33::i;:::-;55636:31:::1;43897:16;43908:4;43897:10;:16::i;:::-;57480:29:::2;::::0;;;:17:::2;:29;::::0;;;;:36;;;::::2;57512:4;57480:36;::::0;;57528:32:::2;57535:12;20637:10:::0;;20557:98;57535:12:::2;57528:32;::::0;;8224:42:1;8212:55;;;8194:74;;8299:2;8284:18;;8277:34;;;8167:18;57528:32:0::2;;;;;;;56352:1:::1;57364:202:::0;;:::o;72817:1161::-;72915:39;55875:29;72915:21;:39::i;:::-;72961:41;55719:31;72961:21;:41::i;:::-;73015:17;;;73011:70;;73050:23;;;;;;;;;;;;;;73011:70;73100:9;73093:4;:16;73089:63;;;73127:17;;;;;;;;;;;;;;73089:63;73182:15;;73210:18;;;73206:59;;;73246:11;;;;;;;;;;;;;;73206:59;73451:17;;73356:18;;;;73395:9;:16;;;;73535:38;73550:22;73356:18;73395:16;73550:22;:::i;:::-;73535:14;:38::i;:::-;73582:19;73625:10;73637:3;73642:10;73654:9;73665:13;73680:9;;73614:76;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;73604:87;;73614:76;73604:87;;;;73700:17;:19;;73604:87;;-1:-1:-1;73700:17:0;:19;;;:::i;:::-;;;;-1:-1:-1;;73747:45:0;;73729:12;;73747:14;;73775:11;;73729:12;73747:45;73729:12;73747:45;73775:11;73747:14;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73728:64;;;73804:7;73799:70;;73829:32;;;;;73846:14;73829:32;;;3490:74:1;3463:18;;73829:32:0;3344:226:1;73799:70:0;73960:11;73906:3;73882:90;;73894:10;73882:90;;;73911:10;73923:9;73934:13;73949:9;;73882:90;;;;;;;;;;:::i;:::-;;;;;;;;72908:1070;;;;;;72817:1161;;;;:::o;69919:169::-;66651:35;43897:16;43908:4;43897:10;:16::i;:::-;70030:1:::1;70003:24;:28:::0;;;70045:37:::1;::::0;20637:10;;70045:37:::1;::::0;::::1;69919:169:::0;:::o;57728:204::-;57795:10;56577:30;56596:10;56577:18;:30::i;:::-;55636:31:::1;43897:16;43908:4;43897:10;:16::i;:::-;57875:5:::2;57843:29:::0;;;:17:::2;:29;::::0;;;;:37;;;::::2;::::0;;57892:34:::2;20637:10:::0;57901:12:::2;20557:98:::0;46742:149;45935:7;45962:12;;;:6;:12;;;;;:22;;;43897:16;43908:4;43897:10;:16::i;:::-;46857:26:::1;46869:4;46875:7;46857:11;:26::i;71575:850::-:0;16229:19;16252:13;;;;;;16251:14;;16299:34;;;;-1:-1:-1;16317:12:0;;16332:1;16317:12;;;;:16;16299:34;16298:108;;;-1:-1:-1;16378:4:0;4995:19;:23;;;16339:66;;-1:-1:-1;16388:12:0;;;;;:17;16339:66;16276:204;;;;;;;9637:2:1;16276:204:0;;;9619:21:1;9676:2;9656:18;;;9649:30;9715:34;9695:18;;;9688:62;9786:16;9766:18;;;9759:44;9820:19;;16276:204:0;9435:410:1;16276:204:0;16491:12;:16;;;;16506:1;16491:16;;;16518:67;;;;16553:13;:20;;;;;;;;16518:67;71756:30:::1;::::0;::::1;71752:83;;71804:23;;;;;;;;;;;;;;71752:83;71847:32;::::0;::::1;71843:85;;71897:23;;;;;;;;;;;;;;71843:85;71936:15;:13;:15::i;:::-;71958:16;:14;:16::i;:::-;71981:22;:20;:22::i;:::-;72010:54;72029:16;72047;72010:18;:54::i;:::-;72071:43;72095:18;72071:23;:43::i;:::-;72143:1;72123:17;:21:::0;72153:48:::1;43451:4;72184:16:::0;72153:10:::1;:48::i;:::-;72208:53;70654:36;72244:16;72208:10;:53::i;:::-;72268:52;66651:35;72303:16;72268:10;:52::i;:::-;72327:48;55636:31;72358:16;72327:10;:48::i;:::-;72384:14;:35:::0;;;::::1;72409:9;72384:35;::::0;;16607:102;;;;16658:5;16642:21;;;;;;16683:14;;-1:-1:-1;1898:36:1;;16683:14:0;;1886:2:1;1871:18;16683:14:0;;;;;;;16607:102;16218:498;71575:850;;;;:::o;59786:662::-;58526:38;43897:16;43908:4;43897:10;:16::i;:::-;59933:14;59989:3:::1;59967:25:::0;::::1;59963:119;;;60010:64;::::0;::::1;::::0;;::::1;::::0;::::1;874:25:1::0;;;847:18;;60010:64:0::1;728:177:1::0;59963:119:0::1;60095:9;60090:294;60110:19;60106:1;:23;60090:294;;;60142:19;60164:14;;60179:1;60164:17;;;;;;;:::i;:::-;;;;;;;60142:39;;58301:1;60194:59;;:22;:35;60217:11;60194:35;;;;;;;;;;;;:59:::0;60190:145:::1;;60266:35;::::0;;;:22:::1;:35;::::0;;;;58353:1:::1;60266:59:::0;;60190:145:::1;-1:-1:-1::0;60364:3:0::1;;60090:294;;;;60397:45;60427:14;;60397:45;;;;;;;:::i;:::-;;;;;;;;59896:552;59786:662:::0;;;:::o;44763:105::-;44830:30;44841:4;20637:10;44830;:30::i;:::-;44763:105;:::o;49043:238::-;44398:4;44422:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;49122:152;;49166:12;;;;:6;:12;;;;;;;;:29;;;;;;;;;;:36;;;;49198:4;49166:36;;;49249:12;20637:10;;20557:98;49249:12;49222:40;;49240:7;49222:40;;49234:4;49222:40;;;;;;;;;;49043:238;;:::o;49461:239::-;44398:4;44422:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;49541:152;;;49616:5;49584:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;:37;;;;;;49641:40;20637:10;;49584:12;;49641:40;;49616:5;49641:40;49461:239;;:::o;52666:293::-;51891:1;52800:7;;:19;52792:63;;;;;;;10935:2:1;52792:63:0;;;10917:21:1;10974:2;10954:18;;;10947:30;11013:33;10993:18;;;10986:61;11064:18;;52792:63:0;10733:355:1;52792:63:0;51891:1;52933:7;:18;52666:293::o;57040:164::-;57124:29;;;;:17;:29;;;;;;;;57120:79;;;57171:20;;;;;;;;874:25:1;;;847:18;;57171:20:0;728:177:1;60600:289:0;60685:36;;;;:22;:36;;;;;;58353:1;60685:61;60681:135;;60764:44;;;;;;;;;;;;;;60681:135;60824:36;;;;:22;:36;;;;;58404:1;60824:59;;60600:289::o;68025:500::-;68086:31;68149:15;68130:16;;:34;68126:242;;;68212:15;;68194:33;;:15;:33;:::i;:::-;68175:16;:52;-1:-1:-1;68262:11:0;68126:242;;;68349:11;68322:24;;:38;;;;:::i;:::-;68296:64;;68126:242;68406:10;;68380:23;:36;68376:85;;;68434:19;;;;;;;;;;;;;;68376:85;68469:24;:50;-1:-1:-1;68025:500:0:o;56750:165::-;56832:29;;;;:17;:29;;;;;;;;56827:83;;56879:23;;;;;;;;874:25:1;;;847:18;;56879:23:0;728:177:1;22897:59:0;18372:13;;;;;;;18364:69;;;;;;;11295:2:1;18364:69:0;;;11277:21:1;11334:2;11314:18;;;11307:30;11373:34;11353:18;;;11346:62;11444:13;11424:18;;;11417:41;11475:19;;18364:69:0;11093:407:1;18364:69:0;22897:59::o;67366:379::-;18372:13;;;;;;;18364:69;;;;;;;11295:2:1;18364:69:0;;;11277:21:1;11334:2;11314:18;;;11307:30;11373:34;11353:18;;;11346:62;11444:13;11424:18;;;11417:41;11475:19;;18364:69:0;11093:407:1;18364:69:0;67478:16:::1;67498:1;67478:21:::0;67474:65:::1;;67517:14;;;;;;;;;;;;;;67474:65;67551:11;67566:1;67551:16:::0;67547:59:::1;;67585:13;;;;;;;;;;;;;;67547:59;67614:15;:34:::0;;;67655:10:::1;:24:::0;;;67705:34:::1;67632:16:::0;67705:15:::1;:34;:::i;:::-;67686:16;:53:::0;-1:-1:-1;;67366:379:0:o;59388:157::-;18372:13;;;;;;;18364:69;;;;;;;11295:2:1;18364:69:0;;;11277:21:1;11334:2;11314:18;;;11307:30;11373:34;11353:18;;;11346:62;11444:13;11424:18;;;11417:41;11475:19;;18364:69:0;11093:407:1;18364:69:0;59482:57:::1;58526:38;59520:18;59482:10;:57::i;45158:514::-:0;44398:4;44422:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;45242:423;;45435:39;45466:7;45435:30;:39::i;:::-;45547:49;45586:4;45593:2;45547:30;:49::i;:::-;45340:279;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;45286:367;;;;;;;;:::i;40669:151::-;40727:13;40760:52;40772:22;;;38511:2;40065:447;40140:13;40166:19;40198:10;40202:6;40198:1;:10;:::i;:::-;:14;;40211:1;40198:14;:::i;:::-;40188:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40188:25:0;;40166:47;;40224:15;:6;40231:1;40224:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;;40250;:6;40257:1;40250:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;-1:-1:-1;40281:9:0;40293:10;40297:6;40293:1;:10;:::i;:::-;:14;;40306:1;40293:14;:::i;:::-;40281:26;;40276:131;40313:1;40309;:5;40276:131;;;40348:8;40357:5;40365:3;40357:11;40348:21;;;;;;;:::i;:::-;;;;40336:6;40343:1;40336:9;;;;;;;;:::i;:::-;;;;:33;;;;;;;;;;-1:-1:-1;40394:1:0;40384:11;;;;;40316:3;;;:::i;:::-;;;40276:131;;;-1:-1:-1;40425:10:0;;40417:55;;;;;;;13629:2:1;40417:55:0;;;13611:21:1;;;13648:18;;;13641:30;13707:34;13687:18;;;13680:62;13759:18;;40417:55:0;13427:356:1;40417:55:0;40497:6;40065:447;-1:-1:-1;;;40065:447:0:o;14:332:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;543:180;602:6;655:2;643:9;634:7;630:23;626:32;623:52;;;671:1;668;661:12;623:52;-1:-1:-1;694:23:1;;543:180;-1:-1:-1;543:180:1:o;1277:154::-;1363:42;1356:5;1352:54;1345:5;1342:65;1332:93;;1421:1;1418;1411:12;1436:315;1504:6;1512;1565:2;1553:9;1544:7;1540:23;1536:32;1533:52;;;1581:1;1578;1571:12;1533:52;1617:9;1604:23;1594:33;;1677:2;1666:9;1662:18;1649:32;1690:31;1715:5;1690:31;:::i;:::-;1740:5;1730:15;;;1436:315;;;;;:::o;1945:347::-;1996:8;2006:6;2060:3;2053:4;2045:6;2041:17;2037:27;2027:55;;2078:1;2075;2068:12;2027:55;-1:-1:-1;2101:20:1;;2144:18;2133:30;;2130:50;;;2176:1;2173;2166:12;2130:50;2213:4;2205:6;2201:17;2189:29;;2265:3;2258:4;2249:6;2241;2237:19;2233:30;2230:39;2227:59;;;2282:1;2279;2272:12;2227:59;1945:347;;;;;:::o;2297:1042::-;2429:6;2437;2445;2453;2461;2469;2477;2485;2538:3;2526:9;2517:7;2513:23;2509:33;2506:53;;;2555:1;2552;2545:12;2506:53;2594:9;2581:23;2613:31;2638:5;2613:31;:::i;:::-;2663:5;-1:-1:-1;2720:2:1;2705:18;;2692:32;2733:33;2692:32;2733:33;:::i;:::-;2785:7;-1:-1:-1;2839:2:1;2824:18;;2811:32;;-1:-1:-1;2890:2:1;2875:18;;2862:32;;-1:-1:-1;2946:3:1;2931:19;;2918:33;2960;2918;2960;:::i;:::-;3012:7;-1:-1:-1;3070:3:1;3055:19;;3042:33;3098:18;3087:30;;3084:50;;;3130:1;3127;3120:12;3084:50;3169:58;3219:7;3210:6;3199:9;3195:22;3169:58;:::i;:::-;2297:1042;;;;-1:-1:-1;2297:1042:1;;;;;;3143:84;;3328:3;3313:19;3300:33;;2297:1042;-1:-1:-1;;;;2297:1042:1:o;3575:612::-;3663:6;3671;3679;3687;3740:2;3728:9;3719:7;3715:23;3711:32;3708:52;;;3756:1;3753;3746:12;3708:52;3795:9;3782:23;3814:31;3839:5;3814:31;:::i;:::-;3864:5;-1:-1:-1;3916:2:1;3901:18;;3888:32;;-1:-1:-1;3971:2:1;3956:18;;3943:32;3998:18;3987:30;;3984:50;;;4030:1;4027;4020:12;3984:50;4069:58;4119:7;4110:6;4099:9;4095:22;4069:58;:::i;:::-;3575:612;;;;-1:-1:-1;4146:8:1;-1:-1:-1;;;;3575:612:1:o;4192:525::-;4278:6;4286;4294;4302;4355:3;4343:9;4334:7;4330:23;4326:33;4323:53;;;4372:1;4369;4362:12;4323:53;4411:9;4398:23;4430:31;4455:5;4430:31;:::i;:::-;4480:5;-1:-1:-1;4537:2:1;4522:18;;4509:32;4550:33;4509:32;4550:33;:::i;:::-;4192:525;;4602:7;;-1:-1:-1;;;;4656:2:1;4641:18;;4628:32;;4707:2;4692:18;4679:32;;4192:525::o;4722:615::-;4808:6;4816;4869:2;4857:9;4848:7;4844:23;4840:32;4837:52;;;4885:1;4882;4875:12;4837:52;4925:9;4912:23;4954:18;4995:2;4987:6;4984:14;4981:34;;;5011:1;5008;5001:12;4981:34;5049:6;5038:9;5034:22;5024:32;;5094:7;5087:4;5083:2;5079:13;5075:27;5065:55;;5116:1;5113;5106:12;5065:55;5156:2;5143:16;5182:2;5174:6;5171:14;5168:34;;;5198:1;5195;5188:12;5168:34;5251:7;5246:2;5236:6;5233:1;5229:14;5225:2;5221:23;5217:32;5214:45;5211:65;;;5272:1;5269;5262:12;5211:65;5303:2;5295:11;;;;;5325:6;;-1:-1:-1;4722:615:1;;-1:-1:-1;;;;4722:615:1:o;5758:325::-;5846:6;5841:3;5834:19;5898:6;5891:5;5884:4;5879:3;5875:14;5862:43;;5950:1;5943:4;5934:6;5929:3;5925:16;5921:27;5914:38;5816:3;6072:4;6002:66;5997:2;5989:6;5985:15;5981:88;5976:3;5972:98;5968:109;5961:116;;5758:325;;;;:::o;6088:682::-;6348:4;6377:42;6458:2;6450:6;6446:15;6435:9;6428:34;6510:2;6502:6;6498:15;6493:2;6482:9;6478:18;6471:43;;6550:6;6545:2;6534:9;6530:18;6523:34;6593:6;6588:2;6577:9;6573:18;6566:34;6637:6;6631:3;6620:9;6616:19;6609:35;6681:3;6675;6664:9;6660:19;6653:32;6702:62;6759:3;6748:9;6744:19;6736:6;6728;6702:62;:::i;:::-;6694:70;6088:682;-1:-1:-1;;;;;;;;;6088:682:1:o;6775:271::-;6958:6;6950;6945:3;6932:33;6914:3;6984:16;;7009:13;;;6984:16;6775:271;-1:-1:-1;6775:271:1:o;7051:184::-;7103:77;7100:1;7093:88;7200:4;7197:1;7190:15;7224:4;7221:1;7214:15;7240:125;7305:9;;;7326:10;;;7323:36;;;7339:18;;:::i;7370:128::-;7437:9;;;7458:11;;;7455:37;;;7472:18;;:::i;7503:168::-;7576:9;;;7607;;7624:15;;;7618:22;;7604:37;7594:71;;7645:18;;:::i;8322:195::-;8361:3;8392:66;8385:5;8382:77;8379:103;;8462:18;;:::i;:::-;-1:-1:-1;8509:1:1;8498:13;;8322:195::o;8971:459::-;9212:6;9201:9;9194:25;9255:6;9250:2;9239:9;9235:18;9228:34;9298:6;9293:2;9282:9;9278:18;9271:34;9341:3;9336:2;9325:9;9321:18;9314:31;9175:4;9362:62;9419:3;9408:9;9404:19;9396:6;9388;9362:62;:::i;:::-;9354:70;8971:459;-1:-1:-1;;;;;;;8971:459:1:o;10049:184::-;10101:77;10098:1;10091:88;10198:4;10195:1;10188:15;10222:4;10219:1;10212:15;10238:490;10427:2;10416:9;10409:21;10466:6;10461:2;10450:9;10446:18;10439:34;10390:4;10496:66;10488:6;10485:78;10482:98;;;10576:1;10573;10566:12;10482:98;10610:6;10607:1;10603:14;10667:6;10659;10654:2;10643:9;10639:18;10626:48;10695:22;;;;10719:2;10691:31;;10238:490;-1:-1:-1;;;10238:490:1:o;11505:250::-;11590:1;11600:113;11614:6;11611:1;11608:13;11600:113;;;11690:11;;;11684:18;11671:11;;;11664:39;11636:2;11629:10;11600:113;;;-1:-1:-1;;11747:1:1;11729:16;;11722:27;11505:250::o;11760:812::-;12171:25;12166:3;12159:38;12141:3;12226:6;12220:13;12242:75;12310:6;12305:2;12300:3;12296:12;12289:4;12281:6;12277:17;12242:75;:::i;:::-;12381:19;12376:2;12336:16;;;12368:11;;;12361:40;12426:13;;12448:76;12426:13;12510:2;12502:11;;12495:4;12483:17;;12448:76;:::i;:::-;12544:17;12563:2;12540:26;;11760:812;-1:-1:-1;;;;11760:812:1:o;12577:455::-;12726:2;12715:9;12708:21;12689:4;12758:6;12752:13;12801:6;12796:2;12785:9;12781:18;12774:34;12817:79;12889:6;12884:2;12873:9;12869:18;12864:2;12856:6;12852:15;12817:79;:::i;:::-;12948:2;12936:15;12953:66;12932:88;12917:104;;;;13023:2;12913:113;;12577:455;-1:-1:-1;;12577:455:1:o;13037:184::-;13089:77;13086:1;13079:88;13186:4;13183:1;13176:15;13210:4;13207:1;13200:15;13226:196;13265:3;13293:5;13283:39;;13302:18;;:::i;:::-;-1:-1:-1;13349:66:1;13338:78;;13226:196::o
Swarm Source
ipfs://3c1e23193a3a3d14166e51b9c2b8e6595df00bbebec7495efaec76ae5ace8ff4
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.