Latest 25 from a total of 1,074 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer To W Pe... | 38649132 | 3 hrs ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38648925 | 3 hrs ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38648733 | 3 hrs ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38597490 | 17 hrs ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38596907 | 17 hrs ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38595462 | 18 hrs ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38595343 | 18 hrs ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38544299 | 32 hrs ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38543438 | 32 hrs ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38535444 | 34 hrs ago | IN | 0.000005 ETH | 0.00000038 | ||||
| Transfer To | 38503938 | 43 hrs ago | IN | 0.000005 ETH | 0.00000023 | ||||
| Transfer To W Pe... | 38483227 | 2 days ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38483103 | 2 days ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38431317 | 2 days ago | IN | 0.000005 ETH | 0.00000018 | ||||
| Transfer To W Pe... | 38431152 | 2 days ago | IN | 0.000005 ETH | 0.00000018 | ||||
| Transfer To W Pe... | 38431052 | 2 days ago | IN | 0.000005 ETH | 0.00000018 | ||||
| Transfer To W Pe... | 38430939 | 2 days ago | IN | 0.000005 ETH | 0.00000018 | ||||
| Transfer To W Pe... | 38426110 | 2 days ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38425992 | 2 days ago | IN | 0.000005 ETH | 0.00000026 | ||||
| Transfer To W Pe... | 38406328 | 2 days ago | IN | 0.000005 ETH | 0.00000018 | ||||
| Transfer To W Pe... | 38406177 | 2 days ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38388452 | 3 days ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38388273 | 3 days ago | IN | 0.000005 ETH | 0.00000025 | ||||
| Transfer To W Pe... | 38386372 | 3 days ago | IN | 0.000005 ETH | 0.00000026 | ||||
| Transfer To W Pe... | 38386187 | 3 days ago | IN | 0.000005 ETH | 0.00000025 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 38649132 | 3 hrs ago | 0.000005 ETH | ||||
| 38648925 | 3 hrs ago | 0.000005 ETH | ||||
| 38648733 | 3 hrs ago | 0.000005 ETH | ||||
| 38597490 | 17 hrs ago | 0.000005 ETH | ||||
| 38596907 | 17 hrs ago | 0.000005 ETH | ||||
| 38595462 | 18 hrs ago | 0.000005 ETH | ||||
| 38595343 | 18 hrs ago | 0.000005 ETH | ||||
| 38544299 | 32 hrs ago | 0.000005 ETH | ||||
| 38543438 | 32 hrs ago | 0.000005 ETH | ||||
| 38535444 | 34 hrs ago | 0.000005 ETH | ||||
| 38503938 | 43 hrs ago | 0.000005 ETH | ||||
| 38483227 | 2 days ago | 0.000005 ETH | ||||
| 38483103 | 2 days ago | 0.000005 ETH | ||||
| 38431317 | 2 days ago | 0.000005 ETH | ||||
| 38431152 | 2 days ago | 0.000005 ETH | ||||
| 38431052 | 2 days ago | 0.000005 ETH | ||||
| 38430939 | 2 days ago | 0.000005 ETH | ||||
| 38426110 | 2 days ago | 0.000005 ETH | ||||
| 38425992 | 2 days ago | 0.000005 ETH | ||||
| 38406328 | 2 days ago | 0.000005 ETH | ||||
| 38406177 | 2 days ago | 0.000005 ETH | ||||
| 38388452 | 3 days ago | 0.000005 ETH | ||||
| 38388273 | 3 days ago | 0.000005 ETH | ||||
| 38386372 | 3 days ago | 0.000005 ETH | ||||
| 38386187 | 3 days ago | 0.000005 ETH |
Cross-Chain Transactions
Contract Source Code (Solidity)
/** *Submitted for verification at uniscan.xyz on 2025-11-24 */ // Sources flattened with hardhat v2.26.2 https://hardhat.org // SPDX-License-Identifier: BUSL-1.1 AND MIT // File @openzeppelin/contracts/access/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File @openzeppelin/contracts/utils/introspection/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File @openzeppelin/contracts/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // 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/utils/math/[email protected] // Original license: SPDX_License_Identifier: MIT // 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 SignedMath { /** * @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/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.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, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @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/access/[email protected] // Original license: SPDX_License_Identifier: MIT // 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 AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File @openzeppelin/contracts/security/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File @openzeppelin/contracts/token/ERC20/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); } // File @openzeppelin/contracts/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // 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 Address { /** * @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/token/ERC20/utils/[email protected] // Original license: SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } } // File @openzeppelin/contracts/security/[email protected] // Original license: SPDX_License_Identifier: MIT // 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 ReentrancyGuard { // 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; constructor() { _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; } } // File contracts/modules/chain-abstraction/interfaces/IAssetController.sol // Original license: SPDX_License_Identifier: MIT pragma solidity >=0.8.19 <=0.8.20; interface IAssetController { function token() external view returns (address); function transferTo( address recipient, uint256 amount, bool unwrap, uint256 destChainId, address bridgeAdapter, bytes memory bridgeOptions ) external payable; function transferTo( address recipient, uint256 amount, bool unwrap, uint256 destChainId, address[] memory adapters, uint256[] memory fees, bytes[] memory options ) external payable; function resendTransfer(bytes32 transferId, address adapter, bytes memory options) external payable; function resendTransfer(bytes32 transferId, address[] memory adapters, uint256[] memory fees, bytes[] memory options) external payable; } // File contracts/modules/chain-abstraction/wrappers/ControllerWrapper.sol // Original license: SPDX_License_Identifier: BUSL-1.1 pragma solidity 0.8.19; contract ControllerWrapper is AccessControl, ReentrancyGuard, Pausable { using SafeERC20 for IERC20; // ===== Events ===== event TransferSent( address indexed sender, address indexed controller, bool resent, bool multi, uint256 grossAmount, uint256 netAmount, bytes data ); event FeesCollected(address indexed payer, address indexed token, address indexed controller, uint256 feeAmount, address treasury); event FeeRateSet(uint256 oldRate, uint256 newRate); event TreasurySet(address indexed oldTreasury, address indexed newTreasury); event ControllerWhitelisted(address indexed controller, bool whitelisted); event ControllerFeeTiersSet(address indexed controller, uint256 indexed destChainId, uint256[] thresholds, uint256[] rates); event DestChainPremiumSet(uint256 indexed destChainId, uint256 rate); // ===== Errors ===== error Wrapper_ControllerNotWhitelisted(); error Wrapper_LengthMismatch(); error Wrapper_InvalidParams(); error Wrapper_InvalidFeeRate(); error Wrapper_TreasuryZeroAddress(); error Wrapper_ZeroAddress(); error Wrapper_FeeOnTransferTokenNotSupported(); error Wrapper_TransferFailed(); error Wrapper_Unauthorized(); struct PermitData { uint256 deadline; uint8 v; bytes32 r; bytes32 s; } struct DepositInput { address controller; address recipient; uint256 amount; bool unwrap; uint256 destChainId; } // ===== Tiered Fee Mechanism ===== struct FeeTier { uint256 threshold; // minimum amount for this tier (inclusive) uint256 rate; // fee rate for this tier } // Up to 3 tiers per (controller, destChainId) struct FeeTierConfig { FeeTier[3] tiers; // sorted ascending by threshold uint8 count; // number of active tiers (0-3) } // ===== Storage ===== bytes32 public constant CONTROLLER_MANAGER_ROLE = keccak256("CONTROLLER_MANAGER_ROLE"); uint256 public constant RATE_DENOMINATOR = 100_000; // 100.00% uint256 public constant MAX_FEE_RATE = 5_000; // 5.00% uint256 public feeRate; // global base rate address public treasury; // fee recipient mapping(address => bool) public controllers; // whitelist // controller => destChainId => FeeTierConfig mapping(address => mapping(uint256 => FeeTierConfig)) private _controllerFeeTiers; // Per-destination premium added on top of base (then clamped) mapping(uint256 => uint256) public destChainPremiumRate; // per-destination premium rate /** * @param access The addresses for access control: [admin, controller manager] * @param _treasury The treasury address for fee collection * @param _feeRate The global fee rate * @param initialControllers The initial whitelisted controllers * @param premiumChainIds The destination chain IDs for premium rates * @param premiumRate The premium rates corresponding to the destination chain IDs */ constructor( address[2] memory access, // admin, controller manager address _treasury, uint256 _feeRate, address[] memory initialControllers, uint256[] memory premiumChainIds, uint256[] memory premiumRate ) { _grantRole(DEFAULT_ADMIN_ROLE, access[0]); _grantRole(CONTROLLER_MANAGER_ROLE, access[1]); // Treasury + global rate if (_treasury == address(0) && _feeRate > 0) revert Wrapper_TreasuryZeroAddress(); if (_feeRate > MAX_FEE_RATE) revert Wrapper_InvalidFeeRate(); treasury = _treasury; feeRate = _feeRate; emit TreasurySet(address(0), _treasury); emit FeeRateSet(0, _feeRate); // Whitelist for (uint256 i = 0; i < initialControllers.length; i++) { controllers[initialControllers[i]] = true; emit ControllerWhitelisted(initialControllers[i], true); } // No tiered fee configuration in constructor. Use setControllerFeeTiers after deployment if needed. // Destination premiums if (premiumChainIds.length != premiumRate.length) revert Wrapper_LengthMismatch(); for (uint256 i = 0; i < premiumChainIds.length; i++) { if (premiumRate[i] > MAX_FEE_RATE) revert Wrapper_InvalidFeeRate(); destChainPremiumRate[premiumChainIds[i]] = premiumRate[i]; emit DestChainPremiumSet(premiumChainIds[i], premiumRate[i]); } } /// @dev limits the function callers to `admin` or `controller manager` modifier adminOrManager() { if (!(hasRole(DEFAULT_ADMIN_ROLE, msg.sender) || hasRole(CONTROLLER_MANAGER_ROLE, msg.sender))) { revert Wrapper_Unauthorized(); } _; } // ===== External ===== /** * @notice Transfer assets to a recipient on a destination chain via the specified controller and a single adapter. * An ERC20 approval of the amount must be given to this contract prior to calling this function. * @param input The deposit input parameters. * @param adapter The bridge adapter to use. * @param bridgeOptions Additional options for the bridge. * @param data Arbitrary data for logging purposes. */ function transferTo( DepositInput calldata input, address adapter, bytes calldata bridgeOptions, bytes calldata data ) external payable nonReentrant whenNotPaused { (address token, uint256 net) = _process(input.controller, input.amount, input.destChainId); IAssetController(input.controller).transferTo{value: msg.value}( input.recipient, net, input.unwrap, input.destChainId, adapter, bridgeOptions ); IERC20(token).forceApprove(input.controller, 0); emit TransferSent(msg.sender, input.controller, false, false, input.amount, net, data); } /** * @notice Transfer assets to a recipient on a destination chain via the specified controller and a single adapter, using permit for approval. * @param input The deposit input parameters. * @param permit The permit data for ERC20 approval. * @param adapter The bridge adapter to use. * @param bridgeOptions Additional options for the bridge. * @param data Arbitrary data for logging purposes. */ function transferToWPermit( DepositInput calldata input, PermitData calldata permit, address adapter, bytes calldata bridgeOptions, bytes calldata data ) external payable nonReentrant whenNotPaused { (address token, uint256 net) = _processPermit(input.controller, input.amount, input.destChainId, permit); IAssetController(input.controller).transferTo{value: msg.value}( input.recipient, net, input.unwrap, input.destChainId, adapter, bridgeOptions ); IERC20(token).forceApprove(input.controller, 0); emit TransferSent(msg.sender, input.controller, false, false, input.amount, net, data); } /** * @notice Transfer assets to a recipient on a destination chain via the specified controller and multiple adapters. * An ERC20 approval of the amount must be given to this contract prior to calling this function. * @param input The deposit input parameters. * @param adapters The bridge adapters to use. * @param fees The fees for each adapter. * @param bridgeOptions Additional options for the bridges. * @param data Arbitrary data for logging purposes. */ function transferTo( DepositInput calldata input, address[] memory adapters, uint256[] memory fees, bytes[] calldata bridgeOptions, bytes calldata data ) external payable nonReentrant whenNotPaused { (address token, uint256 net) = _process(input.controller, input.amount, input.destChainId); IAssetController(input.controller).transferTo{value: msg.value}( input.recipient, net, input.unwrap, input.destChainId, adapters, fees, bridgeOptions ); IERC20(token).forceApprove(input.controller, 0); emit TransferSent(msg.sender, input.controller, false, true, input.amount, net, data); } /** * @notice Transfer assets to a recipient on a destination chain via the specified controller and multiple adapters, using permit for approval. * @param input The deposit input parameters. * @param permit The permit data for ERC20 approval. * @param adapters The bridge adapters to use. * @param fees The fees for each adapter. * @param bridgeOptions Additional options for the bridges. * @param data Arbitrary data for logging purposes. */ function transferToWPermit( DepositInput calldata input, PermitData calldata permit, address[] memory adapters, uint256[] memory fees, bytes[] calldata bridgeOptions, bytes calldata data ) external payable nonReentrant whenNotPaused { (address token, uint256 net) = _processPermit(input.controller, input.amount, input.destChainId, permit); IAssetController(input.controller).transferTo{value: msg.value}( input.recipient, net, input.unwrap, input.destChainId, adapters, fees, bridgeOptions ); IERC20(token).forceApprove(input.controller, 0); emit TransferSent(msg.sender, input.controller, false, true, input.amount, net, data); } /** * @notice Resend a single-bridge transfer * @param controller The controller to use. * @param transferId The ID of the transfer to resend. * @param adapter The bridge adapter to use. * @param bridgeOptions Additional options for the bridge. * @param data Arbitrary data for logging purposes. */ function resendTransfer( address controller, bytes32 transferId, address adapter, bytes calldata bridgeOptions, bytes calldata data ) external payable nonReentrant whenNotPaused { if (!controllers[controller]) revert Wrapper_ControllerNotWhitelisted(); IAssetController(controller).resendTransfer{value: msg.value}(transferId, adapter, bridgeOptions); emit TransferSent(msg.sender, controller, true, false, 0, 0, data); } /** * @notice Resend a multi-bridge transfer * @param controller The controller to use. * @param transferId The ID of the transfer to resend. * @param adapters The bridge adapters to use. * @param fees The fees for each adapter. * @param bridgeOptions Additional options for the bridges. * @param data Arbitrary data for logging purposes. */ function resendTransfer( address controller, bytes32 transferId, address[] calldata adapters, uint256[] calldata fees, bytes[] calldata bridgeOptions, bytes calldata data ) external payable nonReentrant whenNotPaused { if (!controllers[controller]) revert Wrapper_ControllerNotWhitelisted(); IAssetController(controller).resendTransfer{value: msg.value}(transferId, adapters, fees, bridgeOptions); emit TransferSent(msg.sender, controller, true, true, 0, 0, data); } // ===== Admin ===== /** * @notice Set the whitelisted status for multiple controllers. * @param controller The addresses of the controllers. * @param whitelisted The whitelisted status for each controller. */ function setControllers(address[] calldata controller, bool[] calldata whitelisted) external adminOrManager { if (controller.length != whitelisted.length) revert Wrapper_LengthMismatch(); for (uint256 i = 0; i < controller.length; i++) { controllers[controller[i]] = whitelisted[i]; emit ControllerWhitelisted(controller[i], whitelisted[i]); } } /** * @notice Set the fee rate for the wrapper. * @param newFeeRate The new fee rate to be set. */ function setFeeRate(uint256 newFeeRate) external adminOrManager { if (newFeeRate > MAX_FEE_RATE) revert Wrapper_InvalidFeeRate(); if (newFeeRate > 0 && treasury == address(0)) revert Wrapper_TreasuryZeroAddress(); emit FeeRateSet(feeRate, newFeeRate); feeRate = newFeeRate; } /** * @notice Set tiered fee configuration for a controller and multiple destination chains. The same tiered fee is applied to all specified destination chains. * @param controller The address of the controller. * @param destChainIds The IDs of the destination chains. * @param thresholds The thresholds for each fee tier. * @param bips The fee bips for each tier. */ function setControllerFeeTiers( address controller, uint256[] calldata destChainIds, uint256[] calldata thresholds, uint256[] calldata bips ) external adminOrManager { if (thresholds.length != bips.length || thresholds.length > 3) revert Wrapper_LengthMismatch(); for (uint256 i = 0; i < destChainIds.length; i++) { _setControllerFeeTiers(controller, destChainIds[i], thresholds, bips); } } /** * @notice Set premium fee rates for specific destination chains. Each rate corresponds to the chain ID at the same index. * @param chainIds The IDs of the destination chains. * @param rates The premium fee rates for each chain. */ function setDestChainPremiumRate(uint256[] calldata chainIds, uint256[] calldata rates) external adminOrManager { if (chainIds.length != rates.length) revert Wrapper_LengthMismatch(); for (uint256 i = 0; i < chainIds.length; i++) { if (rates[i] > MAX_FEE_RATE) revert Wrapper_InvalidFeeRate(); destChainPremiumRate[chainIds[i]] = rates[i]; emit DestChainPremiumSet(chainIds[i], rates[i]); } } /** * @notice Set the treasury address. * @param newTreasury The new treasury address. */ function setTreasury(address newTreasury) external onlyRole(DEFAULT_ADMIN_ROLE) { if (newTreasury == address(0)) revert Wrapper_TreasuryZeroAddress(); emit TreasurySet(treasury, newTreasury); treasury = newTreasury; } function pause() external onlyRole(DEFAULT_ADMIN_ROLE) { _pause(); } function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) { _unpause(); } /** * @notice Recover tokens sent to the contract * @param token The address of the token to recover. * @param to The address to send the recovered tokens to. * @param amount The amount of tokens to recover. */ function rescueTokens(address token, address to, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) { if (to == address(0)) revert Wrapper_ZeroAddress(); IERC20(token).safeTransfer(to, amount); } /** * @notice Recover ETH sent to the contract * @param to The address to send the recovered ETH to. * @param amount The amount of ETH to recover. */ function rescueETH(address payable to, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) { if (to == address(0)) revert Wrapper_ZeroAddress(); (bool success, ) = to.call{value: amount}(""); if (!success) revert Wrapper_TransferFailed(); } // ===== Views ===== function getControllerFeeTiers( address controller, uint256 destChainId ) external view returns (uint256[] memory thresholds, uint256[] memory bips) { FeeTierConfig memory config = _controllerFeeTiers[controller][destChainId]; thresholds = new uint256[](config.count); bips = new uint256[](config.count); for (uint8 i = 0; i < config.count; i++) { thresholds[i] = config.tiers[i].threshold; bips[i] = config.tiers[i].rate; } return (thresholds, bips); } /** * @notice Quote the fee and net given amount/controller/destChain. * @param controller The controller address * @param destChainId The destination chain ID * @param amount The gross amount * @return fee The total fee to be collected * @return net The net amount after fee */ function quote(address controller, uint256 destChainId, uint256 amount) external view returns (uint256 fee, uint256 net) { (fee, net) = _quoteFee(controller, destChainId, amount); } // ===== Internal helpers ===== function _setControllerFeeTiers(address controller_, uint256 destChainId, uint256[] memory thresholds, uint256[] memory bips) internal { FeeTierConfig storage config = _controllerFeeTiers[controller_][destChainId]; // Clear existing tiers for (uint8 i = 0; i < 3; i++) { config.tiers[i] = FeeTier(0, 0); } uint256 items = thresholds.length; if (items > 0) { for (uint8 i = 0; i < items; i++) { // Ensure basis points are within valid range if (bips[i] > MAX_FEE_RATE) revert Wrapper_InvalidFeeRate(); // Ensure threshold is not zero (except first tier) if (i > 0 && thresholds[i] == 0) revert Wrapper_InvalidParams(); // Ensure thresholds are in strictly ascending order if (i > 0 && thresholds[i] <= thresholds[i - 1]) revert Wrapper_InvalidParams(); config.tiers[i] = FeeTier(thresholds[i], bips[i]); } } config.count = uint8(items); emit ControllerFeeTiersSet(controller_, destChainId, thresholds, bips); } function _quoteFee(address controller, uint256 destChainId, uint256 amount) internal view returns (uint256 fee, uint256 net) { FeeTierConfig memory config = _controllerFeeTiers[controller][destChainId]; uint256 baseFee = 0; if (config.count > 0 && amount > 0) { // Tiered fee calculation uint256 remaining = amount; uint256 processed = 0; uint256 tierStart = 0; for (uint8 i = 0; i < config.count; i++) { uint256 threshold = config.tiers[i].threshold; uint256 rate = config.tiers[i].rate; uint256 tierAmount; if (i == config.count - 1) { // Last tier: everything above previous threshold tierAmount = remaining; } else if (remaining > threshold - tierStart) { tierAmount = threshold - tierStart; } else { tierAmount = remaining; } if (tierAmount > 0) { baseFee += (tierAmount * rate) / RATE_DENOMINATOR; processed += tierAmount; remaining -= tierAmount; } tierStart = threshold; if (remaining == 0) break; } } else if (feeRate > 0 && amount > 0) { // Fallback to global feeRate baseFee = (amount * feeRate) / RATE_DENOMINATOR; } // Add destination chain premium (if any) uint256 premiumRate = destChainPremiumRate[destChainId]; if (premiumRate > 0 && amount > 0) { // Premium is applied on the original amount, then added to baseFee baseFee += (amount * premiumRate) / RATE_DENOMINATOR; } fee = baseFee; net = amount - fee; } function _process(address controller, uint256 amount, uint256 destChainId) internal returns (address token, uint256 netAmount) { if (!controllers[controller]) revert Wrapper_ControllerNotWhitelisted(); token = IAssetController(controller).token(); netAmount = _handleTransfers(token, controller, amount, destChainId); } function _processPermit( address controller, uint256 amount, uint256 destChainId, PermitData calldata permit ) internal returns (address token, uint256 netAmount) { if (!controllers[controller]) revert Wrapper_ControllerNotWhitelisted(); token = IAssetController(controller).token(); IERC20Permit(token).permit(msg.sender, address(this), amount, permit.deadline, permit.v, permit.r, permit.s); netAmount = _handleTransfers(token, controller, amount, destChainId); } function _handleTransfers(address token, address controller, uint256 amount, uint256 destChainId) internal returns (uint256 netAmount) { IERC20 t = IERC20(token); // Pull exactly `amount` and disallow fee-on-transfer tokens uint256 balBefore = t.balanceOf(address(this)); t.safeTransferFrom(msg.sender, address(this), amount); uint256 received = t.balanceOf(address(this)) - balBefore; if (received != amount) revert Wrapper_FeeOnTransferTokenNotSupported(); (uint256 fee, uint256 net) = _quoteFee(controller, destChainId, amount); if (fee > 0) { if (treasury == address(0)) revert Wrapper_TreasuryZeroAddress(); t.safeTransfer(treasury, fee); emit FeesCollected(msg.sender, token, controller, fee, treasury); } t.forceApprove(controller, net); return net; } receive() external payable {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address[2]","name":"access","type":"address[2]"},{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"uint256","name":"_feeRate","type":"uint256"},{"internalType":"address[]","name":"initialControllers","type":"address[]"},{"internalType":"uint256[]","name":"premiumChainIds","type":"uint256[]"},{"internalType":"uint256[]","name":"premiumRate","type":"uint256[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Wrapper_ControllerNotWhitelisted","type":"error"},{"inputs":[],"name":"Wrapper_FeeOnTransferTokenNotSupported","type":"error"},{"inputs":[],"name":"Wrapper_InvalidFeeRate","type":"error"},{"inputs":[],"name":"Wrapper_InvalidParams","type":"error"},{"inputs":[],"name":"Wrapper_LengthMismatch","type":"error"},{"inputs":[],"name":"Wrapper_TransferFailed","type":"error"},{"inputs":[],"name":"Wrapper_TreasuryZeroAddress","type":"error"},{"inputs":[],"name":"Wrapper_Unauthorized","type":"error"},{"inputs":[],"name":"Wrapper_ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"controller","type":"address"},{"indexed":true,"internalType":"uint256","name":"destChainId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"thresholds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"rates","type":"uint256[]"}],"name":"ControllerFeeTiersSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"controller","type":"address"},{"indexed":false,"internalType":"bool","name":"whitelisted","type":"bool"}],"name":"ControllerWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"destChainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"}],"name":"DestChainPremiumSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newRate","type":"uint256"}],"name":"FeeRateSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"payer","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"controller","type":"address"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"treasury","type":"address"}],"name":"FeesCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"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":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"controller","type":"address"},{"indexed":false,"internalType":"bool","name":"resent","type":"bool"},{"indexed":false,"internalType":"bool","name":"multi","type":"bool"},{"indexed":false,"internalType":"uint256","name":"grossAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"netAmount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TransferSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldTreasury","type":"address"},{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasurySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"CONTROLLER_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RATE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"controllers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"destChainPremiumRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"uint256","name":"destChainId","type":"uint256"}],"name":"getControllerFeeTiers","outputs":[{"internalType":"uint256[]","name":"thresholds","type":"uint256[]"},{"internalType":"uint256[]","name":"bips","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":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"uint256","name":"destChainId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"net","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":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"bytes32","name":"transferId","type":"bytes32"},{"internalType":"address","name":"adapter","type":"address"},{"internalType":"bytes","name":"bridgeOptions","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"resendTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"bytes32","name":"transferId","type":"bytes32"},{"internalType":"address[]","name":"adapters","type":"address[]"},{"internalType":"uint256[]","name":"fees","type":"uint256[]"},{"internalType":"bytes[]","name":"bridgeOptions","type":"bytes[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"resendTransfer","outputs":[],"stateMutability":"payable","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":"controller","type":"address"},{"internalType":"uint256[]","name":"destChainIds","type":"uint256[]"},{"internalType":"uint256[]","name":"thresholds","type":"uint256[]"},{"internalType":"uint256[]","name":"bips","type":"uint256[]"}],"name":"setControllerFeeTiers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"controller","type":"address[]"},{"internalType":"bool[]","name":"whitelisted","type":"bool[]"}],"name":"setControllers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"},{"internalType":"uint256[]","name":"rates","type":"uint256[]"}],"name":"setDestChainPremiumRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeeRate","type":"uint256"}],"name":"setFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTreasury","type":"address"}],"name":"setTreasury","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":[{"components":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"uint256","name":"destChainId","type":"uint256"}],"internalType":"struct ControllerWrapper.DepositInput","name":"input","type":"tuple"},{"internalType":"address[]","name":"adapters","type":"address[]"},{"internalType":"uint256[]","name":"fees","type":"uint256[]"},{"internalType":"bytes[]","name":"bridgeOptions","type":"bytes[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transferTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"uint256","name":"destChainId","type":"uint256"}],"internalType":"struct ControllerWrapper.DepositInput","name":"input","type":"tuple"},{"internalType":"address","name":"adapter","type":"address"},{"internalType":"bytes","name":"bridgeOptions","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transferTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"uint256","name":"destChainId","type":"uint256"}],"internalType":"struct ControllerWrapper.DepositInput","name":"input","type":"tuple"},{"components":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct ControllerWrapper.PermitData","name":"permit","type":"tuple"},{"internalType":"address[]","name":"adapters","type":"address[]"},{"internalType":"uint256[]","name":"fees","type":"uint256[]"},{"internalType":"bytes[]","name":"bridgeOptions","type":"bytes[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transferToWPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"controller","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"unwrap","type":"bool"},{"internalType":"uint256","name":"destChainId","type":"uint256"}],"internalType":"struct ControllerWrapper.DepositInput","name":"input","type":"tuple"},{"components":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct ControllerWrapper.PermitData","name":"permit","type":"tuple"},{"internalType":"address","name":"adapter","type":"address"},{"internalType":"bytes","name":"bridgeOptions","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transferToWPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162003dbb38038062003dbb8339810160408190526200003491620005d0565b600180556002805460ff1916905562000056600087815b60200201516200039a565b620000847f14031051ef64910ea26175284bbaea2d8f485c9aec1697121604906a168aebdb8760016200004b565b6001600160a01b0385161580156200009c5750600084115b15620000bb5760405163082398e560e31b815260040160405180910390fd5b611388841115620000de57604051625b37a160e41b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b03871690811790915560038590556040516000907f21eb548722a564f6e09f039f7aa858ae94c911910f3823b37af2250eeca4f403908290a36040805160008152602081018690527f959ec4191db1bd972bfbc60dc7d735d4cfb897ca3fd297f4ebd6ee918feb84d4910160405180910390a160005b835181101562000245576001600560008684815181106200018e576200018e620006db565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550838181518110620001e257620001e2620006db565b60200260200101516001600160a01b03167fbfd6f983ad3ebd9aeb58497a4e27c4a45c7c299f6895c05fe9204e405bce5b98600160405162000228911515815260200190565b60405180910390a2806200023c81620006f1565b91505062000169565b50805182511462000269576040516330dda05d60e01b815260040160405180910390fd5b60005b82518110156200038d576113888282815181106200028e576200028e620006db565b60200260200101511115620002b557604051625b37a160e41b815260040160405180910390fd5b818181518110620002ca57620002ca620006db565b602002602001015160076000858481518110620002eb57620002eb620006db565b60200260200101518152602001908152602001600020819055508281815181106200031a576200031a620006db565b60200260200101517f2b022a7462191d73614c0d3a87a34970ed11ca5ebe4e7ce53c9ed8bb664ae8d9838381518110620003585762000358620006db565b60200260200101516040516200037091815260200190565b60405180910390a2806200038481620006f1565b9150506200026c565b5050505050505062000719565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000437576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620003f63390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156200047657620004766200043b565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620004a757620004a76200043b565b604052919050565b80516001600160a01b0381168114620004c757600080fd5b919050565b60006001600160401b03821115620004e857620004e86200043b565b5060051b60200190565b600082601f8301126200050457600080fd5b815160206200051d6200051783620004cc565b6200047c565b82815260059290921b840181019181810190868411156200053d57600080fd5b8286015b8481101562000563576200055581620004af565b835291830191830162000541565b509695505050505050565b600082601f8301126200058057600080fd5b81516020620005936200051783620004cc565b82815260059290921b84018101918181019086841115620005b357600080fd5b8286015b84811015620005635780518352918301918301620005b7565b60008060008060008060e08789031215620005ea57600080fd5b87601f880112620005fa57600080fd5b6200060462000451565b80604089018a8111156200061757600080fd5b895b818110156200063c576200062d81620004af565b84526020938401930162000619565b508198506200064b81620004af565b60608b015160808c0151919950975092506001600160401b03915050808211156200067557600080fd5b620006838a838b01620004f2565b945060a08901519150808211156200069a57600080fd5b620006a88a838b016200056e565b935060c0890151915080821115620006bf57600080fd5b50620006ce89828a016200056e565b9150509295509295509295565b634e487b7160e01b600052603260045260246000fd5b6000600182016200071257634e487b7160e01b600052601160045260246000fd5b5060010190565b61369280620007296000396000f3fe6080604052600436106101e75760003560e01c80638456cb5911610102578063a4acee9811610095578063da8c229e11610064578063da8c229e1461055c578063df965bb21461058c578063f0f44260146105ac578063fc68be85146105cc57600080fd5b8063a4acee98146104dc578063af42a26f14610509578063cea9d26f1461051c578063d547741f1461053c57600080fd5b806392f6576e116100d157806392f6576e14610466578063978bbdb91461047c5780639e8cc04b14610492578063a217fddf146104c757600080fd5b80638456cb591461040b57806388c11d521461042057806390f1c8d91461043357806391d148541461044657600080fd5b80633f4ba83a1161017a5780635c975abb116101495780635c975abb1461037657806361d027b31461038e5780637c50f938146103c65780637efad8e0146103f457600080fd5b80633f4ba83a1461030e57806345596e2e146103235780634766f56614610343578063519dd2fc1461035657600080fd5b80632c45e5a0116101b65780632c45e5a01461029b5780632f2ff15d146102bb57806336568abe146102db5780633bfa0ee5146102fb57600080fd5b806301ffc9a7146101f3578063099a04e5146102285780630d23f9b21461024a578063248a9ca31461025d57600080fd5b366101ee57005b600080fd5b3480156101ff57600080fd5b5061021361020e36600461282d565b6105ee565b60405190151581526020015b60405180910390f35b34801561023457600080fd5b5061024861024336600461286c565b610625565b005b6102486102583660046128e9565b6106d1565b34801561026957600080fd5b5061028d610278366004612987565b60009081526020819052604090206001015490565b60405190815260200161021f565b3480156102a757600080fd5b506102486102b63660046129e4565b6107d8565b3480156102c757600080fd5b506102486102d6366004612a4f565b610967565b3480156102e757600080fd5b506102486102f6366004612a4f565b610991565b610248610309366004612bcf565b610a14565b34801561031a57600080fd5b50610248610b6d565b34801561032f57600080fd5b5061024861033e366004612987565b610b83565b610248610351366004612c7b565b610c63565b34801561036257600080fd5b506102486103713660046129e4565b610dac565b34801561038257600080fd5b5060025460ff16610213565b34801561039a57600080fd5b506004546103ae906001600160a01b031681565b6040516001600160a01b03909116815260200161021f565b3480156103d257600080fd5b506103e66103e136600461286c565b610f1b565b60405161021f929190612d4a565b34801561040057600080fd5b5061028d620186a081565b34801561041757600080fd5b506102486110f3565b61024861042e366004612d81565b611106565b610248610441366004612e61565b611258565b34801561045257600080fd5b50610213610461366004612a4f565b61138a565b34801561047257600080fd5b5061028d61138881565b34801561048857600080fd5b5061028d60035481565b34801561049e57600080fd5b506104b26104ad366004612eea565b6113b3565b6040805192835260208301919091520161021f565b3480156104d357600080fd5b5061028d600081565b3480156104e857600080fd5b5061028d6104f7366004612987565b60076020526000908152604090205481565b610248610517366004612f1f565b6113cd565b34801561052857600080fd5b50610248610537366004612fff565b6114dc565b34801561054857600080fd5b50610248610557366004612a4f565b611522565b34801561056857600080fd5b50610213610577366004613040565b60056020526000908152604090205460ff1681565b34801561059857600080fd5b506102486105a736600461305d565b611547565b3480156105b857600080fd5b506102486105c7366004613040565b61165e565b3480156105d857600080fd5b5061028d60008051602061363d83398151915281565b60006001600160e01b03198216637965db0b60e01b148061061f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6000610630816116ed565b6001600160a01b038316610657576040516312cffc5760e01b815260040160405180910390fd5b6000836001600160a01b03168360405160006040518083038185875af1925050503d80600081146106a4576040519150601f19603f3d011682016040523d82523d6000602084013e6106a9565b606091505b50509050806106cb57604051630443456960e41b815260040160405180910390fd5b50505050565b6106d96116f7565b6106e1611750565b6001600160a01b03871660009081526005602052604090205460ff1661071a5760405163de83a4e960e01b815260040160405180910390fd5b604051634995c3e760e01b81526001600160a01b03881690634995c3e790349061074e908a908a908a908a9060040161311f565b6000604051808303818588803b15801561076757600080fd5b505af115801561077b573d6000803e3d6000fd5b5050505050866001600160a01b0316336001600160a01b031660008051602061361d8339815191526001600080600088886040516107be96959493929190613154565b60405180910390a36107cf60018055565b50505050505050565b6107e360003361138a565b80610801575061080160008051602061363d8339815191523361138a565b61081e57604051630992d00560e11b815260040160405180910390fd5b82811461083e576040516330dda05d60e01b815260040160405180910390fd5b60005b838110156109605782828281811061085b5761085b613190565b905060200201602081019061087091906131b4565b6005600087878581811061088657610886613190565b905060200201602081019061089b9190613040565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558484828181106108d5576108d5613190565b90506020020160208101906108ea9190613040565b6001600160a01b03167fbfd6f983ad3ebd9aeb58497a4e27c4a45c7c299f6895c05fe9204e405bce5b9884848481811061092657610926613190565b905060200201602081019061093b91906131b4565b604051901515815260200160405180910390a280610958816131e7565b915050610841565b5050505050565b600082815260208190526040902060010154610982816116ed565b61098c8383611798565b505050565b6001600160a01b0381163314610a065760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b610a10828261181c565b5050565b610a1c6116f7565b610a24611750565b600080610a46610a3760208b018b613040565b8a604001358b60800135611881565b9092509050610a5860208a018a613040565b6001600160a01b03166339c82de634610a7760408d0160208e01613040565b848d6060016020810190610a8b91906131b4565b8e608001358e8e8e8e6040518a63ffffffff1660e01b8152600401610ab7989796959493929190613291565b6000604051808303818588803b158015610ad057600080fd5b505af1158015610ae4573d6000803e3d6000fd5b50610b0d9350610afb9250505060208b018b613040565b6001600160a01b038416906000611936565b610b1a60208a018a613040565b6001600160a01b0316336001600160a01b031660008051602061361d833981519152600060018d60400135868a8a604051610b5a96959493929190613154565b60405180910390a350506107cf60018055565b6000610b78816116ed565b610b806119f8565b50565b610b8e60003361138a565b80610bac5750610bac60008051602061363d8339815191523361138a565b610bc957604051630992d00560e11b815260040160405180910390fd5b611388811115610beb57604051625b37a160e41b815260040160405180910390fd5b600081118015610c0457506004546001600160a01b0316155b15610c225760405163082398e560e31b815260040160405180910390fd5b60035460408051918252602082018390527f959ec4191db1bd972bfbc60dc7d735d4cfb897ca3fd297f4ebd6ee918feb84d4910160405180910390a1600355565b610c6b6116f7565b610c73611750565b600080610c95610c8660208a018a613040565b89604001358a60800135611881565b9092509050610ca76020890189613040565b6001600160a01b031663d30a41c834610cc660408c0160208d01613040565b84610cd760808e0160608f016131b4565b8d608001358d8d8d6040518963ffffffff1660e01b8152600401610d01979695949392919061332d565b6000604051808303818588803b158015610d1a57600080fd5b505af1158015610d2e573d6000803e3d6000fd5b50610d459350610afb9250505060208a018a613040565b610d526020890189613040565b6001600160a01b0316336001600160a01b031660008051602061361d8339815191526000808c60400135868a8a604051610d9196959493929190613154565b60405180910390a35050610da460018055565b505050505050565b610db760003361138a565b80610dd55750610dd560008051602061363d8339815191523361138a565b610df257604051630992d00560e11b815260040160405180910390fd5b828114610e12576040516330dda05d60e01b815260040160405180910390fd5b60005b8381101561096057611388838383818110610e3257610e32613190565b905060200201351115610e5757604051625b37a160e41b815260040160405180910390fd5b828282818110610e6957610e69613190565b9050602002013560076000878785818110610e8657610e86613190565b90506020020135815260200190815260200160002081905550848482818110610eb157610eb1613190565b905060200201357f2b022a7462191d73614c0d3a87a34970ed11ca5ebe4e7ce53c9ed8bb664ae8d9848484818110610eeb57610eeb613190565b90506020020135604051610f0191815260200190565b60405180910390a280610f13816131e7565b915050610e15565b6001600160a01b0382166000908152600660209081526040808320848452909152808220815160a08101835260609384939092908290810182600386835b82821015610f95578382600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610f59565b505050908252506006919091015460ff90811660209283015290820151919250166001600160401b03811115610fcd57610fcd612a97565b604051908082528060200260200182016040528015610ff6578160200160208202803683370190505b509250806020015160ff166001600160401b0381111561101857611018612a97565b604051908082528060200260200182016040528015611041578160200160208202803683370190505b50915060005b816020015160ff168160ff1610156110e957815160ff82166003811061106f5761106f613190565b602002015160000151848260ff168151811061108d5761108d613190565b6020908102919091010152815160ff8216600381106110ae576110ae613190565b602002015160200151838260ff16815181106110cc576110cc613190565b6020908102919091010152806110e18161337d565b915050611047565b50505b9250929050565b60006110fe816116ed565b610b80611a4a565b61110e6116f7565b611116611750565b60008061113961112960208c018c613040565b8b604001358c608001358c611a87565b909250905061114b60208b018b613040565b6001600160a01b03166339c82de63461116a60408e0160208f01613040565b848e606001602081019061117e91906131b4565b8f608001358e8e8e8e6040518a63ffffffff1660e01b81526004016111aa989796959493929190613291565b6000604051808303818588803b1580156111c357600080fd5b505af11580156111d7573d6000803e3d6000fd5b506111ee9350610afb9250505060208c018c613040565b6111fb60208b018b613040565b6001600160a01b0316336001600160a01b031660008051602061361d833981519152600060018e60400135868a8a60405161123b96959493929190613154565b60405180910390a3505061124e60018055565b5050505050505050565b6112606116f7565b611268611750565b60008061128b61127b60208b018b613040565b8a604001358b608001358b611a87565b909250905061129d60208a018a613040565b6001600160a01b031663d30a41c8346112bc60408d0160208e01613040565b848d60600160208101906112d091906131b4565b8e608001358d8d8d6040518963ffffffff1660e01b81526004016112fa979695949392919061332d565b6000604051808303818588803b15801561131357600080fd5b505af1158015611327573d6000803e3d6000fd5b5061133e9350610afb9250505060208b018b613040565b61134b60208a018a613040565b6001600160a01b0316336001600160a01b031660008051602061361d8339815191526000808d60400135868a8a604051610b5a96959493929190613154565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6000806113c1858585611beb565b90969095509350505050565b6113d56116f7565b6113dd611750565b6001600160a01b038a1660009081526005602052604090205460ff166114165760405163de83a4e960e01b815260040160405180910390fd5b60405163d3a8b63160e01b81526001600160a01b038b169063d3a8b631903490611450908d908d908d908d908d908d908d9060040161339c565b6000604051808303818588803b15801561146957600080fd5b505af115801561147d573d6000803e3d6000fd5b5050505050896001600160a01b0316336001600160a01b031660008051602061361d83398151915260018060008088886040516114bf96959493929190613154565b60405180910390a36114d060018055565b50505050505050505050565b60006114e7816116ed565b6001600160a01b03831661150e576040516312cffc5760e01b815260040160405180910390fd5b6106cb6001600160a01b0385168484611e51565b60008281526020819052604090206001015461153d816116ed565b61098c838361181c565b61155260003361138a565b80611570575061157060008051602061363d8339815191523361138a565b61158d57604051630992d00560e11b815260040160405180910390fd5b828114158061159c5750600383115b156115ba576040516330dda05d60e01b815260040160405180910390fd5b60005b8581101561124e5761164c888888848181106115db576115db613190565b9050602002013587878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250611e8192505050565b80611656816131e7565b9150506115bd565b6000611669816116ed565b6001600160a01b0382166116905760405163082398e560e31b815260040160405180910390fd5b6004546040516001600160a01b038085169216907f21eb548722a564f6e09f039f7aa858ae94c911910f3823b37af2250eeca4f40390600090a350600480546001600160a01b0319166001600160a01b0392909216919091179055565b610b808133612113565b6002600154036117495760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109fd565b6002600155565b60025460ff16156117965760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109fd565b565b6117a2828261138a565b610a10576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556117d83390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b611826828261138a565b15610a10576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6001600160a01b038316600090815260056020526040812054819060ff166118bc5760405163de83a4e960e01b815260040160405180910390fd5b846001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191e919061342f565b915061192c8286868661216c565b9050935093915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526119878482612359565b6106cb576040516001600160a01b0384166024820152600060448201526119ee90859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612400565b6106cb8482612400565b611a006124d5565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b611a52611750565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a2d3390565b6001600160a01b038416600090815260056020526040812054819060ff16611ac25760405163de83a4e960e01b815260040160405180910390fd5b856001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b24919061342f565b91506001600160a01b03821663d505accf3330888735611b4a60408a0160208b0161344c565b604080516001600160e01b031960e089901b1681526001600160a01b0396871660048201529590941660248601526044850192909252606484015260ff16608483015286013560a4820152606086013560c482015260e401600060405180830381600087803b158015611bbc57600080fd5b505af1158015611bd0573d6000803e3d6000fd5b50505050611be08287878761216c565b905094509492505050565b6001600160a01b0383166000908152600660209081526040808320858452909152808220815160a08101835283928392908290810182600386835b82821015611c62578382600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190611c26565b505050908252506006919091015460ff908116602092830152908201519192506000911615801590611c945750600085115b15611db75784600080805b856020015160ff168160ff161015611dae57855160009060ff831660038110611cca57611cca613190565b602002015151875190915060009060ff841660038110611cec57611cec613190565b6020020151602001519050600060018960200151611d0a919061346f565b60ff168460ff1603611d1d575085611d42565b611d278584613488565b871115611d3f57611d388584613488565b9050611d42565b50855b8015611d8557620186a0611d56838361349b565b611d6091906134b2565b611d6a90896134d4565b9750611d7681876134d4565b9550611d828188613488565b96505b82945086600003611d9857505050611dae565b5050508080611da69061337d565b915050611c9f565b50505050611ded565b6000600354118015611dc95750600085115b15611ded57620186a060035486611de0919061349b565b611dea91906134b2565b90505b6000868152600760205260409020548015801590611e0b5750600086115b15611e3557620186a0611e1e828861349b565b611e2891906134b2565b611e3290836134d4565b91505b8194508486611e449190613488565b9350505050935093915050565b6040516001600160a01b03831660248201526044810182905261098c90849063a9059cbb60e01b906064016119b7565b6001600160a01b03841660009081526006602090815260408083208684529091528120905b60038160ff161015611f095760408051808201909152600080825260208201528260ff831660038110611edb57611edb613190565b6002020160008201518160000155602082015181600101559050508080611f019061337d565b915050611ea6565b50825180156120b35760005b818160ff1610156120b157611388848260ff1681518110611f3857611f38613190565b60200260200101511115611f5e57604051625b37a160e41b815260040160405180910390fd5b60008160ff16118015611f8d5750848160ff1681518110611f8157611f81613190565b60200260200101516000145b15611fab57604051630cdd0ebf60e31b815260040160405180910390fd5b60008160ff16118015612000575084611fc560018361346f565b60ff1681518110611fd857611fd8613190565b6020026020010151858260ff1681518110611ff557611ff5613190565b602002602001015111155b1561201e57604051630cdd0ebf60e31b815260040160405180910390fd5b6040518060400160405280868360ff168151811061203e5761203e613190565b60200260200101518152602001858360ff168151811061206057612060613190565b6020026020010151815250836000018260ff166003811061208357612083613190565b60020201600082015181600001556020820151816001015590505080806120a99061337d565b915050611f15565b505b60068201805460ff191660ff831617905560405185906001600160a01b038816907fe875e6846deb900a1c39242590238ce046f1880aceb983ceef966c09a50647a0906121039088908890612d4a565b60405180910390a3505050505050565b61211d828261138a565b610a105761212a8161251e565b612135836020612530565b60405160200161214692919061350b565b60408051601f198184030181529082905262461bcd60e51b82526109fd91600401613580565b6040516370a0823160e01b8152306004820152600090859082906001600160a01b038316906370a0823190602401602060405180830381865afa1580156121b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121db91906135b3565b90506121f26001600160a01b0383163330886126d2565b6040516370a0823160e01b815230600482015260009082906001600160a01b038516906370a0823190602401602060405180830381865afa15801561223b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225f91906135b3565b6122699190613488565b905085811461228b5760405163a62c631560e01b815260040160405180910390fd5b60008061229989888a611beb565b90925090508115612336576004546001600160a01b03166122cd5760405163082398e560e31b815260040160405180910390fd5b6004546122e7906001600160a01b03878116911684611e51565b600454604080518481526001600160a01b0392831660208201528b8316928d169133917f0c7016eab065212f095b32ca6daf66b021b628b6457815d893fff6f43a374c34910160405180910390a45b61234a6001600160a01b0386168a83611936565b9450505050505b949350505050565b6000806000846001600160a01b03168460405161237691906135cc565b6000604051808303816000865af19150503d80600081146123b3576040519150601f19603f3d011682016040523d82523d6000602084013e6123b8565b606091505b50915091508180156123e25750805115806123e25750808060200190518101906123e291906135e8565b80156123f757506001600160a01b0385163b15155b95945050505050565b6000612455826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661270a9092919063ffffffff16565b905080516000148061247657508080602001905181019061247691906135e8565b61098c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109fd565b60025460ff166117965760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109fd565b606061061f6001600160a01b03831660145b6060600061253f83600261349b565b61254a9060026134d4565b6001600160401b0381111561256157612561612a97565b6040519080825280601f01601f19166020018201604052801561258b576020820181803683370190505b509050600360fc1b816000815181106125a6576125a6613190565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106125d5576125d5613190565b60200101906001600160f81b031916908160001a90535060006125f984600261349b565b6126049060016134d4565b90505b600181111561267c576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061263857612638613190565b1a60f81b82828151811061264e5761264e613190565b60200101906001600160f81b031916908160001a90535060049490941c9361267581613605565b9050612607565b5083156126cb5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109fd565b9392505050565b6040516001600160a01b03808516602483015283166044820152606481018290526106cb9085906323b872dd60e01b906084016119b7565b6060612351848460008585600080866001600160a01b0316858760405161273191906135cc565b60006040518083038185875af1925050503d806000811461276e576040519150601f19603f3d011682016040523d82523d6000602084013e612773565b606091505b50915091506127848783838761278f565b979650505050505050565b606083156127fe5782516000036127f7576001600160a01b0385163b6127f75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109fd565b5081612351565b61235183838151156128135781518083602001fd5b8060405162461bcd60e51b81526004016109fd9190613580565b60006020828403121561283f57600080fd5b81356001600160e01b0319811681146126cb57600080fd5b6001600160a01b0381168114610b8057600080fd5b6000806040838503121561287f57600080fd5b823561288a81612857565b946020939093013593505050565b80356128a381612857565b919050565b60008083601f8401126128ba57600080fd5b5081356001600160401b038111156128d157600080fd5b6020830191508360208285010111156110ec57600080fd5b600080600080600080600060a0888a03121561290457600080fd5b873561290f81612857565b965060208801359550604088013561292681612857565b945060608801356001600160401b038082111561294257600080fd5b61294e8b838c016128a8565b909650945060808a013591508082111561296757600080fd5b506129748a828b016128a8565b989b979a50959850939692959293505050565b60006020828403121561299957600080fd5b5035919050565b60008083601f8401126129b257600080fd5b5081356001600160401b038111156129c957600080fd5b6020830191508360208260051b85010111156110ec57600080fd5b600080600080604085870312156129fa57600080fd5b84356001600160401b0380821115612a1157600080fd5b612a1d888389016129a0565b90965094506020870135915080821115612a3657600080fd5b50612a43878288016129a0565b95989497509550505050565b60008060408385031215612a6257600080fd5b823591506020830135612a7481612857565b809150509250929050565b600060a08284031215612a9157600080fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612ad557612ad5612a97565b604052919050565b60006001600160401b03821115612af657612af6612a97565b5060051b60200190565b600082601f830112612b1157600080fd5b81356020612b26612b2183612add565b612aad565b82815260059290921b84018101918181019086841115612b4557600080fd5b8286015b84811015612b69578035612b5c81612857565b8352918301918301612b49565b509695505050505050565b600082601f830112612b8557600080fd5b81356020612b95612b2183612add565b82815260059290921b84018101918181019086841115612bb457600080fd5b8286015b84811015612b695780358352918301918301612bb8565b6000806000806000806000610120888a031215612beb57600080fd5b612bf58989612a7f565b965060a08801356001600160401b0380821115612c1157600080fd5b612c1d8b838c01612b00565b975060c08a0135915080821115612c3357600080fd5b612c3f8b838c01612b74565b965060e08a0135915080821115612c5557600080fd5b612c618b838c016129a0565b90965094506101008a013591508082111561296757600080fd5b6000806000806000806101008789031215612c9557600080fd5b612c9f8888612a7f565b955060a0870135612caf81612857565b945060c08701356001600160401b0380821115612ccb57600080fd5b612cd78a838b016128a8565b909650945060e0890135915080821115612cf057600080fd5b50612cfd89828a016128a8565b979a9699509497509295939492505050565b600081518084526020808501945080840160005b83811015612d3f57815187529582019590820190600101612d23565b509495945050505050565b604081526000612d5d6040830185612d0f565b82810360208401526123f78185612d0f565b600060808284031215612a9157600080fd5b6000806000806000806000806101a0898b031215612d9e57600080fd5b612da88a8a612a7f565b9750612db78a60a08b01612d6f565b96506101208901356001600160401b0380821115612dd457600080fd5b612de08c838d01612b00565b97506101408b0135915080821115612df757600080fd5b612e038c838d01612b74565b96506101608b0135915080821115612e1a57600080fd5b612e268c838d016129a0565b90965094506101808b0135915080821115612e4057600080fd5b50612e4d8b828c016128a8565b999c989b5096995094979396929594505050565b6000806000806000806000610180888a031215612e7d57600080fd5b612e878989612a7f565b9650612e968960a08a01612d6f565b9550610120880135612ea781612857565b94506101408801356001600160401b0380821115612ec457600080fd5b612ed08b838c016128a8565b90965094506101608a013591508082111561296757600080fd5b600080600060608486031215612eff57600080fd5b8335612f0a81612857565b95602085013595506040909401359392505050565b60008060008060008060008060008060c08b8d031215612f3e57600080fd5b612f478b612898565b995060208b0135985060408b01356001600160401b0380821115612f6a57600080fd5b612f768e838f016129a0565b909a50985060608d0135915080821115612f8f57600080fd5b612f9b8e838f016129a0565b909850965060808d0135915080821115612fb457600080fd5b612fc08e838f016129a0565b909650945060a08d0135915080821115612fd957600080fd5b50612fe68d828e016128a8565b915080935050809150509295989b9194979a5092959850565b60008060006060848603121561301457600080fd5b833561301f81612857565b9250602084013561302f81612857565b929592945050506040919091013590565b60006020828403121561305257600080fd5b81356126cb81612857565b60008060008060008060006080888a03121561307857600080fd5b873561308381612857565b965060208801356001600160401b038082111561309f57600080fd5b6130ab8b838c016129a0565b909850965060408a01359150808211156130c457600080fd5b6130d08b838c016129a0565b909650945060608a01359150808211156130e957600080fd5b506129748a828b016129a0565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8481526001600160a01b038416602082015260606040820181905260009061314a90830184866130f6565b9695505050505050565b8615158152851515602082015284604082015283606082015260a06080820152600061318460a0830184866130f6565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b8015158114610b8057600080fd5b6000602082840312156131c657600080fd5b81356126cb816131a6565b634e487b7160e01b600052601160045260246000fd5b6000600182016131f9576131f96131d1565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156132845782840389528135601e1988360301811261323b57600080fd5b870185810190356001600160401b0381111561325657600080fd5b80360382131561326557600080fd5b6132708682846130f6565b9a87019a955050509084019060010161321a565b5091979650505050505050565b600060e0820160018060a01b03808c16845260208b818601528a1515604086015289606086015260e0608086015282895180855261010087019150828b01945060005b818110156132f25785518516835294830194918301916001016132d4565b505085810360a0870152613306818a612d0f565b935050505082810360c084015261331e818587613200565b9b9a5050505050505050505050565b6001600160a01b038881168252602082018890528615156040830152606082018690528416608082015260c060a0820181905260009061337090830184866130f6565b9998505050505050505050565b600060ff821660ff8103613393576133936131d1565b60010192915050565b87815260806020808301829052908201879052600090889060a08401835b8a8110156133e85783356133cd81612857565b6001600160a01b0316825292820192908201906001016133ba565b5084810360408601528781526001600160fb1b0388111561340857600080fd5b8760051b9250828983830137909101838103820160608501529061331e8183018688613200565b60006020828403121561344157600080fd5b81516126cb81612857565b60006020828403121561345e57600080fd5b813560ff811681146126cb57600080fd5b60ff828116828216039081111561061f5761061f6131d1565b8181038181111561061f5761061f6131d1565b808202811582820484141761061f5761061f6131d1565b6000826134cf57634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561061f5761061f6131d1565b60005b838110156135025781810151838201526020016134ea565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516135438160178501602088016134e7565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516135748160288401602088016134e7565b01602801949350505050565b602081526000825180602084015261359f8160408501602087016134e7565b601f01601f19169190910160400192915050565b6000602082840312156135c557600080fd5b5051919050565b600082516135de8184602087016134e7565b9190910192915050565b6000602082840312156135fa57600080fd5b81516126cb816131a6565b600081613614576136146131d1565b50600019019056fedc35ec9c20a3583ca2942e2bf27861adb550876aefb2699c87769d4e0cddcd4d14031051ef64910ea26175284bbaea2d8f485c9aec1697121604906a168aebdba264697066735822122017304cfbcd8841f997b2ab409931d83ed70b197d553f9c553de8a607a50d4edb64736f6c634300081300330000000000000000000000005db7ad07d4903579a0342f7332bd4e3ed480d1af000000000000000000000000b30dc8ada8a9a704cc803b60f98ec92084a87942000000000000000000000000359f01614eed04dbe2b9a3f6d45835cb1b200b25000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000229ac52e807e83bc21507caa93138972da44a61b000000000000000000000000168b439f88ab57bf7633cb39131f91bc90a3b74d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101e75760003560e01c80638456cb5911610102578063a4acee9811610095578063da8c229e11610064578063da8c229e1461055c578063df965bb21461058c578063f0f44260146105ac578063fc68be85146105cc57600080fd5b8063a4acee98146104dc578063af42a26f14610509578063cea9d26f1461051c578063d547741f1461053c57600080fd5b806392f6576e116100d157806392f6576e14610466578063978bbdb91461047c5780639e8cc04b14610492578063a217fddf146104c757600080fd5b80638456cb591461040b57806388c11d521461042057806390f1c8d91461043357806391d148541461044657600080fd5b80633f4ba83a1161017a5780635c975abb116101495780635c975abb1461037657806361d027b31461038e5780637c50f938146103c65780637efad8e0146103f457600080fd5b80633f4ba83a1461030e57806345596e2e146103235780634766f56614610343578063519dd2fc1461035657600080fd5b80632c45e5a0116101b65780632c45e5a01461029b5780632f2ff15d146102bb57806336568abe146102db5780633bfa0ee5146102fb57600080fd5b806301ffc9a7146101f3578063099a04e5146102285780630d23f9b21461024a578063248a9ca31461025d57600080fd5b366101ee57005b600080fd5b3480156101ff57600080fd5b5061021361020e36600461282d565b6105ee565b60405190151581526020015b60405180910390f35b34801561023457600080fd5b5061024861024336600461286c565b610625565b005b6102486102583660046128e9565b6106d1565b34801561026957600080fd5b5061028d610278366004612987565b60009081526020819052604090206001015490565b60405190815260200161021f565b3480156102a757600080fd5b506102486102b63660046129e4565b6107d8565b3480156102c757600080fd5b506102486102d6366004612a4f565b610967565b3480156102e757600080fd5b506102486102f6366004612a4f565b610991565b610248610309366004612bcf565b610a14565b34801561031a57600080fd5b50610248610b6d565b34801561032f57600080fd5b5061024861033e366004612987565b610b83565b610248610351366004612c7b565b610c63565b34801561036257600080fd5b506102486103713660046129e4565b610dac565b34801561038257600080fd5b5060025460ff16610213565b34801561039a57600080fd5b506004546103ae906001600160a01b031681565b6040516001600160a01b03909116815260200161021f565b3480156103d257600080fd5b506103e66103e136600461286c565b610f1b565b60405161021f929190612d4a565b34801561040057600080fd5b5061028d620186a081565b34801561041757600080fd5b506102486110f3565b61024861042e366004612d81565b611106565b610248610441366004612e61565b611258565b34801561045257600080fd5b50610213610461366004612a4f565b61138a565b34801561047257600080fd5b5061028d61138881565b34801561048857600080fd5b5061028d60035481565b34801561049e57600080fd5b506104b26104ad366004612eea565b6113b3565b6040805192835260208301919091520161021f565b3480156104d357600080fd5b5061028d600081565b3480156104e857600080fd5b5061028d6104f7366004612987565b60076020526000908152604090205481565b610248610517366004612f1f565b6113cd565b34801561052857600080fd5b50610248610537366004612fff565b6114dc565b34801561054857600080fd5b50610248610557366004612a4f565b611522565b34801561056857600080fd5b50610213610577366004613040565b60056020526000908152604090205460ff1681565b34801561059857600080fd5b506102486105a736600461305d565b611547565b3480156105b857600080fd5b506102486105c7366004613040565b61165e565b3480156105d857600080fd5b5061028d60008051602061363d83398151915281565b60006001600160e01b03198216637965db0b60e01b148061061f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6000610630816116ed565b6001600160a01b038316610657576040516312cffc5760e01b815260040160405180910390fd5b6000836001600160a01b03168360405160006040518083038185875af1925050503d80600081146106a4576040519150601f19603f3d011682016040523d82523d6000602084013e6106a9565b606091505b50509050806106cb57604051630443456960e41b815260040160405180910390fd5b50505050565b6106d96116f7565b6106e1611750565b6001600160a01b03871660009081526005602052604090205460ff1661071a5760405163de83a4e960e01b815260040160405180910390fd5b604051634995c3e760e01b81526001600160a01b03881690634995c3e790349061074e908a908a908a908a9060040161311f565b6000604051808303818588803b15801561076757600080fd5b505af115801561077b573d6000803e3d6000fd5b5050505050866001600160a01b0316336001600160a01b031660008051602061361d8339815191526001600080600088886040516107be96959493929190613154565b60405180910390a36107cf60018055565b50505050505050565b6107e360003361138a565b80610801575061080160008051602061363d8339815191523361138a565b61081e57604051630992d00560e11b815260040160405180910390fd5b82811461083e576040516330dda05d60e01b815260040160405180910390fd5b60005b838110156109605782828281811061085b5761085b613190565b905060200201602081019061087091906131b4565b6005600087878581811061088657610886613190565b905060200201602081019061089b9190613040565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558484828181106108d5576108d5613190565b90506020020160208101906108ea9190613040565b6001600160a01b03167fbfd6f983ad3ebd9aeb58497a4e27c4a45c7c299f6895c05fe9204e405bce5b9884848481811061092657610926613190565b905060200201602081019061093b91906131b4565b604051901515815260200160405180910390a280610958816131e7565b915050610841565b5050505050565b600082815260208190526040902060010154610982816116ed565b61098c8383611798565b505050565b6001600160a01b0381163314610a065760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b610a10828261181c565b5050565b610a1c6116f7565b610a24611750565b600080610a46610a3760208b018b613040565b8a604001358b60800135611881565b9092509050610a5860208a018a613040565b6001600160a01b03166339c82de634610a7760408d0160208e01613040565b848d6060016020810190610a8b91906131b4565b8e608001358e8e8e8e6040518a63ffffffff1660e01b8152600401610ab7989796959493929190613291565b6000604051808303818588803b158015610ad057600080fd5b505af1158015610ae4573d6000803e3d6000fd5b50610b0d9350610afb9250505060208b018b613040565b6001600160a01b038416906000611936565b610b1a60208a018a613040565b6001600160a01b0316336001600160a01b031660008051602061361d833981519152600060018d60400135868a8a604051610b5a96959493929190613154565b60405180910390a350506107cf60018055565b6000610b78816116ed565b610b806119f8565b50565b610b8e60003361138a565b80610bac5750610bac60008051602061363d8339815191523361138a565b610bc957604051630992d00560e11b815260040160405180910390fd5b611388811115610beb57604051625b37a160e41b815260040160405180910390fd5b600081118015610c0457506004546001600160a01b0316155b15610c225760405163082398e560e31b815260040160405180910390fd5b60035460408051918252602082018390527f959ec4191db1bd972bfbc60dc7d735d4cfb897ca3fd297f4ebd6ee918feb84d4910160405180910390a1600355565b610c6b6116f7565b610c73611750565b600080610c95610c8660208a018a613040565b89604001358a60800135611881565b9092509050610ca76020890189613040565b6001600160a01b031663d30a41c834610cc660408c0160208d01613040565b84610cd760808e0160608f016131b4565b8d608001358d8d8d6040518963ffffffff1660e01b8152600401610d01979695949392919061332d565b6000604051808303818588803b158015610d1a57600080fd5b505af1158015610d2e573d6000803e3d6000fd5b50610d459350610afb9250505060208a018a613040565b610d526020890189613040565b6001600160a01b0316336001600160a01b031660008051602061361d8339815191526000808c60400135868a8a604051610d9196959493929190613154565b60405180910390a35050610da460018055565b505050505050565b610db760003361138a565b80610dd55750610dd560008051602061363d8339815191523361138a565b610df257604051630992d00560e11b815260040160405180910390fd5b828114610e12576040516330dda05d60e01b815260040160405180910390fd5b60005b8381101561096057611388838383818110610e3257610e32613190565b905060200201351115610e5757604051625b37a160e41b815260040160405180910390fd5b828282818110610e6957610e69613190565b9050602002013560076000878785818110610e8657610e86613190565b90506020020135815260200190815260200160002081905550848482818110610eb157610eb1613190565b905060200201357f2b022a7462191d73614c0d3a87a34970ed11ca5ebe4e7ce53c9ed8bb664ae8d9848484818110610eeb57610eeb613190565b90506020020135604051610f0191815260200190565b60405180910390a280610f13816131e7565b915050610e15565b6001600160a01b0382166000908152600660209081526040808320848452909152808220815160a08101835260609384939092908290810182600386835b82821015610f95578382600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610f59565b505050908252506006919091015460ff90811660209283015290820151919250166001600160401b03811115610fcd57610fcd612a97565b604051908082528060200260200182016040528015610ff6578160200160208202803683370190505b509250806020015160ff166001600160401b0381111561101857611018612a97565b604051908082528060200260200182016040528015611041578160200160208202803683370190505b50915060005b816020015160ff168160ff1610156110e957815160ff82166003811061106f5761106f613190565b602002015160000151848260ff168151811061108d5761108d613190565b6020908102919091010152815160ff8216600381106110ae576110ae613190565b602002015160200151838260ff16815181106110cc576110cc613190565b6020908102919091010152806110e18161337d565b915050611047565b50505b9250929050565b60006110fe816116ed565b610b80611a4a565b61110e6116f7565b611116611750565b60008061113961112960208c018c613040565b8b604001358c608001358c611a87565b909250905061114b60208b018b613040565b6001600160a01b03166339c82de63461116a60408e0160208f01613040565b848e606001602081019061117e91906131b4565b8f608001358e8e8e8e6040518a63ffffffff1660e01b81526004016111aa989796959493929190613291565b6000604051808303818588803b1580156111c357600080fd5b505af11580156111d7573d6000803e3d6000fd5b506111ee9350610afb9250505060208c018c613040565b6111fb60208b018b613040565b6001600160a01b0316336001600160a01b031660008051602061361d833981519152600060018e60400135868a8a60405161123b96959493929190613154565b60405180910390a3505061124e60018055565b5050505050505050565b6112606116f7565b611268611750565b60008061128b61127b60208b018b613040565b8a604001358b608001358b611a87565b909250905061129d60208a018a613040565b6001600160a01b031663d30a41c8346112bc60408d0160208e01613040565b848d60600160208101906112d091906131b4565b8e608001358d8d8d6040518963ffffffff1660e01b81526004016112fa979695949392919061332d565b6000604051808303818588803b15801561131357600080fd5b505af1158015611327573d6000803e3d6000fd5b5061133e9350610afb9250505060208b018b613040565b61134b60208a018a613040565b6001600160a01b0316336001600160a01b031660008051602061361d8339815191526000808d60400135868a8a604051610b5a96959493929190613154565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6000806113c1858585611beb565b90969095509350505050565b6113d56116f7565b6113dd611750565b6001600160a01b038a1660009081526005602052604090205460ff166114165760405163de83a4e960e01b815260040160405180910390fd5b60405163d3a8b63160e01b81526001600160a01b038b169063d3a8b631903490611450908d908d908d908d908d908d908d9060040161339c565b6000604051808303818588803b15801561146957600080fd5b505af115801561147d573d6000803e3d6000fd5b5050505050896001600160a01b0316336001600160a01b031660008051602061361d83398151915260018060008088886040516114bf96959493929190613154565b60405180910390a36114d060018055565b50505050505050505050565b60006114e7816116ed565b6001600160a01b03831661150e576040516312cffc5760e01b815260040160405180910390fd5b6106cb6001600160a01b0385168484611e51565b60008281526020819052604090206001015461153d816116ed565b61098c838361181c565b61155260003361138a565b80611570575061157060008051602061363d8339815191523361138a565b61158d57604051630992d00560e11b815260040160405180910390fd5b828114158061159c5750600383115b156115ba576040516330dda05d60e01b815260040160405180910390fd5b60005b8581101561124e5761164c888888848181106115db576115db613190565b9050602002013587878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250611e8192505050565b80611656816131e7565b9150506115bd565b6000611669816116ed565b6001600160a01b0382166116905760405163082398e560e31b815260040160405180910390fd5b6004546040516001600160a01b038085169216907f21eb548722a564f6e09f039f7aa858ae94c911910f3823b37af2250eeca4f40390600090a350600480546001600160a01b0319166001600160a01b0392909216919091179055565b610b808133612113565b6002600154036117495760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109fd565b6002600155565b60025460ff16156117965760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109fd565b565b6117a2828261138a565b610a10576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556117d83390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b611826828261138a565b15610a10576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6001600160a01b038316600090815260056020526040812054819060ff166118bc5760405163de83a4e960e01b815260040160405180910390fd5b846001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061191e919061342f565b915061192c8286868661216c565b9050935093915050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526119878482612359565b6106cb576040516001600160a01b0384166024820152600060448201526119ee90859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612400565b6106cb8482612400565b611a006124d5565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b611a52611750565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a2d3390565b6001600160a01b038416600090815260056020526040812054819060ff16611ac25760405163de83a4e960e01b815260040160405180910390fd5b856001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b00573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b24919061342f565b91506001600160a01b03821663d505accf3330888735611b4a60408a0160208b0161344c565b604080516001600160e01b031960e089901b1681526001600160a01b0396871660048201529590941660248601526044850192909252606484015260ff16608483015286013560a4820152606086013560c482015260e401600060405180830381600087803b158015611bbc57600080fd5b505af1158015611bd0573d6000803e3d6000fd5b50505050611be08287878761216c565b905094509492505050565b6001600160a01b0383166000908152600660209081526040808320858452909152808220815160a08101835283928392908290810182600386835b82821015611c62578382600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190611c26565b505050908252506006919091015460ff908116602092830152908201519192506000911615801590611c945750600085115b15611db75784600080805b856020015160ff168160ff161015611dae57855160009060ff831660038110611cca57611cca613190565b602002015151875190915060009060ff841660038110611cec57611cec613190565b6020020151602001519050600060018960200151611d0a919061346f565b60ff168460ff1603611d1d575085611d42565b611d278584613488565b871115611d3f57611d388584613488565b9050611d42565b50855b8015611d8557620186a0611d56838361349b565b611d6091906134b2565b611d6a90896134d4565b9750611d7681876134d4565b9550611d828188613488565b96505b82945086600003611d9857505050611dae565b5050508080611da69061337d565b915050611c9f565b50505050611ded565b6000600354118015611dc95750600085115b15611ded57620186a060035486611de0919061349b565b611dea91906134b2565b90505b6000868152600760205260409020548015801590611e0b5750600086115b15611e3557620186a0611e1e828861349b565b611e2891906134b2565b611e3290836134d4565b91505b8194508486611e449190613488565b9350505050935093915050565b6040516001600160a01b03831660248201526044810182905261098c90849063a9059cbb60e01b906064016119b7565b6001600160a01b03841660009081526006602090815260408083208684529091528120905b60038160ff161015611f095760408051808201909152600080825260208201528260ff831660038110611edb57611edb613190565b6002020160008201518160000155602082015181600101559050508080611f019061337d565b915050611ea6565b50825180156120b35760005b818160ff1610156120b157611388848260ff1681518110611f3857611f38613190565b60200260200101511115611f5e57604051625b37a160e41b815260040160405180910390fd5b60008160ff16118015611f8d5750848160ff1681518110611f8157611f81613190565b60200260200101516000145b15611fab57604051630cdd0ebf60e31b815260040160405180910390fd5b60008160ff16118015612000575084611fc560018361346f565b60ff1681518110611fd857611fd8613190565b6020026020010151858260ff1681518110611ff557611ff5613190565b602002602001015111155b1561201e57604051630cdd0ebf60e31b815260040160405180910390fd5b6040518060400160405280868360ff168151811061203e5761203e613190565b60200260200101518152602001858360ff168151811061206057612060613190565b6020026020010151815250836000018260ff166003811061208357612083613190565b60020201600082015181600001556020820151816001015590505080806120a99061337d565b915050611f15565b505b60068201805460ff191660ff831617905560405185906001600160a01b038816907fe875e6846deb900a1c39242590238ce046f1880aceb983ceef966c09a50647a0906121039088908890612d4a565b60405180910390a3505050505050565b61211d828261138a565b610a105761212a8161251e565b612135836020612530565b60405160200161214692919061350b565b60408051601f198184030181529082905262461bcd60e51b82526109fd91600401613580565b6040516370a0823160e01b8152306004820152600090859082906001600160a01b038316906370a0823190602401602060405180830381865afa1580156121b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121db91906135b3565b90506121f26001600160a01b0383163330886126d2565b6040516370a0823160e01b815230600482015260009082906001600160a01b038516906370a0823190602401602060405180830381865afa15801561223b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225f91906135b3565b6122699190613488565b905085811461228b5760405163a62c631560e01b815260040160405180910390fd5b60008061229989888a611beb565b90925090508115612336576004546001600160a01b03166122cd5760405163082398e560e31b815260040160405180910390fd5b6004546122e7906001600160a01b03878116911684611e51565b600454604080518481526001600160a01b0392831660208201528b8316928d169133917f0c7016eab065212f095b32ca6daf66b021b628b6457815d893fff6f43a374c34910160405180910390a45b61234a6001600160a01b0386168a83611936565b9450505050505b949350505050565b6000806000846001600160a01b03168460405161237691906135cc565b6000604051808303816000865af19150503d80600081146123b3576040519150601f19603f3d011682016040523d82523d6000602084013e6123b8565b606091505b50915091508180156123e25750805115806123e25750808060200190518101906123e291906135e8565b80156123f757506001600160a01b0385163b15155b95945050505050565b6000612455826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661270a9092919063ffffffff16565b905080516000148061247657508080602001905181019061247691906135e8565b61098c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109fd565b60025460ff166117965760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109fd565b606061061f6001600160a01b03831660145b6060600061253f83600261349b565b61254a9060026134d4565b6001600160401b0381111561256157612561612a97565b6040519080825280601f01601f19166020018201604052801561258b576020820181803683370190505b509050600360fc1b816000815181106125a6576125a6613190565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106125d5576125d5613190565b60200101906001600160f81b031916908160001a90535060006125f984600261349b565b6126049060016134d4565b90505b600181111561267c576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061263857612638613190565b1a60f81b82828151811061264e5761264e613190565b60200101906001600160f81b031916908160001a90535060049490941c9361267581613605565b9050612607565b5083156126cb5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109fd565b9392505050565b6040516001600160a01b03808516602483015283166044820152606481018290526106cb9085906323b872dd60e01b906084016119b7565b6060612351848460008585600080866001600160a01b0316858760405161273191906135cc565b60006040518083038185875af1925050503d806000811461276e576040519150601f19603f3d011682016040523d82523d6000602084013e612773565b606091505b50915091506127848783838761278f565b979650505050505050565b606083156127fe5782516000036127f7576001600160a01b0385163b6127f75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109fd565b5081612351565b61235183838151156128135781518083602001fd5b8060405162461bcd60e51b81526004016109fd9190613580565b60006020828403121561283f57600080fd5b81356001600160e01b0319811681146126cb57600080fd5b6001600160a01b0381168114610b8057600080fd5b6000806040838503121561287f57600080fd5b823561288a81612857565b946020939093013593505050565b80356128a381612857565b919050565b60008083601f8401126128ba57600080fd5b5081356001600160401b038111156128d157600080fd5b6020830191508360208285010111156110ec57600080fd5b600080600080600080600060a0888a03121561290457600080fd5b873561290f81612857565b965060208801359550604088013561292681612857565b945060608801356001600160401b038082111561294257600080fd5b61294e8b838c016128a8565b909650945060808a013591508082111561296757600080fd5b506129748a828b016128a8565b989b979a50959850939692959293505050565b60006020828403121561299957600080fd5b5035919050565b60008083601f8401126129b257600080fd5b5081356001600160401b038111156129c957600080fd5b6020830191508360208260051b85010111156110ec57600080fd5b600080600080604085870312156129fa57600080fd5b84356001600160401b0380821115612a1157600080fd5b612a1d888389016129a0565b90965094506020870135915080821115612a3657600080fd5b50612a43878288016129a0565b95989497509550505050565b60008060408385031215612a6257600080fd5b823591506020830135612a7481612857565b809150509250929050565b600060a08284031215612a9157600080fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612ad557612ad5612a97565b604052919050565b60006001600160401b03821115612af657612af6612a97565b5060051b60200190565b600082601f830112612b1157600080fd5b81356020612b26612b2183612add565b612aad565b82815260059290921b84018101918181019086841115612b4557600080fd5b8286015b84811015612b69578035612b5c81612857565b8352918301918301612b49565b509695505050505050565b600082601f830112612b8557600080fd5b81356020612b95612b2183612add565b82815260059290921b84018101918181019086841115612bb457600080fd5b8286015b84811015612b695780358352918301918301612bb8565b6000806000806000806000610120888a031215612beb57600080fd5b612bf58989612a7f565b965060a08801356001600160401b0380821115612c1157600080fd5b612c1d8b838c01612b00565b975060c08a0135915080821115612c3357600080fd5b612c3f8b838c01612b74565b965060e08a0135915080821115612c5557600080fd5b612c618b838c016129a0565b90965094506101008a013591508082111561296757600080fd5b6000806000806000806101008789031215612c9557600080fd5b612c9f8888612a7f565b955060a0870135612caf81612857565b945060c08701356001600160401b0380821115612ccb57600080fd5b612cd78a838b016128a8565b909650945060e0890135915080821115612cf057600080fd5b50612cfd89828a016128a8565b979a9699509497509295939492505050565b600081518084526020808501945080840160005b83811015612d3f57815187529582019590820190600101612d23565b509495945050505050565b604081526000612d5d6040830185612d0f565b82810360208401526123f78185612d0f565b600060808284031215612a9157600080fd5b6000806000806000806000806101a0898b031215612d9e57600080fd5b612da88a8a612a7f565b9750612db78a60a08b01612d6f565b96506101208901356001600160401b0380821115612dd457600080fd5b612de08c838d01612b00565b97506101408b0135915080821115612df757600080fd5b612e038c838d01612b74565b96506101608b0135915080821115612e1a57600080fd5b612e268c838d016129a0565b90965094506101808b0135915080821115612e4057600080fd5b50612e4d8b828c016128a8565b999c989b5096995094979396929594505050565b6000806000806000806000610180888a031215612e7d57600080fd5b612e878989612a7f565b9650612e968960a08a01612d6f565b9550610120880135612ea781612857565b94506101408801356001600160401b0380821115612ec457600080fd5b612ed08b838c016128a8565b90965094506101608a013591508082111561296757600080fd5b600080600060608486031215612eff57600080fd5b8335612f0a81612857565b95602085013595506040909401359392505050565b60008060008060008060008060008060c08b8d031215612f3e57600080fd5b612f478b612898565b995060208b0135985060408b01356001600160401b0380821115612f6a57600080fd5b612f768e838f016129a0565b909a50985060608d0135915080821115612f8f57600080fd5b612f9b8e838f016129a0565b909850965060808d0135915080821115612fb457600080fd5b612fc08e838f016129a0565b909650945060a08d0135915080821115612fd957600080fd5b50612fe68d828e016128a8565b915080935050809150509295989b9194979a5092959850565b60008060006060848603121561301457600080fd5b833561301f81612857565b9250602084013561302f81612857565b929592945050506040919091013590565b60006020828403121561305257600080fd5b81356126cb81612857565b60008060008060008060006080888a03121561307857600080fd5b873561308381612857565b965060208801356001600160401b038082111561309f57600080fd5b6130ab8b838c016129a0565b909850965060408a01359150808211156130c457600080fd5b6130d08b838c016129a0565b909650945060608a01359150808211156130e957600080fd5b506129748a828b016129a0565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8481526001600160a01b038416602082015260606040820181905260009061314a90830184866130f6565b9695505050505050565b8615158152851515602082015284604082015283606082015260a06080820152600061318460a0830184866130f6565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b8015158114610b8057600080fd5b6000602082840312156131c657600080fd5b81356126cb816131a6565b634e487b7160e01b600052601160045260246000fd5b6000600182016131f9576131f96131d1565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156132845782840389528135601e1988360301811261323b57600080fd5b870185810190356001600160401b0381111561325657600080fd5b80360382131561326557600080fd5b6132708682846130f6565b9a87019a955050509084019060010161321a565b5091979650505050505050565b600060e0820160018060a01b03808c16845260208b818601528a1515604086015289606086015260e0608086015282895180855261010087019150828b01945060005b818110156132f25785518516835294830194918301916001016132d4565b505085810360a0870152613306818a612d0f565b935050505082810360c084015261331e818587613200565b9b9a5050505050505050505050565b6001600160a01b038881168252602082018890528615156040830152606082018690528416608082015260c060a0820181905260009061337090830184866130f6565b9998505050505050505050565b600060ff821660ff8103613393576133936131d1565b60010192915050565b87815260806020808301829052908201879052600090889060a08401835b8a8110156133e85783356133cd81612857565b6001600160a01b0316825292820192908201906001016133ba565b5084810360408601528781526001600160fb1b0388111561340857600080fd5b8760051b9250828983830137909101838103820160608501529061331e8183018688613200565b60006020828403121561344157600080fd5b81516126cb81612857565b60006020828403121561345e57600080fd5b813560ff811681146126cb57600080fd5b60ff828116828216039081111561061f5761061f6131d1565b8181038181111561061f5761061f6131d1565b808202811582820484141761061f5761061f6131d1565b6000826134cf57634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561061f5761061f6131d1565b60005b838110156135025781810151838201526020016134ea565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516135438160178501602088016134e7565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516135748160288401602088016134e7565b01602801949350505050565b602081526000825180602084015261359f8160408501602087016134e7565b601f01601f19169190910160400192915050565b6000602082840312156135c557600080fd5b5051919050565b600082516135de8184602087016134e7565b9190910192915050565b6000602082840312156135fa57600080fd5b81516126cb816131a6565b600081613614576136146131d1565b50600019019056fedc35ec9c20a3583ca2942e2bf27861adb550876aefb2699c87769d4e0cddcd4d14031051ef64910ea26175284bbaea2d8f485c9aec1697121604906a168aebdba264697066735822122017304cfbcd8841f997b2ab409931d83ed70b197d553f9c553de8a607a50d4edb64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005db7ad07d4903579a0342f7332bd4e3ed480d1af000000000000000000000000b30dc8ada8a9a704cc803b60f98ec92084a87942000000000000000000000000359f01614eed04dbe2b9a3f6d45835cb1b200b25000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000229ac52e807e83bc21507caa93138972da44a61b000000000000000000000000168b439f88ab57bf7633cb39131f91bc90a3b74d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : access (address[2]): 0x5dB7AD07D4903579A0342F7332Bd4E3eD480d1AF,0xb30DC8adA8a9a704cC803B60F98EC92084a87942
Arg [1] : _treasury (address): 0x359f01614EED04Dbe2b9A3F6d45835cB1b200B25
Arg [2] : _feeRate (uint256): 70
Arg [3] : initialControllers (address[]): 0x229ac52e807e83Bc21507CaA93138972Da44A61b,0x168B439F88AB57bF7633CB39131f91BC90A3b74d
Arg [4] : premiumChainIds (uint256[]):
Arg [5] : premiumRate (uint256[]):
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000005db7ad07d4903579a0342f7332bd4e3ed480d1af
Arg [1] : 000000000000000000000000b30dc8ada8a9a704cc803b60f98ec92084a87942
Arg [2] : 000000000000000000000000359f01614eed04dbe2b9a3f6d45835cb1b200b25
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000046
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [8] : 000000000000000000000000229ac52e807e83bc21507caa93138972da44a61b
Arg [9] : 000000000000000000000000168b439f88ab57bf7633cb39131f91bc90a3b74d
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
61398:22164:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26467:204;;;;;;;;;;-1:-1:-1;26467:204:0;;;;;:::i;:::-;;:::i;:::-;;;470:14:1;;463:22;445:41;;433:2;418:18;26467:204:0;;;;;;;;77182:274;;;;;;;;;;-1:-1:-1;77182:274:0;;;;;:::i;:::-;;:::i;:::-;;71774:503;;;;;;:::i;:::-;;:::i;28290:131::-;;;;;;;;;;-1:-1:-1;28290:131:0;;;;;:::i;:::-;28364:7;28391:12;;;;;;;;;;:22;;;;28290:131;;;;2891:25:1;;;2879:2;2864:18;28290:131:0;2745:177:1;73489:403:0;;;;;;;;;;-1:-1:-1;73489:403:0;;;;;:::i;:::-;;:::i;28731:147::-;;;;;;;;;;-1:-1:-1;28731:147:0;;;;;:::i;:::-;;:::i;29875:218::-;;;;;;;;;;-1:-1:-1;29875:218:0;;;;;:::i;:::-;;:::i;69311:773::-;;;;;;:::i;:::-;;:::i;76434:86::-;;;;;;;;;;;;;:::i;74022:316::-;;;;;;;;;;-1:-1:-1;74022:316:0;;;;;:::i;:::-;;:::i;66856:710::-;;;;;;:::i;:::-;;:::i;75503:463::-;;;;;;;;;;-1:-1:-1;75503:463:0;;;;;:::i;:::-;;:::i;33864:86::-;;;;;;;;;;-1:-1:-1;33935:7:0;;;;33864:86;;63697:23;;;;;;;;;;-1:-1:-1;63697:23:0;;;;-1:-1:-1;;;;;63697:23:0;;;;;;-1:-1:-1;;;;;10071:32:1;;;10053:51;;10041:2;10026:18;63697:23:0;9907:203:1;77490:561:0;;;;;;;;;;-1:-1:-1;77490:561:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;63518:50::-;;;;;;;;;;;;63561:7;63518:50;;76344:82;;;;;;;;;;;;;:::i;70589:831::-;;;;;;:::i;:::-;;:::i;68020:768::-;;;;;;:::i;:::-;;:::i;26763:147::-;;;;;;;;;;-1:-1:-1;26763:147:0;;;;;:::i;:::-;;:::i;63586:44::-;;;;;;;;;;;;63625:5;63586:44;;63648:22;;;;;;;;;;;;;;;;78385:195;;;;;;;;;;-1:-1:-1;78385:195:0;;;;;:::i;:::-;;:::i;:::-;;;;14894:25:1;;;14950:2;14935:18;;14928:34;;;;14867:18;78385:195:0;14720:248:1;25868:49:0;;;;;;;;;;-1:-1:-1;25868:49:0;25913:4;25868:49;;64020:55;;;;;;;;;;-1:-1:-1;64020:55:0;;;;;:::i;:::-;;;;;;;;;;;;;;72680:557;;;;;;:::i;:::-;;:::i;76774:221::-;;;;;;;;;;-1:-1:-1;76774:221:0;;;;;:::i;:::-;;:::i;29171:149::-;;;;;;;;;;-1:-1:-1;29171:149:0;;;;;:::i;:::-;;:::i;63746:43::-;;;;;;;;;;-1:-1:-1;63746:43:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;74755:476;;;;;;;;;;-1:-1:-1;74755:476:0;;;;;:::i;:::-;;:::i;76087:249::-;;;;;;;;;;-1:-1:-1;76087:249:0;;;;;:::i;:::-;;:::i;63423:86::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;63423:86:0;;26467:204;26552:4;-1:-1:-1;;;;;;26576:47:0;;-1:-1:-1;;;26576:47:0;;:87;;-1:-1:-1;;;;;;;;;;6162:40:0;;;26627:36;26569:94;26467:204;-1:-1:-1;;26467:204:0:o;77182:274::-;25913:4;26359:16;25913:4;26359:10;:16::i;:::-;-1:-1:-1;;;;;77290:16:0;::::1;77286:50;;77315:21;;-1:-1:-1::0;;;77315:21:0::1;;;;;;;;;;;77286:50;77348:12;77366:2;-1:-1:-1::0;;;;;77366:7:0::1;77381:6;77366:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77347:45;;;77408:7;77403:45;;77424:24;;-1:-1:-1::0;;;77424:24:0::1;;;;;;;;;;;77403:45;77275:181;77182:274:::0;;;:::o;71774:503::-;59337:21;:19;:21::i;:::-;33469:19:::1;:17;:19::i;:::-;-1:-1:-1::0;;;;;72018:23:0;::::2;;::::0;;;:11:::2;:23;::::0;;;;;::::2;;72013:71;;72050:34;;-1:-1:-1::0;;;72050:34:0::2;;;;;;;;;;;72013:71;72095:97;::::0;-1:-1:-1;;;72095:97:0;;-1:-1:-1;;;;;72095:43:0;::::2;::::0;::::2;::::0;72146:9:::2;::::0;72095:97:::2;::::0;72157:10;;72169:7;;72178:13;;;;72095:97:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;72233:10;-1:-1:-1::0;;;;;72208:61:0::2;72221:10;-1:-1:-1::0;;;;;72208:61:0::2;-1:-1:-1::0;;;;;;;;;;;72245:4:0::2;72251:5;72258:1:::0;72261::::2;72264:4;;72208:61;;;;;;;;;;;:::i;:::-;;;;;;;;59381:20:::0;58775:1;59901:22;;59718:213;59381:20;71774:503;;;;;;;:::o;73489:403::-;66190:39;25913:4;66218:10;66190:7;:39::i;:::-;:87;;;;66233:44;-1:-1:-1;;;;;;;;;;;66266:10:0;66233:7;:44::i;:::-;66184:152;;66302:22;;-1:-1:-1;;;66302:22:0;;;;;;;;;;;66184:152;73612:39;;::::1;73608:76;;73660:24;;-1:-1:-1::0;;;73660:24:0::1;;;;;;;;;;;73608:76;73700:9;73695:190;73715:21:::0;;::::1;73695:190;;;73787:11;;73799:1;73787:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;73758:11;:26;73770:10;;73781:1;73770:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;73758:26:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;73758:26:0;:43;;-1:-1:-1;;73758:43:0::1;::::0;::::1;;::::0;;;::::1;::::0;;73843:10;;73854:1;73843:13;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;73821:52:0::1;;73858:11;;73870:1;73858:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;73821:52;::::0;470:14:1;;463:22;445:41;;433:2;418:18;73821:52:0::1;;;;;;;73738:3:::0;::::1;::::0;::::1;:::i;:::-;;;;73695:190;;;;73489:403:::0;;;;:::o;28731:147::-;28364:7;28391:12;;;;;;;;;;:22;;;26359:16;26370:4;26359:10;:16::i;:::-;28845:25:::1;28856:4;28862:7;28845:10;:25::i;:::-;28731:147:::0;;;:::o;29875:218::-;-1:-1:-1;;;;;29971:23:0;;4025:10;29971:23;29963:83;;;;-1:-1:-1;;;29963:83:0;;20928:2:1;29963:83:0;;;20910:21:1;20967:2;20947:18;;;20940:30;21006:34;20986:18;;;20979:62;-1:-1:-1;;;21057:18:1;;;21050:45;21112:19;;29963:83:0;;;;;;;;;30059:26;30071:4;30077:7;30059:11;:26::i;:::-;29875:218;;:::o;69311:773::-;59337:21;:19;:21::i;:::-;33469:19:::1;:17;:19::i;:::-;69571:13:::2;::::0;69601:59:::2;69610:16;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;69628:5;:12;;;69642:5;:17;;;69601:8;:59::i;:::-;69570:90:::0;;-1:-1:-1;69570:90:0;-1:-1:-1;69688:16:0::2;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;-1:-1:-1::0;;;;;69671:45:0::2;;69724:9;69749:15;::::0;;;::::2;::::0;::::2;;:::i;:::-;69779:3;69797:5;:12;;;;;;;;;;:::i;:::-;69824:5;:17;;;69856:8;69879:4;69898:13;;69671:251;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;69933:47:0::2;::::0;-1:-1:-1;69960:16:0::2;::::0;-1:-1:-1;;;69960:16:0::2;::::0;::::2;::::0;::::2;:::i;:::-;-1:-1:-1::0;;;;;69933:26:0;::::2;::::0;69978:1:::2;69933:26;:47::i;:::-;70021:16;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;-1:-1:-1::0;;;;;69996:80:0::2;70009:10;-1:-1:-1::0;;;;;69996:80:0::2;-1:-1:-1::0;;;;;;;;;;;70039:5:0::2;70046:4;70052:5;:12;;;70066:3;70071:4;;69996:80;;;;;;;;;;;:::i;:::-;;;;;;;;69559:525;;59381:20:::0;58775:1;59901:22;;59718:213;76434:86;25913:4;26359:16;25913:4;26359:10;:16::i;:::-;76502:10:::1;:8;:10::i;:::-;76434:86:::0;:::o;74022:316::-;66190:39;25913:4;66218:10;66190:7;:39::i;:::-;:87;;;;66233:44;-1:-1:-1;;;;;;;;;;;66266:10:0;66233:7;:44::i;:::-;66184:152;;66302:22;;-1:-1:-1;;;66302:22:0;;;;;;;;;;;66184:152;63625:5:::1;74101:10;:25;74097:62;;;74135:24;;-1:-1:-1::0;;;74135:24:0::1;;;;;;;;;;;74097:62;74187:1;74174:10;:14;:40;;;;-1:-1:-1::0;74192:8:0::1;::::0;-1:-1:-1;;;;;74192:8:0::1;:22:::0;74174:40:::1;74170:82;;;74223:29;;-1:-1:-1::0;;;74223:29:0::1;;;;;;;;;;;74170:82;74279:7;::::0;74268:31:::1;::::0;;14894:25:1;;;14950:2;14935:18;;14928:34;;;74268:31:0::1;::::0;14867:18:1;74268:31:0::1;;;;;;;74310:7;:20:::0;74022:316::o;66856:710::-;59337:21;:19;:21::i;:::-;33469:19:::1;:17;:19::i;:::-;67072:13:::2;::::0;67102:59:::2;67111:16;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;67129:5;:12;;;67143:5;:17;;;67102:8;:59::i;:::-;67071:90:::0;;-1:-1:-1;67071:90:0;-1:-1:-1;67189:16:0::2;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;-1:-1:-1::0;;;;;67172:45:0::2;;67225:9;67250:15;::::0;;;::::2;::::0;::::2;;:::i;:::-;67280:3:::0;67298:12:::2;::::0;;;::::2;::::0;::::2;;:::i;:::-;67325:5;:17;;;67357:7;67379:13;;67172:231;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;67414:47:0::2;::::0;-1:-1:-1;67441:16:0::2;::::0;-1:-1:-1;;;67441:16:0::2;::::0;::::2;::::0;::::2;:::i;67414:47::-;67502:16;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;-1:-1:-1::0;;;;;67477:81:0::2;67490:10;-1:-1:-1::0;;;;;67477:81:0::2;-1:-1:-1::0;;;;;;;;;;;67520:5:0::2;67527::::0;67534::::2;:12;;;67548:3;67553:4;;67477:81;;;;;;;;;;;:::i;:::-;;;;;;;;67060:506;;59381:20:::0;58775:1;59901:22;;59718:213;59381:20;66856:710;;;;;;:::o;75503:463::-;66190:39;25913:4;66218:10;66190:7;:39::i;:::-;:87;;;;66233:44;-1:-1:-1;;;;;;;;;;;66266:10:0;66233:7;:44::i;:::-;66184:152;;66302:22;;-1:-1:-1;;;66302:22:0;;;;;;;;;;;66184:152;75630:31;;::::1;75626:68;;75670:24;;-1:-1:-1::0;;;75670:24:0::1;;;;;;;;;;;75626:68;75710:9;75705:254;75725:19:::0;;::::1;75705:254;;;63625:5;75770;;75776:1;75770:8;;;;;;;:::i;:::-;;;;;;;:23;75766:60;;;75802:24;;-1:-1:-1::0;;;75802:24:0::1;;;;;;;;;;;75766:60;75877:5;;75883:1;75877:8;;;;;;;:::i;:::-;;;;;;;75841:20;:33;75862:8;;75871:1;75862:11;;;;;;;:::i;:::-;;;;;;;75841:33;;;;;;;;;;;:44;;;;75925:8;;75934:1;75925:11;;;;;;;:::i;:::-;;;;;;;75905:42;75938:5;;75944:1;75938:8;;;;;;;:::i;:::-;;;;;;;75905:42;;;;2891:25:1::0;;2879:2;2864:18;;2745:177;75905:42:0::1;;;;;;;;75746:3:::0;::::1;::::0;::::1;:::i;:::-;;;;75705:254;;77490:561:::0;-1:-1:-1;;;;;77703:31:0;;77673:27;77703:31;;;:19;:31;;;;;;;;:44;;;;;;;;;77673:74;;;;;;;77610:27;;;;77673;;77703:44;77673:74;;;;77703:44;77673:74;:27;:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;77673:74:0;;;-1:-1:-1;77673:74:0;;;;;;;;;;;;;;;77785:12;;;;77673:74;;-1:-1:-1;77771:27:0;-1:-1:-1;;;;;77771:27:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77771:27:0;;77758:40;;77830:6;:12;;;77816:27;;-1:-1:-1;;;;;77816:27:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77816:27:0;;77809:34;;77859:7;77854:154;77876:6;:12;;;77872:16;;:1;:16;;;77854:154;;;77926:12;;:15;;;;;;;;;;:::i;:::-;;;;;:25;;;77910:10;77921:1;77910:13;;;;;;;;;;:::i;:::-;;;;;;;;;;:41;77976:12;;:15;;;;;;;;;;:::i;:::-;;;;;:20;;;77966:4;77971:1;77966:7;;;;;;;;;;:::i;:::-;;;;;;;;;;:30;77890:3;;;;:::i;:::-;;;;77854:154;;;;78018:25;77490:561;;;;;;:::o;76344:82::-;25913:4;26359:16;25913:4;26359:10;:16::i;:::-;76410:8:::1;:6;:8::i;70589:831::-:0;59337:21;:19;:21::i;:::-;33469:19:::1;:17;:19::i;:::-;70893:13:::2;::::0;70923:73:::2;70938:16;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;70956:5;:12;;;70970:5;:17;;;70989:6;70923:14;:73::i;:::-;70892:104:::0;;-1:-1:-1;70892:104:0;-1:-1:-1;71024:16:0::2;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;-1:-1:-1::0;;;;;71007:45:0::2;;71060:9;71085:15;::::0;;;::::2;::::0;::::2;;:::i;:::-;71115:3;71133:5;:12;;;;;;;;;;:::i;:::-;71160:5;:17;;;71192:8;71215:4;71234:13;;71007:251;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;71269:47:0::2;::::0;-1:-1:-1;71296:16:0::2;::::0;-1:-1:-1;;;71296:16:0::2;::::0;::::2;::::0;::::2;:::i;71269:47::-;71357:16;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;-1:-1:-1::0;;;;;71332:80:0::2;71345:10;-1:-1:-1::0;;;;;71332:80:0::2;-1:-1:-1::0;;;;;;;;;;;71375:5:0::2;71382:4;71388:5;:12;;;71402:3;71407:4;;71332:80;;;;;;;;;;;:::i;:::-;;;;;;;;70881:539;;59381:20:::0;58775:1;59901:22;;59718:213;59381:20;70589:831;;;;;;;;:::o;68020:768::-;59337:21;:19;:21::i;:::-;33469:19:::1;:17;:19::i;:::-;68280:13:::2;::::0;68310:73:::2;68325:16;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;68343:5;:12;;;68357:5;:17;;;68376:6;68310:14;:73::i;:::-;68279:104:::0;;-1:-1:-1;68279:104:0;-1:-1:-1;68411:16:0::2;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;-1:-1:-1::0;;;;;68394:45:0::2;;68447:9;68472:15;::::0;;;::::2;::::0;::::2;;:::i;:::-;68502:3;68520:5;:12;;;;;;;;;;:::i;:::-;68547:5;:17;;;68579:7;68601:13;;68394:231;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;68636:47:0::2;::::0;-1:-1:-1;68663:16:0::2;::::0;-1:-1:-1;;;68663:16:0::2;::::0;::::2;::::0;::::2;:::i;68636:47::-;68724:16;;::::0;::::2;:5:::0;:16:::2;:::i;:::-;-1:-1:-1::0;;;;;68699:81:0::2;68712:10;-1:-1:-1::0;;;;;68699:81:0::2;-1:-1:-1::0;;;;;;;;;;;68742:5:0::2;68749::::0;68756::::2;:12;;;68770:3;68775:4;;68699:81;;;;;;;;;;;:::i;26763:147::-:0;26849:4;26873:12;;;;;;;;;;;-1:-1:-1;;;;;26873:29:0;;;;;;;;;;;;;;;26763:147::o;78385:195::-;78480:11;78493;78530:42;78540:10;78552:11;78565:6;78530:9;:42::i;:::-;78517:55;;;;-1:-1:-1;78385:195:0;-1:-1:-1;;;;78385:195:0:o;72680:557::-;59337:21;:19;:21::i;:::-;33469:19:::1;:17;:19::i;:::-;-1:-1:-1::0;;;;;72972:23:0;::::2;;::::0;;;:11:::2;:23;::::0;;;;;::::2;;72967:71;;73004:34;;-1:-1:-1::0;;;73004:34:0::2;;;;;;;;;;;72967:71;73049:104;::::0;-1:-1:-1;;;73049:104:0;;-1:-1:-1;;;;;73049:43:0;::::2;::::0;::::2;::::0;73100:9:::2;::::0;73049:104:::2;::::0;73111:10;;73123:8;;;;73133:4;;;;73139:13;;;;73049:104:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;73194:10;-1:-1:-1::0;;;;;73169:60:0::2;73182:10;-1:-1:-1::0;;;;;73169:60:0::2;-1:-1:-1::0;;;;;;;;;;;73206:4:0::2;73212::::0;73218:1:::2;73221::::0;73224:4:::2;;73169:60;;;;;;;;;;;:::i;:::-;;;;;;;;59381:20:::0;58775:1;59901:22;;59718:213;59381:20;72680:557;;;;;;;;;;:::o;76774:221::-;25913:4;26359:16;25913:4;26359:10;:16::i;:::-;-1:-1:-1;;;;;76892:16:0;::::1;76888:50;;76917:21;;-1:-1:-1::0;;;76917:21:0::1;;;;;;;;;;;76888:50;76949:38;-1:-1:-1::0;;;;;76949:26:0;::::1;76976:2:::0;76980:6;76949:26:::1;:38::i;29171:149::-:0;28364:7;28391:12;;;;;;;;;;:22;;;26359:16;26370:4;26359:10;:16::i;:::-;29286:26:::1;29298:4;29304:7;29286:11;:26::i;74755:476::-:0;66190:39;25913:4;66218:10;66190:7;:39::i;:::-;:87;;;;66233:44;-1:-1:-1;;;;;;;;;;;66266:10:0;66233:7;:44::i;:::-;66184:152;;66302:22;;-1:-1:-1;;;66302:22:0;;;;;;;;;;;66184:152;74977:32;;::::1;;::::0;:57:::1;;-1:-1:-1::0;75033:1:0::1;75013:21:::0;::::1;74977:57;74973:94;;;75043:24;;-1:-1:-1::0;;;75043:24:0::1;;;;;;;;;;;74973:94;75083:9;75078:146;75098:23:::0;;::::1;75078:146;;;75143:69;75166:10;75178:12;;75191:1;75178:15;;;;;;;:::i;:::-;;;;;;;75195:10;;75143:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;75143:69:0::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;-1:-1:-1;75207:4:0;;-1:-1:-1;75207:4:0;;;;75143:69;::::1;::::0;75207:4;;75143:69;75207:4;75143:69;::::1;;::::0;::::1;::::0;;;;-1:-1:-1;75143:22:0::1;::::0;-1:-1:-1;;;75143:69:0:i:1;:::-;75123:3:::0;::::1;::::0;::::1;:::i;:::-;;;;75078:146;;76087:249:::0;25913:4;26359:16;25913:4;26359:10;:16::i;:::-;-1:-1:-1;;;;;76182:25:0;::::1;76178:67;;76216:29;;-1:-1:-1::0;;;76216:29:0::1;;;;;;;;;;;76178:67;76273:8;::::0;76261:34:::1;::::0;-1:-1:-1;;;;;76261:34:0;;::::1;::::0;76273:8:::1;::::0;76261:34:::1;::::0;76273:8:::1;::::0;76261:34:::1;-1:-1:-1::0;76306:8:0::1;:22:::0;;-1:-1:-1;;;;;;76306:22:0::1;-1:-1:-1::0;;;;;76306:22:0;;;::::1;::::0;;;::::1;::::0;;76087:249::o;27214:105::-;27281:30;27292:4;4025:10;27281;:30::i;59417:293::-;58819:1;59551:7;;:19;59543:63;;;;-1:-1:-1;;;59543:63:0;;26638:2:1;59543:63:0;;;26620:21:1;26677:2;26657:18;;;26650:30;26716:33;26696:18;;;26689:61;26767:18;;59543:63:0;26436:355:1;59543:63:0;58819:1;59684:7;:18;59417:293::o;34023:108::-;33935:7;;;;34093:9;34085:38;;;;-1:-1:-1;;;34085:38:0;;26998:2:1;34085:38:0;;;26980:21:1;27037:2;27017:18;;;27010:30;-1:-1:-1;;;27056:18:1;;;27049:46;27112:18;;34085:38:0;26796:340:1;34085:38:0;34023:108::o;31472:238::-;31556:22;31564:4;31570:7;31556;:22::i;:::-;31551:152;;31595:6;:12;;;;;;;;;;;-1:-1:-1;;;;;31595:29:0;;;;;;;;;:36;;-1:-1:-1;;31595:36:0;31627:4;31595:36;;;31678:12;4025:10;;3945:98;31678:12;-1:-1:-1;;;;;31651:40:0;31669:7;-1:-1:-1;;;;;31651:40:0;31663:4;31651:40;;;;;;;;;;31472:238;;:::o;31890:239::-;31974:22;31982:4;31988:7;31974;:22::i;:::-;31970:152;;;32045:5;32013:12;;;;;;;;;;;-1:-1:-1;;;;;32013:29:0;;;;;;;;;;:37;;-1:-1:-1;;32013:37:0;;;32070:40;4025:10;;32013:12;;32070:40;;32045:5;32070:40;31890:239;;:::o;81695:351::-;-1:-1:-1;;;;;81838:23:0;;81788:13;81838:23;;;:11;:23;;;;;;81788:13;;81838:23;;81833:71;;81870:34;;-1:-1:-1;;;81870:34:0;;;;;;;;;;;81833:71;81940:10;-1:-1:-1;;;;;81923:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81915:44;;81982:56;81999:5;82006:10;82018:6;82026:11;81982:16;:56::i;:::-;81970:68;;81695:351;;;;;;:::o;53714:417::-;53830:62;;;-1:-1:-1;;;;;27597:32:1;;53830:62:0;;;27579:51:1;27646:18;;;;27639:34;;;53830:62:0;;;;;;;;;;27552:18:1;;;;53830:62:0;;;;;;;;-1:-1:-1;;;;;53830:62:0;-1:-1:-1;;;53830:62:0;;;53910:44;53934:5;53830:62;53910:23;:44::i;:::-;53905:219;;53998:58;;-1:-1:-1;;;;;27882:32:1;;53998:58:0;;;27864:51:1;54054:1:0;27931:18:1;;;27924:45;53971:86:0;;53991:5;;-1:-1:-1;;;54021:22:0;27837:18:1;;53998:58:0;;;;-1:-1:-1;;53998:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;53998:58:0;-1:-1:-1;;;;;;53998:58:0;;;;;;;;;;53971:19;:86::i;:::-;54072:40;54092:5;54099:12;54072:19;:40::i;34719:120::-;33728:16;:14;:16::i;:::-;34778:7:::1;:15:::0;;-1:-1:-1;;34778:15:0::1;::::0;;34809:22:::1;4025:10:::0;34818:12:::1;34809:22;::::0;-1:-1:-1;;;;;10071:32:1;;;10053:51;;10041:2;10026:18;34809:22:0::1;;;;;;;34719:120::o:0;34460:118::-;33469:19;:17;:19::i;:::-;34520:7:::1;:14:::0;;-1:-1:-1;;34520:14:0::1;34530:4;34520:14;::::0;;34550:20:::1;34557:12;4025:10:::0;;3945:98;82054:551;-1:-1:-1;;;;;82274:23:0;;82224:13;82274:23;;;:11;:23;;;;;;82224:13;;82274:23;;82269:71;;82306:34;;-1:-1:-1;;;82306:34:0;;;;;;;;;;;82269:71;82376:10;-1:-1:-1;;;;;82359:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82351:44;-1:-1:-1;;;;;;82408:26:0;;;82435:10;82455:4;82462:6;82470:15;;82487:8;;;;;;;;:::i;:::-;82497;82408:108;;-1:-1:-1;;;;;;82408:108:0;;;;;;;-1:-1:-1;;;;;28621:15:1;;;82408:108:0;;;28603:34:1;28673:15;;;;28653:18;;;28646:43;28705:18;;;28698:34;;;;28748:18;;;28741:34;28824:4;28812:17;28791:19;;;28784:46;82497:8:0;;;28846:19:1;;;28839:35;82507:8:0;;;;28890:19:1;;;28883:35;28537:19;;82408:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82541:56;82558:5;82565:10;82577:6;82585:11;82541:16;:56::i;:::-;82529:68;;82054:551;;;;;;;:::o;79790:1897::-;-1:-1:-1;;;;;79956:31:0;;79889:11;79956:31;;;:19;:31;;;;;;;;:44;;;;;;;;;79926:74;;;;;;;79889:11;;;;79956:44;79926:74;;;;79956:44;79926:74;79889:11;79926:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;79926:74:0;;;-1:-1:-1;79926:74:0;;;;;;;;;;;;;;;80045:12;;;;79926:74;;-1:-1:-1;79926:74:0;;80045:16;;;;;:30;;;80074:1;80065:6;:10;80045:30;80041:1260;;;80151:6;80131:17;;;80244:892;80266:6;:12;;;80262:16;;:1;:16;;;80244:892;;;80324:12;;80304:17;;80324:15;;;;;;;;;;:::i;:::-;;;;;:25;80383:12;;80324:25;;-1:-1:-1;80324:25:0;;80383:15;;;;;;;;;;:::i;:::-;;;;;:20;;;80368:35;;80422:18;80483:1;80468:6;:12;;;:16;;;;:::i;:::-;80463:21;;:1;:21;;;80459:356;;-1:-1:-1;80593:9:0;80459:356;;;80644:21;80656:9;80644;:21;:::i;:::-;80632:9;:33;80628:187;;;80703:21;80715:9;80703;:21;:::i;:::-;80690:34;;80628:187;;;-1:-1:-1;80786:9:0;80628:187;80837:14;;80833:204;;63561:7;80888:17;80901:4;80888:10;:17;:::i;:::-;80887:38;;;;:::i;:::-;80876:49;;;;:::i;:::-;;-1:-1:-1;80948:23:0;80961:10;80948:23;;:::i;:::-;;-1:-1:-1;80994:23:0;81007:10;80994:23;;:::i;:::-;;;80833:204;81067:9;81055:21;;81099:9;81112:1;81099:14;81095:25;;81115:5;;;;;81095:25;80285:851;;;80280:3;;;;;:::i;:::-;;;;80244:892;;;;80077:1070;;;80041:1260;;;81167:1;81157:7;;:11;:25;;;;;81181:1;81172:6;:10;81157:25;81153:148;;;63561:7;81262;;81253:6;:16;;;;:::i;:::-;81252:37;;;;:::i;:::-;81242:47;;81153:148;81364:19;81386:33;;;:20;:33;;;;;;81434:15;;;;;:29;;;81462:1;81453:6;:10;81434:29;81430:195;;;63561:7;81573:20;81582:11;81573:6;:20;:::i;:::-;81572:41;;;;:::i;:::-;81561:52;;;;:::i;:::-;;;81430:195;81643:7;81637:13;;81676:3;81667:6;:12;;;;:::i;:::-;81661:18;;79915:1772;;;79790:1897;;;;;;:::o;50820:177::-;50930:58;;-1:-1:-1;;;;;27597:32:1;;50930:58:0;;;27579:51:1;27646:18;;;27639:34;;;50903:86:0;;50923:5;;-1:-1:-1;;;50953:23:0;27552:18:1;;50930:58:0;27405:274:1;78625:1157:0;-1:-1:-1;;;;;78802:32:0;;78771:28;78802:32;;;:19;:32;;;;;;;;:45;;;;;;;;;78891:88;78913:1;78909;:5;;;78891:88;;;78954:13;;;;;;;;;-1:-1:-1;78954:13:0;;;;;;;78936:6;:15;;;;;;;;;;:::i;:::-;;;;:31;;;;;;;;;;;;;;;;;;;78916:3;;;;;:::i;:::-;;;;78891:88;;;-1:-1:-1;79005:17:0;;79039:9;;79035:621;;79070:7;79065:580;79087:5;79083:1;:9;;;79065:580;;;63625:5;79185:4;79190:1;79185:7;;;;;;;;;;:::i;:::-;;;;;;;:22;79181:59;;;79216:24;;-1:-1:-1;;;79216:24:0;;;;;;;;;;;79181:59;79336:1;79332;:5;;;:27;;;;;79341:10;79352:1;79341:13;;;;;;;;;;:::i;:::-;;;;;;;79358:1;79341:18;79332:27;79328:63;;;79368:23;;-1:-1:-1;;;79368:23:0;;;;;;;;;;;79328:63;79488:1;79484;:5;;;:43;;;;-1:-1:-1;79510:10:0;79521:5;79525:1;79521;:5;:::i;:::-;79510:17;;;;;;;;;;:::i;:::-;;;;;;;79493:10;79504:1;79493:13;;;;;;;;;;:::i;:::-;;;;;;;:34;;79484:43;79480:79;;;79536:23;;-1:-1:-1;;;79536:23:0;;;;;;;;;;;79480:79;79598:31;;;;;;;;79606:10;79617:1;79606:13;;;;;;;;;;:::i;:::-;;;;;;;79598:31;;;;79621:4;79626:1;79621:7;;;;;;;;;;:::i;:::-;;;;;;;79598:31;;;79580:6;:12;;79593:1;79580:15;;;;;;;;;:::i;:::-;;;;:49;;;;;;;;;;;;;;;;;;;79094:3;;;;;:::i;:::-;;;;79065:580;;;;79035:621;79666:12;;;:27;;-1:-1:-1;;79666:27:0;;;;;;;79709:65;;79744:11;;-1:-1:-1;;;;;79709:65:0;;;;;;;79757:10;;79769:4;;79709:65;:::i;:::-;;;;;;;;78760:1022;;78625:1157;;;;:::o;27609:492::-;27698:22;27706:4;27712:7;27698;:22::i;:::-;27693:401;;27886:28;27906:7;27886:19;:28::i;:::-;27987:38;28015:4;28022:2;27987:19;:38::i;:::-;27791:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;27791:257:0;;;;;;;;;;-1:-1:-1;;;27737:345:0;;;;;;;:::i;82613:909::-;82886:26;;-1:-1:-1;;;82886:26:0;;82906:4;82886:26;;;10053:51:1;82729:17:0;;82777:5;;82729:17;;-1:-1:-1;;;;;82886:11:0;;;;;10026:18:1;;82886:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;82866:46;-1:-1:-1;82923:53:0;-1:-1:-1;;;;;82923:18:0;;82942:10;82962:4;82969:6;82923:18;:53::i;:::-;83006:26;;-1:-1:-1;;;83006:26:0;;83026:4;83006:26;;;10053:51:1;82987:16:0;;83035:9;;-1:-1:-1;;;;;83006:11:0;;;;;10026:18:1;;83006:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38;;;;:::i;:::-;82987:57;;83071:6;83059:8;:18;83055:71;;83086:40;;-1:-1:-1;;;83086:40:0;;;;;;;;;;;83055:71;83140:11;83153;83168:42;83178:10;83190:11;83203:6;83168:9;:42::i;:::-;83139:71;;-1:-1:-1;83139:71:0;-1:-1:-1;83227:7:0;;83223:227;;83255:8;;-1:-1:-1;;;;;83255:8:0;83251:64;;83286:29;;-1:-1:-1;;;83286:29:0;;;;;;;;;;;83251:64;83345:8;;83330:29;;-1:-1:-1;;;;;83330:14:0;;;;83345:8;83355:3;83330:14;:29::i;:::-;83429:8;;83379:59;;;31579:25:1;;;-1:-1:-1;;;;;83429:8:0;;;31635:2:1;31620:18;;31613:60;83379:59:0;;;;;;;83393:10;;83379:59;;31552:18:1;83379:59:0;;;;;;;83223:227;83462:31;-1:-1:-1;;;;;83462:14:0;;83477:10;83489:3;83462:14;:31::i;:::-;83511:3;-1:-1:-1;;;;;82613:909:0;;;;;;;:::o;56326:602::-;56409:4;56716:12;56730:23;56765:5;-1:-1:-1;;;;;56757:19:0;56777:4;56757:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56715:67;;;;56813:7;:69;;;;-1:-1:-1;56825:17:0;;:22;;:56;;;56862:10;56851:30;;;;;;;;;;;;:::i;:::-;56813:107;;;;-1:-1:-1;;;;;;41999:19:0;;;:23;;56886:34;56793:127;56326:602;-1:-1:-1;;;;;56326:602:0:o;55166:649::-;55590:23;55616:69;55644:4;55616:69;;;;;;;;;;;;;;;;;55624:5;-1:-1:-1;;;;;55616:27:0;;;:69;;;;;:::i;:::-;55590:95;;55704:10;:17;55725:1;55704:22;:56;;;;55741:10;55730:30;;;;;;;;;;;;:::i;:::-;55696:111;;;;-1:-1:-1;;;55696:111:0;;32428:2:1;55696:111:0;;;32410:21:1;32467:2;32447:18;;;32440:30;32506:34;32486:18;;;32479:62;-1:-1:-1;;;32557:18:1;;;32550:40;32607:19;;55696:111:0;32226:406:1;34208:108:0;33935:7;;;;34267:41;;;;-1:-1:-1;;;34267:41:0;;32839:2:1;34267:41:0;;;32821:21:1;32878:2;32858:18;;;32851:30;-1:-1:-1;;;32897:18:1;;;32890:50;32957:18;;34267:41:0;32637:344:1;23322:151:0;23380:13;23413:52;-1:-1:-1;;;;;23425:22:0;;21197:2;22718:447;22793:13;22819:19;22851:10;22855:6;22851:1;:10;:::i;:::-;:14;;22864:1;22851:14;:::i;:::-;-1:-1:-1;;;;;22841:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22841:25:0;;22819:47;;-1:-1:-1;;;22877:6:0;22884:1;22877:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;22877:15:0;;;;;;;;;-1:-1:-1;;;22903:6:0;22910:1;22903:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;22903:15:0;;;;;;;;-1:-1:-1;22934:9:0;22946:10;22950:6;22946:1;:10;:::i;:::-;:14;;22959:1;22946:14;:::i;:::-;22934:26;;22929:131;22966:1;22962;:5;22929:131;;;-1:-1:-1;;;23010:5:0;23018:3;23010:11;23001:21;;;;;;;:::i;:::-;;;;22989:6;22996:1;22989:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;22989:33:0;;;;;;;;-1:-1:-1;23047:1:0;23037:11;;;;;22969:3;;;:::i;:::-;;;22929:131;;;-1:-1:-1;23078:10:0;;23070:55;;;;-1:-1:-1;;;23070:55:0;;33329:2:1;23070:55:0;;;33311:21:1;;;33348:18;;;33341:30;33407:34;33387:18;;;33380:62;33459:18;;23070:55:0;33127:356:1;23070:55:0;23150:6;22718:447;-1:-1:-1;;;22718:447:0:o;51242:205::-;51370:68;;-1:-1:-1;;;;;33746:15:1;;;51370:68:0;;;33728:34:1;33798:15;;33778:18;;;33771:43;33830:18;;;33823:34;;;51343:96:0;;51363:5;;-1:-1:-1;;;51393:27:0;33663:18:1;;51370:68:0;33488:375:1;44459:229:0;44596:12;44628:52;44650:6;44658:4;44664:1;44667:12;44596;45833;45847:23;45874:6;-1:-1:-1;;;;;45874:11:0;45893:5;45900:4;45874:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45832:73;;;;45923:69;45950:6;45958:7;45967:10;45979:12;45923:26;:69::i;:::-;45916:76;45545:455;-1:-1:-1;;;;;;;45545:455:0:o;48118:644::-;48303:12;48332:7;48328:427;;;48360:10;:17;48381:1;48360:22;48356:290;;-1:-1:-1;;;;;41999:19:0;;;48570:60;;;;-1:-1:-1;;;48570:60:0;;34477:2:1;48570:60:0;;;34459:21:1;34516:2;34496:18;;;34489:30;34555:31;34535:18;;;34528:59;34604:18;;48570:60:0;34275:353:1;48570:60:0;-1:-1:-1;48667:10:0;48660:17;;48328:427;48710:33;48718:10;48730:12;49465:17;;:21;49461:388;;49697:10;49691:17;49754:15;49741:10;49737:2;49733:19;49726:44;49461:388;49824:12;49817:20;;-1:-1:-1;;;49817:20:0;;;;;;;;:::i;14:286:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;167:23;;-1:-1:-1;;;;;;219:32:1;;209:43;;199:71;;266:1;263;256:12;497:139;-1:-1:-1;;;;;580:31:1;;570:42;;560:70;;626:1;623;616:12;641:331;717:6;725;778:2;766:9;757:7;753:23;749:32;746:52;;;794:1;791;784:12;746:52;833:9;820:23;852:39;885:5;852:39;:::i;:::-;910:5;962:2;947:18;;;;934:32;;-1:-1:-1;;;641:331:1:o;977:142::-;1045:20;;1074:39;1045:20;1074:39;:::i;:::-;977:142;;;:::o;1124:347::-;1175:8;1185:6;1239:3;1232:4;1224:6;1220:17;1216:27;1206:55;;1257:1;1254;1247:12;1206:55;-1:-1:-1;1280:20:1;;-1:-1:-1;;;;;1312:30:1;;1309:50;;;1355:1;1352;1345:12;1309:50;1392:4;1384:6;1380:17;1368:29;;1444:3;1437:4;1428:6;1420;1416:19;1412:30;1409:39;1406:59;;;1461:1;1458;1451:12;1476:1079;1593:6;1601;1609;1617;1625;1633;1641;1694:3;1682:9;1673:7;1669:23;1665:33;1662:53;;;1711:1;1708;1701:12;1662:53;1750:9;1737:23;1769:39;1802:5;1769:39;:::i;:::-;1827:5;-1:-1:-1;1879:2:1;1864:18;;1851:32;;-1:-1:-1;1935:2:1;1920:18;;1907:32;1948:41;1907:32;1948:41;:::i;:::-;2008:7;-1:-1:-1;2066:2:1;2051:18;;2038:32;-1:-1:-1;;;;;2119:14:1;;;2116:34;;;2146:1;2143;2136:12;2116:34;2185:58;2235:7;2226:6;2215:9;2211:22;2185:58;:::i;:::-;2262:8;;-1:-1:-1;2159:84:1;-1:-1:-1;2350:3:1;2335:19;;2322:33;;-1:-1:-1;2367:16:1;;;2364:36;;;2396:1;2393;2386:12;2364:36;;2435:60;2487:7;2476:8;2465:9;2461:24;2435:60;:::i;:::-;1476:1079;;;;-1:-1:-1;1476:1079:1;;-1:-1:-1;1476:1079:1;;;;2409:86;;-1:-1:-1;;;1476:1079:1:o;2560:180::-;2619:6;2672:2;2660:9;2651:7;2647:23;2643:32;2640:52;;;2688:1;2685;2678:12;2640:52;-1:-1:-1;2711:23:1;;2560:180;-1:-1:-1;2560:180:1:o;2927:367::-;2990:8;3000:6;3054:3;3047:4;3039:6;3035:17;3031:27;3021:55;;3072:1;3069;3062:12;3021:55;-1:-1:-1;3095:20:1;;-1:-1:-1;;;;;3127:30:1;;3124:50;;;3170:1;3167;3160:12;3124:50;3207:4;3199:6;3195:17;3183:29;;3267:3;3260:4;3250:6;3247:1;3243:14;3235:6;3231:27;3227:38;3224:47;3221:67;;;3284:1;3281;3274:12;3299:770;3418:6;3426;3434;3442;3495:2;3483:9;3474:7;3470:23;3466:32;3463:52;;;3511:1;3508;3501:12;3463:52;3551:9;3538:23;-1:-1:-1;;;;;3621:2:1;3613:6;3610:14;3607:34;;;3637:1;3634;3627:12;3607:34;3676:70;3738:7;3729:6;3718:9;3714:22;3676:70;:::i;:::-;3765:8;;-1:-1:-1;3650:96:1;-1:-1:-1;3853:2:1;3838:18;;3825:32;;-1:-1:-1;3869:16:1;;;3866:36;;;3898:1;3895;3888:12;3866:36;;3937:72;4001:7;3990:8;3979:9;3975:24;3937:72;:::i;:::-;3299:770;;;;-1:-1:-1;4028:8:1;-1:-1:-1;;;;3299:770:1:o;4074:323::-;4142:6;4150;4203:2;4191:9;4182:7;4178:23;4174:32;4171:52;;;4219:1;4216;4209:12;4171:52;4255:9;4242:23;4232:33;;4315:2;4304:9;4300:18;4287:32;4328:39;4361:5;4328:39;:::i;:::-;4386:5;4376:15;;;4074:323;;;;;:::o;4402:161::-;4467:5;4512:3;4503:6;4498:3;4494:16;4490:26;4487:46;;;4529:1;4526;4519:12;4487:46;-1:-1:-1;4551:6:1;4402:161;-1:-1:-1;4402:161:1:o;4568:127::-;4629:10;4624:3;4620:20;4617:1;4610:31;4660:4;4657:1;4650:15;4684:4;4681:1;4674:15;4700:275;4771:2;4765:9;4836:2;4817:13;;-1:-1:-1;;4813:27:1;4801:40;;-1:-1:-1;;;;;4856:34:1;;4892:22;;;4853:62;4850:88;;;4918:18;;:::i;:::-;4954:2;4947:22;4700:275;;-1:-1:-1;4700:275:1:o;4980:183::-;5040:4;-1:-1:-1;;;;;5065:6:1;5062:30;5059:56;;;5095:18;;:::i;:::-;-1:-1:-1;5140:1:1;5136:14;5152:4;5132:25;;4980:183::o;5168:745::-;5222:5;5275:3;5268:4;5260:6;5256:17;5252:27;5242:55;;5293:1;5290;5283:12;5242:55;5329:6;5316:20;5355:4;5379:60;5395:43;5435:2;5395:43;:::i;:::-;5379:60;:::i;:::-;5473:15;;;5559:1;5555:10;;;;5543:23;;5539:32;;;5504:12;;;;5583:15;;;5580:35;;;5611:1;5608;5601:12;5580:35;5647:2;5639:6;5635:15;5659:225;5675:6;5670:3;5667:15;5659:225;;;5755:3;5742:17;5772:39;5805:5;5772:39;:::i;:::-;5824:18;;5862:12;;;;5692;;5659:225;;;-1:-1:-1;5902:5:1;5168:745;-1:-1:-1;;;;;;5168:745:1:o;5918:662::-;5972:5;6025:3;6018:4;6010:6;6006:17;6002:27;5992:55;;6043:1;6040;6033:12;5992:55;6079:6;6066:20;6105:4;6129:60;6145:43;6185:2;6145:43;:::i;6129:60::-;6223:15;;;6309:1;6305:10;;;;6293:23;;6289:32;;;6254:12;;;;6333:15;;;6330:35;;;6361:1;6358;6351:12;6330:35;6397:2;6389:6;6385:15;6409:142;6425:6;6420:3;6417:15;6409:142;;;6491:17;;6479:30;;6529:12;;;;6442;;6409:142;;6585:1349;6811:6;6819;6827;6835;6843;6851;6859;6912:3;6900:9;6891:7;6887:23;6883:33;6880:53;;;6929:1;6926;6919:12;6880:53;6952:59;7003:7;6992:9;6952:59;:::i;:::-;6942:69;;7062:3;7051:9;7047:19;7034:33;-1:-1:-1;;;;;7127:2:1;7119:6;7116:14;7113:34;;;7143:1;7140;7133:12;7113:34;7166:61;7219:7;7210:6;7199:9;7195:22;7166:61;:::i;:::-;7156:71;;7280:3;7269:9;7265:19;7252:33;7236:49;;7310:2;7300:8;7297:16;7294:36;;;7326:1;7323;7316:12;7294:36;7349:63;7404:7;7393:8;7382:9;7378:24;7349:63;:::i;:::-;7339:73;;7465:3;7454:9;7450:19;7437:33;7421:49;;7495:2;7485:8;7482:16;7479:36;;;7511:1;7508;7501:12;7479:36;7550:72;7614:7;7603:8;7592:9;7588:24;7550:72;:::i;:::-;7641:8;;-1:-1:-1;7524:98:1;-1:-1:-1;7729:3:1;7714:19;;7701:33;;-1:-1:-1;7746:16:1;;;7743:36;;;7775:1;7772;7765:12;8124:1000;8264:6;8272;8280;8288;8296;8304;8357:3;8345:9;8336:7;8332:23;8328:33;8325:53;;;8374:1;8371;8364:12;8325:53;8397:59;8448:7;8437:9;8397:59;:::i;:::-;8387:69;;8506:3;8495:9;8491:19;8478:33;8520:39;8553:5;8520:39;:::i;:::-;8578:5;-1:-1:-1;8634:3:1;8619:19;;8606:33;-1:-1:-1;;;;;8688:14:1;;;8685:34;;;8715:1;8712;8705:12;8685:34;8754:58;8804:7;8795:6;8784:9;8780:22;8754:58;:::i;:::-;8831:8;;-1:-1:-1;8728:84:1;-1:-1:-1;8919:3:1;8904:19;;8891:33;;-1:-1:-1;8936:16:1;;;8933:36;;;8965:1;8962;8955:12;8933:36;;9004:60;9056:7;9045:8;9034:9;9030:24;9004:60;:::i;:::-;8124:1000;;;;-1:-1:-1;8124:1000:1;;-1:-1:-1;8124:1000:1;;9083:8;;8124:1000;-1:-1:-1;;;8124:1000:1:o;10443:435::-;10496:3;10534:5;10528:12;10561:6;10556:3;10549:19;10587:4;10616:2;10611:3;10607:12;10600:19;;10653:2;10646:5;10642:14;10674:1;10684:169;10698:6;10695:1;10692:13;10684:169;;;10759:13;;10747:26;;10793:12;;;;10828:15;;;;10720:1;10713:9;10684:169;;;-1:-1:-1;10869:3:1;;10443:435;-1:-1:-1;;;;;10443:435:1:o;10883:465::-;11140:2;11129:9;11122:21;11103:4;11166:56;11218:2;11207:9;11203:18;11195:6;11166:56;:::i;:::-;11270:9;11262:6;11258:22;11253:2;11242:9;11238:18;11231:50;11298:44;11335:6;11327;11298:44;:::i;11535:159::-;11598:5;11643:3;11634:6;11629:3;11625:16;11621:26;11618:46;;;11660:1;11657;11650:12;11699:1482;11964:6;11972;11980;11988;11996;12004;12012;12020;12073:3;12061:9;12052:7;12048:23;12044:33;12041:53;;;12090:1;12087;12080:12;12041:53;12113:59;12164:7;12153:9;12113:59;:::i;:::-;12103:69;;12191:67;12250:7;12244:3;12233:9;12229:19;12191:67;:::i;:::-;12181:77;;12309:3;12298:9;12294:19;12281:33;-1:-1:-1;;;;;12374:2:1;12366:6;12363:14;12360:34;;;12390:1;12387;12380:12;12360:34;12413:61;12466:7;12457:6;12446:9;12442:22;12413:61;:::i;:::-;12403:71;;12527:3;12516:9;12512:19;12499:33;12483:49;;12557:2;12547:8;12544:16;12541:36;;;12573:1;12570;12563:12;12541:36;12596:63;12651:7;12640:8;12629:9;12625:24;12596:63;:::i;:::-;12586:73;;12712:3;12701:9;12697:19;12684:33;12668:49;;12742:2;12732:8;12729:16;12726:36;;;12758:1;12755;12748:12;12726:36;12797:72;12861:7;12850:8;12839:9;12835:24;12797:72;:::i;:::-;12888:8;;-1:-1:-1;12771:98:1;-1:-1:-1;12976:3:1;12961:19;;12948:33;;-1:-1:-1;12993:16:1;;;12990:36;;;13022:1;13019;13012:12;12990:36;;13061:60;13113:7;13102:8;13091:9;13087:24;13061:60;:::i;:::-;11699:1482;;;;-1:-1:-1;11699:1482:1;;-1:-1:-1;11699:1482:1;;;;;;13140:8;-1:-1:-1;;;11699:1482:1:o;13186:1133::-;13365:6;13373;13381;13389;13397;13405;13413;13466:3;13454:9;13445:7;13441:23;13437:33;13434:53;;;13483:1;13480;13473:12;13434:53;13506:59;13557:7;13546:9;13506:59;:::i;:::-;13496:69;;13584:67;13643:7;13637:3;13626:9;13622:19;13584:67;:::i;:::-;13574:77;;13701:3;13690:9;13686:19;13673:33;13715:39;13748:5;13715:39;:::i;:::-;13773:5;-1:-1:-1;13829:3:1;13814:19;;13801:33;-1:-1:-1;;;;;13883:14:1;;;13880:34;;;13910:1;13907;13900:12;13880:34;13949:58;13999:7;13990:6;13979:9;13975:22;13949:58;:::i;:::-;14026:8;;-1:-1:-1;13923:84:1;-1:-1:-1;14114:3:1;14099:19;;14086:33;;-1:-1:-1;14131:16:1;;;14128:36;;;14160:1;14157;14150:12;14324:391;14401:6;14409;14417;14470:2;14458:9;14449:7;14445:23;14441:32;14438:52;;;14486:1;14483;14476:12;14438:52;14525:9;14512:23;14544:39;14577:5;14544:39;:::i;:::-;14602:5;14654:2;14639:18;;14626:32;;-1:-1:-1;14705:2:1;14690:18;;;14677:32;;14324:391;-1:-1:-1;;;14324:391:1:o;14973:1531::-;15180:6;15188;15196;15204;15212;15220;15228;15236;15244;15252;15305:3;15293:9;15284:7;15280:23;15276:33;15273:53;;;15322:1;15319;15312:12;15273:53;15345:29;15364:9;15345:29;:::i;:::-;15335:39;;15421:2;15410:9;15406:18;15393:32;15383:42;;15476:2;15465:9;15461:18;15448:32;-1:-1:-1;;;;;15540:2:1;15532:6;15529:14;15526:34;;;15556:1;15553;15546:12;15526:34;15595:70;15657:7;15648:6;15637:9;15633:22;15595:70;:::i;:::-;15684:8;;-1:-1:-1;15569:96:1;-1:-1:-1;15772:2:1;15757:18;;15744:32;;-1:-1:-1;15788:16:1;;;15785:36;;;15817:1;15814;15807:12;15785:36;15856:72;15920:7;15909:8;15898:9;15894:24;15856:72;:::i;:::-;15947:8;;-1:-1:-1;15830:98:1;-1:-1:-1;16035:3:1;16020:19;;16007:33;;-1:-1:-1;16052:16:1;;;16049:36;;;16081:1;16078;16071:12;16049:36;16120:72;16184:7;16173:8;16162:9;16158:24;16120:72;:::i;:::-;16211:8;;-1:-1:-1;16094:98:1;-1:-1:-1;16299:3:1;16284:19;;16271:33;;-1:-1:-1;16316:16:1;;;16313:36;;;16345:1;16342;16335:12;16313:36;;16384:60;16436:7;16425:8;16414:9;16410:24;16384:60;:::i;:::-;16358:86;;16463:8;16453:18;;;16490:8;16480:18;;;14973:1531;;;;;;;;;;;;;:::o;16509:472::-;16586:6;16594;16602;16655:2;16643:9;16634:7;16630:23;16626:32;16623:52;;;16671:1;16668;16661:12;16623:52;16710:9;16697:23;16729:39;16762:5;16729:39;:::i;:::-;16787:5;-1:-1:-1;16844:2:1;16829:18;;16816:32;16857:41;16816:32;16857:41;:::i;:::-;16509:472;;16917:7;;-1:-1:-1;;;16971:2:1;16956:18;;;;16943:32;;16509:472::o;16986:255::-;17045:6;17098:2;17086:9;17077:7;17073:23;17069:32;17066:52;;;17114:1;17111;17104:12;17066:52;17153:9;17140:23;17172:39;17205:5;17172:39;:::i;17246:1232::-;17413:6;17421;17429;17437;17445;17453;17461;17514:3;17502:9;17493:7;17489:23;17485:33;17482:53;;;17531:1;17528;17521:12;17482:53;17570:9;17557:23;17589:39;17622:5;17589:39;:::i;:::-;17647:5;-1:-1:-1;17703:2:1;17688:18;;17675:32;-1:-1:-1;;;;;17756:14:1;;;17753:34;;;17783:1;17780;17773:12;17753:34;17822:70;17884:7;17875:6;17864:9;17860:22;17822:70;:::i;:::-;17911:8;;-1:-1:-1;17796:96:1;-1:-1:-1;17999:2:1;17984:18;;17971:32;;-1:-1:-1;18015:16:1;;;18012:36;;;18044:1;18041;18034:12;18012:36;18083:72;18147:7;18136:8;18125:9;18121:24;18083:72;:::i;:::-;18174:8;;-1:-1:-1;18057:98:1;-1:-1:-1;18262:2:1;18247:18;;18234:32;;-1:-1:-1;18278:16:1;;;18275:36;;;18307:1;18304;18297:12;18275:36;;18346:72;18410:7;18399:8;18388:9;18384:24;18346:72;:::i;18693:266::-;18781:6;18776:3;18769:19;18833:6;18826:5;18819:4;18814:3;18810:14;18797:43;-1:-1:-1;18885:1:1;18860:16;;;18878:4;18856:27;;;18849:38;;;;18941:2;18920:15;;;-1:-1:-1;;18916:29:1;18907:39;;;18903:50;;18693:266::o;18964:412::-;19159:25;;;-1:-1:-1;;;;;19220:32:1;;19215:2;19200:18;;19193:60;19289:2;19284;19269:18;;19262:30;;;-1:-1:-1;;19309:61:1;;19351:18;;19343:6;19335;19309:61;:::i;:::-;19301:69;18964:412;-1:-1:-1;;;;;;18964:412:1:o;19381:567::-;19668:6;19661:14;19654:22;19643:9;19636:41;19727:6;19720:14;19713:22;19708:2;19697:9;19693:18;19686:50;19772:6;19767:2;19756:9;19752:18;19745:34;19815:6;19810:2;19799:9;19795:18;19788:34;19859:3;19853;19842:9;19838:19;19831:32;19617:4;19880:62;19937:3;19926:9;19922:19;19914:6;19906;19880:62;:::i;:::-;19872:70;19381:567;-1:-1:-1;;;;;;;;19381:567:1:o;19953:127::-;20014:10;20009:3;20005:20;20002:1;19995:31;20045:4;20042:1;20035:15;20069:4;20066:1;20059:15;20085:118;20171:5;20164:13;20157:21;20150:5;20147:32;20137:60;;20193:1;20190;20183:12;20208:241;20264:6;20317:2;20305:9;20296:7;20292:23;20288:32;20285:52;;;20333:1;20330;20323:12;20285:52;20372:9;20359:23;20391:28;20413:5;20391:28;:::i;20454:127::-;20515:10;20510:3;20506:20;20503:1;20496:31;20546:4;20543:1;20536:15;20570:4;20567:1;20560:15;20586:135;20625:3;20646:17;;;20643:43;;20666:18;;:::i;:::-;-1:-1:-1;20713:1:1;20702:13;;20586:135::o;21142:1067::-;21249:6;21244:3;21237:19;21219:3;21275:4;21316:2;21311:3;21307:12;21341:11;21368;21361:18;;21418:6;21415:1;21411:14;21404:5;21400:26;21388:38;;21449:5;21472:1;21482:701;21496:6;21493:1;21490:13;21482:701;;;21567:5;21561:4;21557:16;21552:3;21545:29;21626:6;21613:20;21716:2;21712:7;21704:5;21688:14;21684:26;21680:40;21660:18;21656:65;21646:93;;21735:1;21732;21725:12;21646:93;21767:30;;21875:16;;;;21826:21;-1:-1:-1;;;;;21907:32:1;;21904:52;;;21952:1;21949;21942:12;21904:52;22005:8;21989:14;21985:29;21976:7;21972:43;21969:63;;;22028:1;22025;22018:12;21969:63;22053:50;22098:4;22088:8;22079:7;22053:50;:::i;:::-;22161:12;;;;22045:58;-1:-1:-1;;;22126:15:1;;;;21518:1;21511:9;21482:701;;;-1:-1:-1;22199:4:1;;21142:1067;-1:-1:-1;;;;;;;21142:1067:1:o;22214:1418::-;22648:4;22696:3;22685:9;22681:19;22736:1;22732;22727:3;22723:11;22719:19;22777:2;22769:6;22765:15;22754:9;22747:34;22800:2;22838:6;22833:2;22822:9;22818:18;22811:34;22895:6;22888:14;22881:22;22876:2;22865:9;22861:18;22854:50;22940:6;22935:2;22924:9;22920:18;22913:34;22984:3;22978;22967:9;22963:19;22956:32;23008:6;23043;23037:13;23074:6;23066;23059:22;23112:3;23101:9;23097:19;23090:26;;23151:2;23143:6;23139:15;23125:29;;23172:1;23182:178;23196:6;23193:1;23190:13;23182:178;;;23261:13;;23257:22;;23245:35;;23335:15;;;;23300:12;;;;23218:1;23211:9;23182:178;;;23186:3;;23406:9;23401:3;23397:19;23391:3;23380:9;23376:19;23369:48;23440:41;23477:3;23469:6;23440:41;:::i;:::-;23426:55;;;;;23530:9;23522:6;23518:22;23512:3;23501:9;23497:19;23490:51;23558:68;23619:6;23611;23603;23558:68;:::i;:::-;23550:76;22214:1418;-1:-1:-1;;;;;;;;;;;22214:1418:1:o;24193:669::-;-1:-1:-1;;;;;24522:15:1;;;24504:34;;24569:2;24554:18;;24547:34;;;24624:14;;24617:22;24612:2;24597:18;;24590:50;24671:2;24656:18;;24649:34;;;24720:15;;24714:3;24699:19;;24692:44;24773:3;24484;24752:19;;24745:32;;;24447:4;;24794:62;;24836:19;;24828:6;24820;24794:62;:::i;:::-;24786:70;24193:669;-1:-1:-1;;;;;;;;;24193:669:1:o;24867:175::-;24904:3;24948:4;24941:5;24937:16;24977:4;24968:7;24965:17;24962:43;;24985:18;;:::i;:::-;25034:1;25021:15;;24867:175;-1:-1:-1;;24867:175:1:o;25047:1384::-;25484:25;;;25471:3;25528:2;25546:18;;;25539:31;;;25456:19;;;25605:22;;;25423:4;;25685:6;;25658:3;25643:19;;25423:4;25719:285;25733:6;25730:1;25727:13;25719:285;;;25808:6;25795:20;25828:39;25861:5;25828:39;:::i;:::-;-1:-1:-1;;;;;25892:31:1;25880:44;;25979:15;;;;25944:12;;;;25920:1;25748:9;25719:285;;;-1:-1:-1;26040:19:1;;;26035:2;26020:18;;26013:47;26069:19;;;-1:-1:-1;;;;;26100:31:1;;26097:51;;;26144:1;26141;26134:12;26097:51;26178:6;26175:1;26171:14;26157:28;;26229:6;26221;26216:2;26211:3;26207:12;26194:42;26255:16;;;26311:18;;;26307:27;;26302:2;26287:18;;26280:55;26255:16;26352:73;26413:11;;;26405:6;26397;26352:73;:::i;27141:259::-;27211:6;27264:2;27252:9;27243:7;27239:23;27235:32;27232:52;;;27280:1;27277;27270:12;27232:52;27312:9;27306:16;27331:39;27364:5;27331:39;:::i;27980:269::-;28037:6;28090:2;28078:9;28069:7;28065:23;28061:32;28058:52;;;28106:1;28103;28096:12;28058:52;28145:9;28132:23;28195:4;28188:5;28184:16;28177:5;28174:27;28164:55;;28215:1;28212;28205:12;28929:151;29019:4;29012:12;;;28998;;;28994:31;;29037:14;;29034:40;;;29054:18;;:::i;29085:128::-;29152:9;;;29173:11;;;29170:37;;;29187:18;;:::i;29218:168::-;29291:9;;;29322;;29339:15;;;29333:22;;29319:37;29309:71;;29360:18;;:::i;29391:217::-;29431:1;29457;29447:132;;29501:10;29496:3;29492:20;29489:1;29482:31;29536:4;29533:1;29526:15;29564:4;29561:1;29554:15;29447:132;-1:-1:-1;29593:9:1;;29391:217::o;29613:125::-;29678:9;;;29699:10;;;29696:36;;;29712:18;;:::i;29743:250::-;29828:1;29838:113;29852:6;29849:1;29846:13;29838:113;;;29928:11;;;29922:18;29909:11;;;29902:39;29874:2;29867:10;29838:113;;;-1:-1:-1;;29985:1:1;29967:16;;29960:27;29743:250::o;29998:812::-;30409:25;30404:3;30397:38;30379:3;30464:6;30458:13;30480:75;30548:6;30543:2;30538:3;30534:12;30527:4;30519:6;30515:17;30480:75;:::i;:::-;-1:-1:-1;;;30614:2:1;30574:16;;;30606:11;;;30599:40;30664:13;;30686:76;30664:13;30748:2;30740:11;;30733:4;30721:17;;30686:76;:::i;:::-;30782:17;30801:2;30778:26;;29998:812;-1:-1:-1;;;;29998:812:1:o;30815:396::-;30964:2;30953:9;30946:21;30927:4;30996:6;30990:13;31039:6;31034:2;31023:9;31019:18;31012:34;31055:79;31127:6;31122:2;31111:9;31107:18;31102:2;31094:6;31090:15;31055:79;:::i;:::-;31195:2;31174:15;-1:-1:-1;;31170:29:1;31155:45;;;;31202:2;31151:54;;30815:396;-1:-1:-1;;30815:396:1:o;31216:184::-;31286:6;31339:2;31327:9;31318:7;31314:23;31310:32;31307:52;;;31355:1;31352;31345:12;31307:52;-1:-1:-1;31378:16:1;;31216:184;-1:-1:-1;31216:184:1:o;31684:287::-;31813:3;31851:6;31845:13;31867:66;31926:6;31921:3;31914:4;31906:6;31902:17;31867:66;:::i;:::-;31949:16;;;;;31684:287;-1:-1:-1;;31684:287:1:o;31976:245::-;32043:6;32096:2;32084:9;32075:7;32071:23;32067:32;32064:52;;;32112:1;32109;32102:12;32064:52;32144:9;32138:16;32163:28;32185:5;32163:28;:::i;32986:136::-;33025:3;33053:5;33043:39;;33062:18;;:::i;:::-;-1:-1:-1;;;33098:18:1;;32986:136::o
Swarm Source
ipfs://17304cfbcd8841f997b2ab409931d83ed70b197d553f9c553de8a607a50d4edb
Net Worth in USD
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.