Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
AssetForwarder
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity)
/** *Submitted for verification at basescan.org on 2024-01-05 */ // SPDX-License-Identifier: MIT pragma solidity 0.8.18; // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } /** * @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()); } } // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) /** * @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; } // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) /** * @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); } } } // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) /** * @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); } } } /** * @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)); } } // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) /** * @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); } /** * @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; } } /** * @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()); } } } // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) /** * @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); } // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) /** * @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); } // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) /** * @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); } } } /** * @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)); } } /** * @title A contract that provides modifiers to prevent reentrancy to state-changing and view-only methods. This contract * is inspired by https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/ReentrancyGuard.sol * and https://github.com/balancer-labs/balancer-core/blob/master/contracts/BPool.sol. * @dev The reason why we use this local contract instead of importing from uma/contracts is because of the addition * of the internal method `functionCallStackOriginatesFromOutsideThisContract` which doesn't exist in the one exported * by uma/contracts. */ contract ReentrancyGuard { bool internal _notEntered; constructor() { // Storing an initial 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. _notEntered = true; } /** * @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 state modification. */ modifier nonReentrant() { _preEntranceCheck(); _preEntranceSet(); _; _postEntranceReset(); } /** * @dev Designed to prevent a view-only method from being re-entered during a call to a nonReentrant() state-changing method. */ modifier nonReentrantView() { _preEntranceCheck(); _; } /** * @dev Returns true if the contract is currently in a non-entered state, meaning that the origination of the call * came from outside the contract. This is relevant with fallback/receive methods to see if the call came from ETH * being dropped onto the contract externally or due to ETH dropped on the the contract from within a method in this * contract, such as unwrapping WETH to ETH within the contract. */ function functionCallStackOriginatesFromOutsideThisContract() internal view returns (bool) { return _notEntered; } // Internal methods are used to avoid copying the require statement's bytecode to every nonReentrant() method. // On entry into a function, _preEntranceCheck() should always be called to check if the function is being // re-entered. Then, if the function modifies state, it should call _postEntranceSet(), perform its logic, and // then call _postEntranceReset(). // View-only methods can simply call _preEntranceCheck() to make sure that it is not being re-entered. function _preEntranceCheck() internal view { // On the first call to nonReentrant, _notEntered will be true require(_notEntered, "ReentrancyGuard: reentrant call"); } function _preEntranceSet() internal { // Any calls to nonReentrant after this point will fail _notEntered = false; } function _postEntranceReset() internal { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _notEntered = true; } } /// @title Interface for handler contracts that support deposits and deposit executions. /// @author Router Protocol. interface IAssetForwarder { event FundsDeposited( uint256 partnerId, uint256 amount, bytes32 destChainIdBytes, uint256 destAmount, uint256 depositId, address srcToken, address depositor, bytes recipient, bytes destToken ); event iUSDCDeposited( uint256 partnerId, uint256 amount, bytes32 destChainIdBytes, uint256 usdcNonce, address srcToken, bytes32 recipient, address depositor ); event FundsDepositedWithMessage( uint256 partnerId, uint256 amount, bytes32 destChainIdBytes, uint256 destAmount, uint256 depositId, address srcToken, bytes recipient, address depositor, bytes destToken, bytes message ); event FundsPaid(bytes32 messageHash, address forwarder, uint256 nonce); event DepositInfoUpdate( address srcToken, uint256 feeAmount, uint256 depositId, uint256 eventNonce, bool initiatewithdrawal, address depositor ); event FundsPaidWithMessage( bytes32 messageHash, address forwarder, uint256 nonce, bool execFlag, bytes execData ); struct DestDetails { uint32 domainId; uint256 fee; bool isSet; } struct RelayData { uint256 amount; bytes32 srcChainId; uint256 depositId; address destToken; address recipient; } struct RelayDataMessage { uint256 amount; bytes32 srcChainId; uint256 depositId; address destToken; address recipient; bytes message; } struct DepositData { uint256 partnerId; uint256 amount; uint256 destAmount; address srcToken; address refundRecipient; bytes32 destChainIdBytes; } function iDepositUSDC( uint256 partnerId, bytes32 destChainIdBytes, bytes32 recipient, uint256 amount ) external payable; function iDeposit( DepositData memory depositData, bytes memory destToken, bytes memory recipient ) external payable; function iDepositInfoUpdate( address srcToken, uint256 feeAmount, uint256 depositId, bool initiatewithdrawal ) external payable; function iDepositMessage( DepositData memory depositData, bytes memory destToken, bytes memory recipient, bytes memory message ) external payable; function iRelay(RelayData memory relayData) external payable; function iRelayMessage(RelayDataMessage memory relayData) external payable; } interface IWETH { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; function transferFrom( address src, address dst, uint256 wad ) external returns (bool); function approve(address guy, uint256 wad) external returns (bool); } interface ITokenMessenger { function depositForBurn( uint256 _amount, uint32 _destinationDomain, bytes32 _mintRecipient, address _burnToken ) external returns (uint64); function depositForBurnWithCaller( uint256 _amount, uint32 _destinationDomain, bytes32 _mintRecipient, address _burnToken, bytes32 _destinationCaller ) external returns (uint64); function replaceDepositForBurn( bytes memory originalMessage, bytes calldata originalAttestation, bytes32 _destCaller, bytes32 _mintRecipient ) external; } /// @title Handles ERC20 deposits and deposit executions. /// @author Router Protocol. /// @notice This contract is intended to be used with the Bridge contract. interface IMessageHandler { function handleMessage( address tokenSent, uint256 amount, bytes memory message ) external; } /** * @title MultiCaller * @notice Logic is 100% copied from "https://github.com/Uniswap/v3-periphery/blob/main/contracts/base/Multicall.sol" just version upgraded * please check if this can create conflict with handling msg.value */ contract MultiCaller { function multicall(bytes[] calldata data) external returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); if (!success) { // Next 5 lines from https://ethereum.stackexchange.com/a/83577 if (result.length < 68) revert(); assembly { result := add(result, 0x04) } revert(abi.decode(result, (string))); } results[i] = result; } } } contract AssetForwarder is AccessControl, ReentrancyGuard, Pausable, IAssetForwarder, MultiCaller { using SafeERC20 for IERC20; IWETH public immutable wrappedNativeToken; bytes32 public routerMiddlewareBase; address public gatewayContract; // address of USDC address public usdc; // USDC token messenger ITokenMessenger public tokenMessenger; uint256 public depositNonce; mapping(bytes32 => DestDetails) public destDetails; uint256 public constant MAX_TRANSFER_SIZE = 1e36; bytes32 public constant RESOURCE_SETTER = keccak256("RESOURCE_SETTER"); bytes32 public constant PAUSER = keccak256("PAUSER"); mapping(bytes32 => bool) public executeRecord; uint256 public MIN_GAS_THRESHHOLD; uint256 public pauseStakeAmountMin; uint256 public pauseStakeAmountMax; uint256 public totalStakedAmount; bool public isCommunityPauseEnabled = true; address private constant NATIVE_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; event CommunityPaused(address indexed pauser, uint256 stakedAmount); error MessageAlreadyExecuted(); error InvalidGateway(); error InvalidRequestSender(); error InvalidRefundData(); error InvalidAmount(); error AmountTooLarge(); error MessageExcecutionFailedWithLowGas(); error InvalidFee(); constructor( address _wrappedNativeTokenAddress, address _gatewayContract, address _usdcAddress, address _tokenMessenger, bytes memory _routerMiddlewareBase, uint _minGasThreshhold ) { wrappedNativeToken = IWETH(_wrappedNativeTokenAddress); tokenMessenger = ITokenMessenger(_tokenMessenger); gatewayContract = _gatewayContract; usdc = _usdcAddress; routerMiddlewareBase = keccak256(_routerMiddlewareBase); MIN_GAS_THRESHHOLD = _minGasThreshhold; _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(RESOURCE_SETTER, msg.sender); _grantRole(PAUSER, msg.sender); } function update( uint index, address _gatewayContract, bytes calldata _routerMiddlewareBase, uint256 minPauseStakeAmount, uint256 maxPauseStakeAmount ) public onlyRole(RESOURCE_SETTER) { if (index == 1) { gatewayContract = _gatewayContract; } else if (index == 2) { routerMiddlewareBase = keccak256(_routerMiddlewareBase); } else if (index == 3) { require( minPauseStakeAmount <= maxPauseStakeAmount, "minPauseStakeAmount must be less than or equal to maxPauseStakeAmount" ); pauseStakeAmountMin = minPauseStakeAmount; pauseStakeAmountMax = maxPauseStakeAmount; } } /// @notice Function used to set usdc token messenger address /// @notice Only RESOURCE_SETTER can call this function /// @param _tokenMessenger address of token messenger function updateTokenMessenger( address _tokenMessenger ) external onlyRole(RESOURCE_SETTER) { tokenMessenger = ITokenMessenger(_tokenMessenger); } function pause() external onlyRole(PAUSER) whenNotPaused { _pause(); } /// @notice Unpauses deposits on the handler. /// @notice Only callable by an address that currently has the PAUSER role. function unpause() external onlyRole(PAUSER) whenPaused { _unpause(); } function isNative(address token) internal pure returns (bool) { return token == NATIVE_ADDRESS; } function setDestDetails( bytes32[] memory _destChainIdBytes, DestDetails[] memory _destDetails ) public onlyRole(RESOURCE_SETTER) { require( _destChainIdBytes.length == _destDetails.length, "invalid length" ); for (uint256 idx = 0; idx < _destDetails.length; idx++) { destDetails[_destChainIdBytes[idx]] = _destDetails[idx]; } } function iDepositUSDC( uint256 partnerId, bytes32 destChainIdBytes, bytes32 recipient, uint256 amount ) external payable nonReentrant whenNotPaused { require( destDetails[destChainIdBytes].isSet && usdc != address(0), "usdc not supported either on src on dst chain" ); if (msg.value != destDetails[destChainIdBytes].fee) revert InvalidFee(); if (amount > MAX_TRANSFER_SIZE) revert AmountTooLarge(); IERC20(usdc).safeTransferFrom(msg.sender, address(this), amount); IERC20(usdc).safeIncreaseAllowance(address(tokenMessenger), amount); uint64 nonce = tokenMessenger.depositForBurn( amount, destDetails[destChainIdBytes].domainId, recipient, usdc ); // it will emit event DepositForBurn, returns nonce emit iUSDCDeposited( partnerId, amount, destChainIdBytes, nonce, usdc, recipient, msg.sender ); } // TODO: Docs Update function iDeposit( DepositData memory depositData, bytes memory destToken, bytes memory recipient ) external payable nonReentrant whenNotPaused { if (depositData.amount > MAX_TRANSFER_SIZE) revert AmountTooLarge(); if (isNative(depositData.srcToken)) { if (depositData.amount != msg.value) revert InvalidAmount(); wrappedNativeToken.deposit{value: msg.value}(); // only amount should be deposited depositData.srcToken = address(wrappedNativeToken); } else { IERC20(depositData.srcToken).safeTransferFrom( msg.sender, address(this), depositData.amount ); } emit FundsDeposited( depositData.partnerId, depositData.amount, depositData.destChainIdBytes, depositData.destAmount, ++depositNonce, depositData.srcToken, depositData.refundRecipient, recipient, destToken ); } function iDepositInfoUpdate( address srcToken, uint256 feeAmount, uint256 depositId, bool initiatewithdrawal ) external payable nonReentrant whenNotPaused { if (initiatewithdrawal) { assert(msg.value == 0); emit DepositInfoUpdate( srcToken, 0, depositId, ++depositNonce, true, msg.sender ); return; } if (feeAmount > MAX_TRANSFER_SIZE) revert AmountTooLarge(); if (isNative(srcToken)) { if (feeAmount != msg.value) revert InvalidAmount(); wrappedNativeToken.deposit{value: msg.value}(); // only amount should be deposited srcToken = address(wrappedNativeToken); } else { IERC20(srcToken).safeTransferFrom( msg.sender, address(this), feeAmount ); } emit DepositInfoUpdate( srcToken, feeAmount, depositId, ++depositNonce, false, msg.sender ); } function iDepositMessage( DepositData memory depositData, bytes memory destToken, bytes memory recipient, bytes memory message ) external payable nonReentrant whenNotPaused { if (depositData.amount > MAX_TRANSFER_SIZE) revert AmountTooLarge(); if (isNative(depositData.srcToken)) { if (depositData.amount != msg.value) revert InvalidAmount(); wrappedNativeToken.deposit{value: msg.value}(); // only amount should be deposited depositData.srcToken = address(wrappedNativeToken); } else { IERC20(depositData.srcToken).safeTransferFrom( msg.sender, address(this), depositData.amount ); } emit FundsDepositedWithMessage( depositData.partnerId, depositData.amount, depositData.destChainIdBytes, depositData.destAmount, ++depositNonce, depositData.srcToken, recipient, depositData.refundRecipient, destToken, message ); } function iRelay( RelayData memory relayData ) external payable nonReentrant whenNotPaused { // Check is message is already executed if (relayData.amount > MAX_TRANSFER_SIZE) revert AmountTooLarge(); bytes32 messageHash = keccak256( abi.encode( relayData.amount, relayData.srcChainId, relayData.depositId, relayData.destToken, relayData.recipient, address(this) ) ); if (executeRecord[messageHash]) revert MessageAlreadyExecuted(); executeRecord[messageHash] = true; if (isNative(relayData.destToken)) { if (relayData.amount != msg.value) revert InvalidAmount(); //slither-disable-next-line arbitrary-send-eth payable(relayData.recipient).transfer(relayData.amount); } else { IERC20(relayData.destToken).safeTransferFrom( msg.sender, relayData.recipient, relayData.amount ); } emit FundsPaid(messageHash, msg.sender, ++depositNonce); } function iRelayMessage( RelayDataMessage memory relayData ) external payable nonReentrant whenNotPaused { if (relayData.amount > MAX_TRANSFER_SIZE) revert AmountTooLarge(); // Check is message is already executed bytes32 messageHash = keccak256( abi.encode( relayData.amount, relayData.srcChainId, relayData.depositId, relayData.destToken, relayData.recipient, address(this), relayData.message ) ); if (executeRecord[messageHash]) revert MessageAlreadyExecuted(); executeRecord[messageHash] = true; if (isNative(relayData.destToken)) { if (relayData.amount != msg.value) revert InvalidAmount(); payable(relayData.recipient).transfer(relayData.amount); } else { IERC20(relayData.destToken).safeTransferFrom( msg.sender, relayData.recipient, relayData.amount ); } bytes memory execData; bool execFlag; if (isContract(relayData.recipient) && relayData.message.length > 0) { (execFlag, execData) = relayData.recipient.call( abi.encodeWithSelector( IMessageHandler.handleMessage.selector, relayData.destToken, relayData.amount, relayData.message ) ); if (!execFlag && gasleft() < MIN_GAS_THRESHHOLD) revert MessageExcecutionFailedWithLowGas(); } emit FundsPaidWithMessage( messageHash, msg.sender, ++depositNonce, execFlag, execData ); } function iReceive( string calldata requestSender, bytes memory packet, string calldata ) external returns (bytes memory) { if (msg.sender != address(gatewayContract)) revert InvalidGateway(); if (routerMiddlewareBase != keccak256(bytes(requestSender))) revert InvalidRequestSender(); ( address recipient, address[] memory tokens, uint256[] memory amounts ) = abi.decode(packet, (address, address[], uint256[])); uint256 count = tokens.length; if (count != amounts.length) revert InvalidRefundData(); for (uint256 i = 0; i < count; i++) { if (!isNative(tokens[i])) IERC20(tokens[i]).safeTransfer(recipient, amounts[i]); //slither-disable-next-line arbitrary-send-eth else payable(recipient).transfer(amounts[i]); } return ""; } function isContract(address addr) internal view returns (bool) { uint256 size; assembly { size := extcodesize(addr) } return size > 0; } // TODO: do we need this? We should not have it like this as this will // not be decentralized. We should have withdraw fees instead. function rescue( address token ) external onlyRole(DEFAULT_ADMIN_ROLE) nonReentrant { if (isNative(token)) { payable(msg.sender).transfer(address(this).balance); } else { IERC20(token).safeTransfer( msg.sender, IERC20(token).balanceOf(address(this)) ); } } function toggleCommunityPause() external onlyRole(DEFAULT_ADMIN_ROLE) { isCommunityPauseEnabled = !isCommunityPauseEnabled; } function communityPause() external payable whenNotPaused { // Check if msg.value is within the allowed range require(isCommunityPauseEnabled, "Community pause is disabled"); require( pauseStakeAmountMin != 0 && pauseStakeAmountMax != 0, "Set Stake Amount Range" ); require( msg.value >= pauseStakeAmountMin && msg.value <= pauseStakeAmountMax, "Stake amount out of range" ); uint256 newTotalStakedAmount = totalStakedAmount + msg.value; totalStakedAmount = newTotalStakedAmount; _pause(); emit CommunityPaused(msg.sender, msg.value); } function withdrawStakeAmount() external onlyRole(DEFAULT_ADMIN_ROLE) { require( address(this).balance >= totalStakedAmount, "Insufficient funds" ); uint256 withdrawalAmount = totalStakedAmount; totalStakedAmount = 0; payable(msg.sender).transfer(withdrawalAmount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_wrappedNativeTokenAddress","type":"address"},{"internalType":"address","name":"_gatewayContract","type":"address"},{"internalType":"address","name":"_usdcAddress","type":"address"},{"internalType":"address","name":"_tokenMessenger","type":"address"},{"internalType":"bytes","name":"_routerMiddlewareBase","type":"bytes"},{"internalType":"uint256","name":"_minGasThreshhold","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AmountTooLarge","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidFee","type":"error"},{"inputs":[],"name":"InvalidGateway","type":"error"},{"inputs":[],"name":"InvalidRefundData","type":"error"},{"inputs":[],"name":"InvalidRequestSender","type":"error"},{"inputs":[],"name":"MessageAlreadyExecuted","type":"error"},{"inputs":[],"name":"MessageExcecutionFailedWithLowGas","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pauser","type":"address"},{"indexed":false,"internalType":"uint256","name":"stakedAmount","type":"uint256"}],"name":"CommunityPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"srcToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"eventNonce","type":"uint256"},{"indexed":false,"internalType":"bool","name":"initiatewithdrawal","type":"bool"},{"indexed":false,"internalType":"address","name":"depositor","type":"address"}],"name":"DepositInfoUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"partnerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"destAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositId","type":"uint256"},{"indexed":false,"internalType":"address","name":"srcToken","type":"address"},{"indexed":false,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"bytes","name":"recipient","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"destToken","type":"bytes"}],"name":"FundsDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"partnerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"destAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositId","type":"uint256"},{"indexed":false,"internalType":"address","name":"srcToken","type":"address"},{"indexed":false,"internalType":"bytes","name":"recipient","type":"bytes"},{"indexed":false,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"bytes","name":"destToken","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"FundsDepositedWithMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"forwarder","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"FundsPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"forwarder","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"bool","name":"execFlag","type":"bool"},{"indexed":false,"internalType":"bytes","name":"execData","type":"bytes"}],"name":"FundsPaidWithMessage","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"partnerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"usdcNonce","type":"uint256"},{"indexed":false,"internalType":"address","name":"srcToken","type":"address"},{"indexed":false,"internalType":"bytes32","name":"recipient","type":"bytes32"},{"indexed":false,"internalType":"address","name":"depositor","type":"address"}],"name":"iUSDCDeposited","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TRANSFER_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_GAS_THRESHHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESOURCE_SETTER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"communityPause","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"depositNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"destDetails","outputs":[{"internalType":"uint32","name":"domainId","type":"uint32"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bool","name":"isSet","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"executeRecord","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gatewayContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"partnerId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"refundRecipient","type":"address"},{"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"}],"internalType":"struct IAssetForwarder.DepositData","name":"depositData","type":"tuple"},{"internalType":"bytes","name":"destToken","type":"bytes"},{"internalType":"bytes","name":"recipient","type":"bytes"}],"name":"iDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"depositId","type":"uint256"},{"internalType":"bool","name":"initiatewithdrawal","type":"bool"}],"name":"iDepositInfoUpdate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"partnerId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"refundRecipient","type":"address"},{"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"}],"internalType":"struct IAssetForwarder.DepositData","name":"depositData","type":"tuple"},{"internalType":"bytes","name":"destToken","type":"bytes"},{"internalType":"bytes","name":"recipient","type":"bytes"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"iDepositMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"partnerId","type":"uint256"},{"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"iDepositUSDC","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"requestSender","type":"string"},{"internalType":"bytes","name":"packet","type":"bytes"},{"internalType":"string","name":"","type":"string"}],"name":"iReceive","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"srcChainId","type":"bytes32"},{"internalType":"uint256","name":"depositId","type":"uint256"},{"internalType":"address","name":"destToken","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"internalType":"struct IAssetForwarder.RelayData","name":"relayData","type":"tuple"}],"name":"iRelay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"srcChainId","type":"bytes32"},{"internalType":"uint256","name":"depositId","type":"uint256"},{"internalType":"address","name":"destToken","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct IAssetForwarder.RelayDataMessage","name":"relayData","type":"tuple"}],"name":"iRelayMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"isCommunityPauseEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauseStakeAmountMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseStakeAmountMin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"routerMiddlewareBase","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_destChainIdBytes","type":"bytes32[]"},{"components":[{"internalType":"uint32","name":"domainId","type":"uint32"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bool","name":"isSet","type":"bool"}],"internalType":"struct IAssetForwarder.DestDetails[]","name":"_destDetails","type":"tuple[]"}],"name":"setDestDetails","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleCommunityPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenMessenger","outputs":[{"internalType":"contract ITokenMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"_gatewayContract","type":"address"},{"internalType":"bytes","name":"_routerMiddlewareBase","type":"bytes"},{"internalType":"uint256","name":"minPauseStakeAmount","type":"uint256"},{"internalType":"uint256","name":"maxPauseStakeAmount","type":"uint256"}],"name":"update","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenMessenger","type":"address"}],"name":"updateTokenMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawStakeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrappedNativeToken","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a0604052600d805460ff191660011790553480156200001e57600080fd5b50604051620048aa380380620048aa8339810160408190526200004191620001e3565b6001805461ffff1916811790556001600160a01b03868116608052600580546001600160a01b03199081168684161790915560038054821688841617905560048054909116918616919091179055815160208301206002556009819055620000ab6000336200010f565b620000d77f8b9e7a9f25b0aca3f51c01b8fee30790fb16f4d4deded8385ae6643d054bb078336200010f565b620001037f539440820030c4994db4e31b6b800deafd503688728f932addfe7a410515c14c336200010f565b5050505050506200030b565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16620001ac576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556200016b3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b80516001600160a01b0381168114620001c857600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c08789031215620001fd57600080fd5b6200020887620001b0565b9550602062000219818901620001b0565b95506200022960408901620001b0565b94506200023960608901620001b0565b60808901519094506001600160401b03808211156200025757600080fd5b818a0191508a601f8301126200026c57600080fd5b815181811115620002815762000281620001cd565b604051601f8201601f19908116603f01168101908382118183101715620002ac57620002ac620001cd565b816040528281528d86848701011115620002c557600080fd5b600093505b82841015620002e95784840186015181850187015292850192620002ca565b600086848301015280975050505050505060a087015190509295509295509295565b608051614559620003516000396000818161034701528181610b8801528181610c1c0152818161248b0152818161250c0152818161272901526127bd01526145596000f3fe6080604052600436106102c65760003560e01c806378e0f9bd11610179578063c44e947e116100d6578063de35f5cb1161008a578063f452ed4d11610064578063f452ed4d14610816578063f627df9414610829578063fd5ad37c1461083e57600080fd5b8063de35f5cb146107bd578063eb0cde1d146107d3578063f215f1481461080057600080fd5b8063d9dc8694116100bb578063d9dc869414610732578063db618e2a14610766578063ddd224f11461079a57600080fd5b8063c44e947e146106fc578063d547741f1461071257600080fd5b8063981a8a021161012d578063ac9650d811610112578063ac9650d8146106a6578063ad7c17ee146106d3578063b19941a9146106e657600080fd5b8063981a8a0214610627578063a217fddf1461069157600080fd5b80638456cb591161015e5780638456cb59146105ac5780638a27fecb146105c157806391d14854146105d657600080fd5b806378e0f9bd1461056c578063839006f21461058c57600080fd5b80633f4ba83a116102275780635ac62700116101db57806364778c1f116101c057806364778c1f1461053e5780636696821b146105515780636fb003da1461055957600080fd5b80635ac62700146105015780635c975abb1461052157600080fd5b8063461178301161020c57806346117830146104a85780634b7b9476146104d5578063567e98f9146104eb57600080fd5b80633f4ba83a146104795780634463182f1461048e57600080fd5b8063248a9ca31161027e57806336568abe1161026357806336568abe146104195780633e28c7d2146104395780633e413bee1461044c57600080fd5b8063248a9ca3146103bb5780632f2ff15d146103f957600080fd5b80630421caf0116102af5780630421caf01461032257806317fcb39b146103355780631aa6485a1461038e57600080fd5b80630171958a146102cb57806301ffc9a7146102ed575b600080fd5b3480156102d757600080fd5b506102eb6102e63660046136f4565b61086e565b005b3480156102f957600080fd5b5061030d6103083660046137ad565b6109ea565b60405190151581526020015b60405180910390f35b6102eb610330366004613914565b610a83565b34801561034157600080fd5b506103697f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b34801561039a57600080fd5b506103ae6103a93660046139f9565b610d20565b6040516103199190613afc565b3480156103c757600080fd5b506103eb6103d6366004613b0f565b60009081526020819052604090206001015490565b604051908152602001610319565b34801561040557600080fd5b506102eb610414366004613b28565b610f73565b34801561042557600080fd5b506102eb610434366004613b28565b610f9d565b6102eb610447366004613b58565b611050565b34801561045857600080fd5b506004546103699073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b506102eb6113a7565b34801561049a57600080fd5b50600d5461030d9060ff1681565b3480156104b457600080fd5b506005546103699073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e157600080fd5b506103eb60095481565b3480156104f757600080fd5b506103eb600c5481565b34801561050d57600080fd5b506102eb61051c366004613b8a565b6113e4565b34801561052d57600080fd5b50600154610100900460ff1661030d565b6102eb61054c366004613bf8565b611556565b6102eb611883565b6102eb610567366004613c77565b611a40565b34801561057857600080fd5b506102eb610587366004613d28565b611eaf565b34801561059857600080fd5b506102eb6105a7366004613d28565b611f21565b3480156105b857600080fd5b506102eb6120a5565b3480156105cd57600080fd5b506102eb6120df565b3480156105e257600080fd5b5061030d6105f1366004613b28565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561063357600080fd5b5061066d610642366004613b0f565b60076020526000908152604090208054600182015460029092015463ffffffff909116919060ff1683565b6040805163ffffffff90941684526020840192909252151590820152606001610319565b34801561069d57600080fd5b506103eb600081565b3480156106b257600080fd5b506106c66106c1366004613d45565b61218e565b6040516103199190613dba565b6102eb6106e1366004613e3a565b612300565b3480156106f257600080fd5b506103eb600a5481565b34801561070857600080fd5b506103eb60025481565b34801561071e57600080fd5b506102eb61072d366004613b28565b6125ff565b34801561073e57600080fd5b506103eb7f539440820030c4994db4e31b6b800deafd503688728f932addfe7a410515c14c81565b34801561077257600080fd5b506103eb7f8b9e7a9f25b0aca3f51c01b8fee30790fb16f4d4deded8385ae6643d054bb07881565b3480156107a657600080fd5b506103eb6ec097ce7bc90715b34b9f100000000081565b3480156107c957600080fd5b506103eb60065481565b3480156107df57600080fd5b506003546103699073ffffffffffffffffffffffffffffffffffffffff1681565b34801561080c57600080fd5b506103eb600b5481565b6102eb610824366004613e84565b612624565b34801561083557600080fd5b506102eb6128c0565b34801561084a57600080fd5b5061030d610859366004613b0f565b60086020526000908152604090205460ff1681565b7f8b9e7a9f25b0aca3f51c01b8fee30790fb16f4d4deded8385ae6643d054bb078610898816128fe565b8151835114610908576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c6964206c656e67746800000000000000000000000000000000000060448201526064015b60405180910390fd5b60005b82518110156109e45782818151811061092657610926613efa565b60200260200101516007600086848151811061094457610944613efa565b6020908102919091018101518252818101929092526040908101600020835181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9091161781559183015160018301559190910151600290910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806109dc81613f58565b91505061090b565b50505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610a7d57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b610a8b612908565b610ab8600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b610ac0612976565b6ec097ce7bc90715b34b9f100000000084602001511115610b0d576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b44846060015173ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b15610c495734846020015114610b86576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610bee57600080fd5b505af1158015610c02573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016606087015250610c7e9050565b610c7e33308660200151876060015173ffffffffffffffffffffffffffffffffffffffff166129e8909392919063ffffffff16565b7f3dbc28a2fa93575c89d951d683c45ddb951a2ecf6bc9b9704a61589fa0fcb70f846000015185602001518660a001518760400151600660008154610cc290613f58565b918290555060608a015160808b0151604051610ce9979695949392918b918d908c90613f90565b60405180910390a16109e4600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b60035460609073ffffffffffffffffffffffffffffffffffffffff163314610d74576040517ffc9dfe8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8585604051610d84929190614022565b604051809103902060025414610dc6576040517f23dfe1fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600086806020019051810190610ddf9190614098565b92509250925060008251905081518114610e25576040517f94809d2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610f5557610e7c848281518110610e4557610e45613efa565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b610ee257610edd85848381518110610e9657610e96613efa565b6020026020010151868481518110610eb057610eb0613efa565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16612ac49092919063ffffffff16565b610f43565b8473ffffffffffffffffffffffffffffffffffffffff166108fc848381518110610f0e57610f0e613efa565b60200260200101519081150290604051600060405180830381858888f19350505050158015610f41573d6000803e3d6000fd5b505b80610f4d81613f58565b915050610e28565b50506040805160208101909152600081529998505050505050505050565b600082815260208190526040902060010154610f8e816128fe565b610f988383612b1a565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314611042576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016108ff565b61104c8282612c0a565b5050565b611058612908565b611085600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b61108d612976565b60008381526007602052604090206002015460ff1680156110c5575060045473ffffffffffffffffffffffffffffffffffffffff1615155b611151576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f75736463206e6f7420737570706f7274656420656974686572206f6e2073726360448201527f206f6e2064737420636861696e0000000000000000000000000000000000000060648201526084016108ff565b600083815260076020526040902060010154341461119b576040517f58d620b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6ec097ce7bc90715b34b9f10000000008111156111e4576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546112099073ffffffffffffffffffffffffffffffffffffffff163330846129e8565b6005546004546112339173ffffffffffffffffffffffffffffffffffffffff918216911683612cc1565b600554600084815260076020526040808220546004805492517f6fd3504e00000000000000000000000000000000000000000000000000000000815290810186905263ffffffff90911660248201526044810186905273ffffffffffffffffffffffffffffffffffffffff918216606482015291921690636fd3504e906084016020604051808303816000875af11580156112d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f69190614167565b600454604080518881526020810186905290810187905267ffffffffffffffff8316606082015273ffffffffffffffffffffffffffffffffffffffff909116608082015260a081018590523360c08201529091507f297a8bc8b87367a63661d6429dbab51be5cefd71ce6a3050fa900a8f276d66d99060e00160405180910390a1506109e4600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b7f539440820030c4994db4e31b6b800deafd503688728f932addfe7a410515c14c6113d1816128fe565b6113d9612dba565b6113e1612e2b565b50565b7f8b9e7a9f25b0aca3f51c01b8fee30790fb16f4d4deded8385ae6643d054bb07861140e816128fe565b8660010361145b57600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff881617905561154d565b86600203611484578484604051611473929190614022565b60405190819003902060025561154d565b8660030361154d5781831115611542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f6d696e50617573655374616b65416d6f756e74206d757374206265206c65737360448201527f207468616e206f7220657175616c20746f206d617850617573655374616b654160648201527f6d6f756e74000000000000000000000000000000000000000000000000000000608482015260a4016108ff565b600a839055600b8290555b50505050505050565b61155e612908565b61158b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b611593612976565b80516ec097ce7bc90715b34b9f100000000010156115dd576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516020808301516040808501516060808701516080808901518551978801989098529386019490945284015273ffffffffffffffffffffffffffffffffffffffff9182169083015290911660a08201523060c082015260009060e001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600890935291205490915060ff16156116ba576040517f7448c64c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560608201516117299073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b156117b85781513414611768576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080820151825160405173ffffffffffffffffffffffffffffffffffffffff9092169181156108fc0291906000818181858888f193505050501580156117b2573d6000803e3d6000fd5b506117e9565b6080820151825160608401516117e99273ffffffffffffffffffffffffffffffffffffffff909116913391906129e8565b7f0f3ca0b27903ec13ef88a7ea8be837cc19b0d7f71a735f2083215739a8004464813360066000815461181b90613f58565b91829055506040805193845273ffffffffffffffffffffffffffffffffffffffff90921660208401529082015260600160405180910390a1506113e1600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b61188b612976565b600d5460ff166118f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f436f6d6d756e6974792070617573652069732064697361626c6564000000000060448201526064016108ff565b600a54158015906119095750600b5415155b61196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536574205374616b6520416d6f756e742052616e67650000000000000000000060448201526064016108ff565b600a5434101580156119835750600b543411155b6119e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5374616b6520616d6f756e74206f7574206f662072616e67650000000000000060448201526064016108ff565b600034600c546119f99190614191565b600c8190559050611a08612ea8565b60405134815233907f9593b43c20e09177a4170170ac564123ad8138e040e21eec96d1ae9db9ee5d6d9060200160405180910390a250565b611a48612908565b611a75600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b611a7d612976565b80516ec097ce7bc90715b34b9f10000000001015611ac7576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516020808301516040808501516060860151608087015160a08801519351600097611afa9790969530929091016141a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600890935291205490915060ff1615611b7a576040517f7448c64c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556060820151611be99073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b15611c785781513414611c28576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080820151825160405173ffffffffffffffffffffffffffffffffffffffff9092169181156108fc0291906000818181858888f19350505050158015611c72573d6000803e3d6000fd5b50611ca9565b608082015182516060840151611ca99273ffffffffffffffffffffffffffffffffffffffff909116913391906129e8565b60606000611cbb84608001513b151590565b8015611ccc575060008460a0015151115b15611e2b57836080015173ffffffffffffffffffffffffffffffffffffffff1663d00a2d5f60e01b856060015186600001518760a00151604051602401611d1593929190614204565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611d9e9190614242565b6000604051808303816000865af19150503d8060008114611ddb576040519150601f19603f3d011682016040523d82523d6000602084013e611de0565b606091505b509250905080158015611df457506009545a105b15611e2b576040517f9e82ca7900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f21937deaa62558dad619c8d730a7d1d7ef41731fc194c32973511e1455cb37ad8333600660008154611e5d90613f58565b9182905550604051611e75939291908690889061425e565b60405180910390a15050506113e1600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b7f8b9e7a9f25b0aca3f51c01b8fee30790fb16f4d4deded8385ae6643d054bb078611ed9816128fe565b50600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000611f2c816128fe565b611f34612908565b611f61600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff831603611fc45760405133904780156108fc02916000818181858888f19350505050158015611fbe573d6000803e3d6000fd5b50612076565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015261207690339073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015612034573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205891906142a1565b73ffffffffffffffffffffffffffffffffffffffff85169190612ac4565b61104c600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b7f539440820030c4994db4e31b6b800deafd503688728f932addfe7a410515c14c6120cf816128fe565b6120d7612976565b6113e1612ea8565b60006120ea816128fe565b600c54471015612156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e742066756e6473000000000000000000000000000060448201526064016108ff565b600c80546000918290556040519091339183156108fc0291849190818181858888f19350505050158015610f98573d6000803e3d6000fd5b60608167ffffffffffffffff8111156121a9576121a9613543565b6040519080825280602002602001820160405280156121dc57816020015b60608152602001906001900390816121c75790505b50905060005b828110156122f9576000803086868581811061220057612200613efa565b905060200281019061221291906142ba565b604051612220929190614022565b600060405180830381855af49150503d806000811461225b576040519150601f19603f3d011682016040523d82523d6000602084013e612260565b606091505b5091509150816122c65760448151101561227957600080fd5b60048101905080806020019051810190612293919061431f565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ff9190613afc565b808484815181106122d9576122d9613efa565b6020026020010181905250505080806122f190613f58565b9150506121e2565b5092915050565b612308612908565b612335600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b61233d612976565b80156123d65734156123515761235161438d565b7f86896302632bf6dc8a3ac0ae7ddf17d5a5d5c1ca1aad37b4b920a587c51135b18460008460066000815461238590613f58565b91829055506040805173ffffffffffffffffffffffffffffffffffffffff90951685526020850193909352918301526060820152600160808201523360a082015260c00160405180910390a16125d0565b6ec097ce7bc90715b34b9f100000000083111561241f576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff85160361253257348314612489576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156124f157600080fd5b505af1158015612505573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000009350612554565b61255473ffffffffffffffffffffffffffffffffffffffff85163330866129e8565b7f86896302632bf6dc8a3ac0ae7ddf17d5a5d5c1ca1aad37b4b920a587c51135b184848460066000815461258790613f58565b91829055506040805173ffffffffffffffffffffffffffffffffffffffff90951685526020850193909352918301526060820152600060808201523360a082015260c001610ce9565b6109e4600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b60008281526020819052604090206001015461261a816128fe565b610f988383612c0a565b61262c612908565b612659600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b612661612976565b6ec097ce7bc90715b34b9f1000000000836020015111156126ae576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6126e5836060015173ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b156127ea5734836020015114612727576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561278f57600080fd5b505af11580156127a3573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660608601525061281f9050565b61281f33308560200151866060015173ffffffffffffffffffffffffffffffffffffffff166129e8909392919063ffffffff16565b7f6f223106c8e3df857d691613d18d1478cc7c629a1fdf16c7b461d36729fcc7ad836000015184602001518560a00151866040015160066000815461286390613f58565b9182905550606089015160808a015160405161288997969594939291908a908c906143bc565b60405180910390a1610f98600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b60006128cb816128fe565b50600d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6113e18133612f04565b60015460ff16612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016108ff565b565b600154610100900460ff1615612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016108ff565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109e49085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612fbc565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610f989084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612a42565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661104c5760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055612bac3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff161561104c5760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff83811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5b91906142a1565b90506109e4847f095ea7b30000000000000000000000000000000000000000000000000000000085612d8d8686614191565b60405173ffffffffffffffffffffffffffffffffffffffff90921660248301526044820152606401612a42565b600154610100900460ff16612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016108ff565b612e33612dba565b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b612eb0612976565b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612e7e3390565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661104c57612f42816130cb565b612f4d8360206130ea565b604051602001612f5e929190614439565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526108ff91600401613afc565b600061301e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166133349092919063ffffffff16565b905080516000148061303f57508080602001905181019061303f91906144ba565b610f98576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ff565b6060610a7d73ffffffffffffffffffffffffffffffffffffffff831660145b606060006130f98360026144d7565b613104906002614191565b67ffffffffffffffff81111561311c5761311c613543565b6040519080825280601f01601f191660200182016040528015613146576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061317d5761317d613efa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106131e0576131e0613efa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061321c8460026144d7565b613227906001614191565b90505b60018111156132c4577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061326857613268613efa565b1a60f81b82828151811061327e5761327e613efa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936132bd816144ee565b905061322a565b50831561332d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ff565b9392505050565b6060613343848460008561334b565b949350505050565b6060824710156133dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ff565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516134069190614242565b60006040518083038185875af1925050503d8060008114613443576040519150601f19603f3d011682016040523d82523d6000602084013e613448565b606091505b509150915061345987838387613464565b979650505050505050565b606083156134fa5782516000036134f35773ffffffffffffffffffffffffffffffffffffffff85163b6134f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ff565b5081613343565b613343838381511561350f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ff9190613afc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561359557613595613543565b60405290565b60405160c0810167ffffffffffffffff8111828210171561359557613595613543565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561360557613605613543565b604052919050565b600067ffffffffffffffff82111561362757613627613543565b5060051b60200190565b80151581146113e157600080fd5b600082601f83011261365057600080fd5b813560206136656136608361360d565b6135be565b8281526060928302850182019282820191908785111561368457600080fd5b8387015b858110156136e75781818a0312156136a05760008081fd5b6136a8613572565b813563ffffffff811681146136bd5760008081fd5b815281860135868201526040808301356136d681613631565b908201528452928401928101613688565b5090979650505050505050565b6000806040838503121561370757600080fd5b823567ffffffffffffffff8082111561371f57600080fd5b818501915085601f83011261373357600080fd5b813560206137436136608361360d565b82815260059290921b8401810191818101908984111561376257600080fd5b948201945b8386101561378057853582529482019490820190613767565b9650508601359250508082111561379657600080fd5b506137a38582860161363f565b9150509250929050565b6000602082840312156137bf57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461332d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff811681146113e157600080fd5b600060c0828403121561382357600080fd5b61382b61359b565b90508135815260208201356020820152604082013560408201526060820135613853816137ef565b60608201526080820135613866816137ef565b8060808301525060a082013560a082015292915050565b600067ffffffffffffffff82111561389757613897613543565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126138d457600080fd5b81356138e26136608261387d565b8181528460208386010111156138f757600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080610120858703121561392b57600080fd5b6139358686613811565b935060c085013567ffffffffffffffff8082111561395257600080fd5b61395e888389016138c3565b945060e087013591508082111561397457600080fd5b613980888389016138c3565b935061010087013591508082111561399757600080fd5b506139a4878288016138c3565b91505092959194509250565b60008083601f8401126139c257600080fd5b50813567ffffffffffffffff8111156139da57600080fd5b6020830191508360208285010111156139f257600080fd5b9250929050565b600080600080600060608688031215613a1157600080fd5b853567ffffffffffffffff80821115613a2957600080fd5b613a3589838a016139b0565b90975095506020880135915080821115613a4e57600080fd5b613a5a89838a016138c3565b94506040880135915080821115613a7057600080fd5b50613a7d888289016139b0565b969995985093965092949392505050565b60005b83811015613aa9578181015183820152602001613a91565b50506000910152565b60008151808452613aca816020860160208601613a8e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061332d6020830184613ab2565b600060208284031215613b2157600080fd5b5035919050565b60008060408385031215613b3b57600080fd5b823591506020830135613b4d816137ef565b809150509250929050565b60008060008060808587031215613b6e57600080fd5b5050823594602084013594506040840135936060013592509050565b60008060008060008060a08789031215613ba357600080fd5b863595506020870135613bb5816137ef565b9450604087013567ffffffffffffffff811115613bd157600080fd5b613bdd89828a016139b0565b979a9699509760608101359660809091013595509350505050565b600060a08284031215613c0a57600080fd5b60405160a0810181811067ffffffffffffffff82111715613c2d57613c2d613543565b80604052508235815260208301356020820152604083013560408201526060830135613c58816137ef565b60608201526080830135613c6b816137ef565b60808201529392505050565b600060208284031215613c8957600080fd5b813567ffffffffffffffff80821115613ca157600080fd5b9083019060c08286031215613cb557600080fd5b613cbd61359b565b8235815260208301356020820152604083013560408201526060830135613ce3816137ef565b60608201526080830135613cf6816137ef565b608082015260a083013582811115613d0d57600080fd5b613d19878286016138c3565b60a08301525095945050505050565b600060208284031215613d3a57600080fd5b813561332d816137ef565b60008060208385031215613d5857600080fd5b823567ffffffffffffffff80821115613d7057600080fd5b818501915085601f830112613d8457600080fd5b813581811115613d9357600080fd5b8660208260051b8501011115613da857600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613e2d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613e1b858351613ab2565b94509285019290850190600101613de1565b5092979650505050505050565b60008060008060808587031215613e5057600080fd5b8435613e5b816137ef565b935060208501359250604085013591506060850135613e7981613631565b939692955090935050565b60008060006101008486031215613e9a57600080fd5b613ea48585613811565b925060c084013567ffffffffffffffff80821115613ec157600080fd5b613ecd878388016138c3565b935060e0860135915080821115613ee357600080fd5b50613ef0868287016138c3565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f8957613f89613f29565b5060010190565b60006101408c83528b60208401528a604084015289606084015288608084015273ffffffffffffffffffffffffffffffffffffffff80891660a08501528160c0850152613fdf82850189613ab2565b90871660e08501528381036101008501529050613ffc8186613ab2565b90508281036101208401526140118185613ab2565b9d9c50505050505050505050505050565b8183823760009101908152919050565b600082601f83011261404357600080fd5b815160206140536136608361360d565b82815260059290921b8401810191818101908684111561407257600080fd5b8286015b8481101561408d5780518352918301918301614076565b509695505050505050565b6000806000606084860312156140ad57600080fd5b83516140b8816137ef565b8093505060208085015167ffffffffffffffff808211156140d857600080fd5b818701915087601f8301126140ec57600080fd5b81516140fa6136608261360d565b81815260059190911b8301840190848101908a83111561411957600080fd5b938501935b82851015614140578451614131816137ef565b8252938501939085019061411e565b60408a0151909750945050508083111561415957600080fd5b5050613ef086828701614032565b60006020828403121561417957600080fd5b815167ffffffffffffffff8116811461332d57600080fd5b80820180821115610a7d57610a7d613f29565b878152866020820152856040820152600073ffffffffffffffffffffffffffffffffffffffff8087166060840152808616608084015280851660a08401525060e060c08301526141f760e0830184613ab2565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006142396060830184613ab2565b95945050505050565b60008251614254818460208701613a8e565b9190910192915050565b85815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152821515606082015260a06080820152600061345960a0830184613ab2565b6000602082840312156142b357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142ef57600080fd5b83018035915067ffffffffffffffff82111561430a57600080fd5b6020019150368190038213156139f257600080fd5b60006020828403121561433157600080fd5b815167ffffffffffffffff81111561434857600080fd5b8201601f8101841361435957600080fd5b80516143676136608261387d565b81815285602083850101111561437c57600080fd5b614239826020830160208601613a8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60006101208b83528a602084015289604084015288606084015287608084015273ffffffffffffffffffffffffffffffffffffffff80881660a085015280871660c0850152508060e084015261441481840186613ab2565b90508281036101008401526144298185613ab2565b9c9b505050505050505050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614471816017850160208801613a8e565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516144ae816028840160208801613a8e565b01602801949350505050565b6000602082840312156144cc57600080fd5b815161332d81613631565b8082028115828204841417610a7d57610a7d613f29565b6000816144fd576144fd613f29565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220e11acc2a66d5e5b8998d9bd6bd0b9b67acf801449e3745dcaaa1c24c1a8e7a1e64736f6c63430008120033000000000000000000000000420000000000000000000000000000000000000600000000000000000000000086dfc31d9cb3280ee1eb1096caa9fc66299af973000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda029130000000000000000000000001682ae6375c4e4a97e4b583bc394c861a46d896200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000c3500000000000000000000000000000000000000000000000000000000000000041726f757465723134686a32746176713866706573647778786375343472747933686839307668756a7276636d73746c347a723374786d667677397330307a74766b00000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102c65760003560e01c806378e0f9bd11610179578063c44e947e116100d6578063de35f5cb1161008a578063f452ed4d11610064578063f452ed4d14610816578063f627df9414610829578063fd5ad37c1461083e57600080fd5b8063de35f5cb146107bd578063eb0cde1d146107d3578063f215f1481461080057600080fd5b8063d9dc8694116100bb578063d9dc869414610732578063db618e2a14610766578063ddd224f11461079a57600080fd5b8063c44e947e146106fc578063d547741f1461071257600080fd5b8063981a8a021161012d578063ac9650d811610112578063ac9650d8146106a6578063ad7c17ee146106d3578063b19941a9146106e657600080fd5b8063981a8a0214610627578063a217fddf1461069157600080fd5b80638456cb591161015e5780638456cb59146105ac5780638a27fecb146105c157806391d14854146105d657600080fd5b806378e0f9bd1461056c578063839006f21461058c57600080fd5b80633f4ba83a116102275780635ac62700116101db57806364778c1f116101c057806364778c1f1461053e5780636696821b146105515780636fb003da1461055957600080fd5b80635ac62700146105015780635c975abb1461052157600080fd5b8063461178301161020c57806346117830146104a85780634b7b9476146104d5578063567e98f9146104eb57600080fd5b80633f4ba83a146104795780634463182f1461048e57600080fd5b8063248a9ca31161027e57806336568abe1161026357806336568abe146104195780633e28c7d2146104395780633e413bee1461044c57600080fd5b8063248a9ca3146103bb5780632f2ff15d146103f957600080fd5b80630421caf0116102af5780630421caf01461032257806317fcb39b146103355780631aa6485a1461038e57600080fd5b80630171958a146102cb57806301ffc9a7146102ed575b600080fd5b3480156102d757600080fd5b506102eb6102e63660046136f4565b61086e565b005b3480156102f957600080fd5b5061030d6103083660046137ad565b6109ea565b60405190151581526020015b60405180910390f35b6102eb610330366004613914565b610a83565b34801561034157600080fd5b506103697f000000000000000000000000420000000000000000000000000000000000000681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b34801561039a57600080fd5b506103ae6103a93660046139f9565b610d20565b6040516103199190613afc565b3480156103c757600080fd5b506103eb6103d6366004613b0f565b60009081526020819052604090206001015490565b604051908152602001610319565b34801561040557600080fd5b506102eb610414366004613b28565b610f73565b34801561042557600080fd5b506102eb610434366004613b28565b610f9d565b6102eb610447366004613b58565b611050565b34801561045857600080fd5b506004546103699073ffffffffffffffffffffffffffffffffffffffff1681565b34801561048557600080fd5b506102eb6113a7565b34801561049a57600080fd5b50600d5461030d9060ff1681565b3480156104b457600080fd5b506005546103699073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104e157600080fd5b506103eb60095481565b3480156104f757600080fd5b506103eb600c5481565b34801561050d57600080fd5b506102eb61051c366004613b8a565b6113e4565b34801561052d57600080fd5b50600154610100900460ff1661030d565b6102eb61054c366004613bf8565b611556565b6102eb611883565b6102eb610567366004613c77565b611a40565b34801561057857600080fd5b506102eb610587366004613d28565b611eaf565b34801561059857600080fd5b506102eb6105a7366004613d28565b611f21565b3480156105b857600080fd5b506102eb6120a5565b3480156105cd57600080fd5b506102eb6120df565b3480156105e257600080fd5b5061030d6105f1366004613b28565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561063357600080fd5b5061066d610642366004613b0f565b60076020526000908152604090208054600182015460029092015463ffffffff909116919060ff1683565b6040805163ffffffff90941684526020840192909252151590820152606001610319565b34801561069d57600080fd5b506103eb600081565b3480156106b257600080fd5b506106c66106c1366004613d45565b61218e565b6040516103199190613dba565b6102eb6106e1366004613e3a565b612300565b3480156106f257600080fd5b506103eb600a5481565b34801561070857600080fd5b506103eb60025481565b34801561071e57600080fd5b506102eb61072d366004613b28565b6125ff565b34801561073e57600080fd5b506103eb7f539440820030c4994db4e31b6b800deafd503688728f932addfe7a410515c14c81565b34801561077257600080fd5b506103eb7f8b9e7a9f25b0aca3f51c01b8fee30790fb16f4d4deded8385ae6643d054bb07881565b3480156107a657600080fd5b506103eb6ec097ce7bc90715b34b9f100000000081565b3480156107c957600080fd5b506103eb60065481565b3480156107df57600080fd5b506003546103699073ffffffffffffffffffffffffffffffffffffffff1681565b34801561080c57600080fd5b506103eb600b5481565b6102eb610824366004613e84565b612624565b34801561083557600080fd5b506102eb6128c0565b34801561084a57600080fd5b5061030d610859366004613b0f565b60086020526000908152604090205460ff1681565b7f8b9e7a9f25b0aca3f51c01b8fee30790fb16f4d4deded8385ae6643d054bb078610898816128fe565b8151835114610908576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f696e76616c6964206c656e67746800000000000000000000000000000000000060448201526064015b60405180910390fd5b60005b82518110156109e45782818151811061092657610926613efa565b60200260200101516007600086848151811061094457610944613efa565b6020908102919091018101518252818101929092526040908101600020835181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff9091161781559183015160018301559190910151600290910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806109dc81613f58565b91505061090b565b50505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610a7d57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b610a8b612908565b610ab8600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b610ac0612976565b6ec097ce7bc90715b34b9f100000000084602001511115610b0d576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b44846060015173ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b15610c495734846020015114610b86576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000420000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610bee57600080fd5b505af1158015610c02573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000420000000000000000000000000000000000000616606087015250610c7e9050565b610c7e33308660200151876060015173ffffffffffffffffffffffffffffffffffffffff166129e8909392919063ffffffff16565b7f3dbc28a2fa93575c89d951d683c45ddb951a2ecf6bc9b9704a61589fa0fcb70f846000015185602001518660a001518760400151600660008154610cc290613f58565b918290555060608a015160808b0151604051610ce9979695949392918b918d908c90613f90565b60405180910390a16109e4600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b60035460609073ffffffffffffffffffffffffffffffffffffffff163314610d74576040517ffc9dfe8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8585604051610d84929190614022565b604051809103902060025414610dc6576040517f23dfe1fb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600086806020019051810190610ddf9190614098565b92509250925060008251905081518114610e25576040517f94809d2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610f5557610e7c848281518110610e4557610e45613efa565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b610ee257610edd85848381518110610e9657610e96613efa565b6020026020010151868481518110610eb057610eb0613efa565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16612ac49092919063ffffffff16565b610f43565b8473ffffffffffffffffffffffffffffffffffffffff166108fc848381518110610f0e57610f0e613efa565b60200260200101519081150290604051600060405180830381858888f19350505050158015610f41573d6000803e3d6000fd5b505b80610f4d81613f58565b915050610e28565b50506040805160208101909152600081529998505050505050505050565b600082815260208190526040902060010154610f8e816128fe565b610f988383612b1a565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314611042576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016108ff565b61104c8282612c0a565b5050565b611058612908565b611085600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b61108d612976565b60008381526007602052604090206002015460ff1680156110c5575060045473ffffffffffffffffffffffffffffffffffffffff1615155b611151576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f75736463206e6f7420737570706f7274656420656974686572206f6e2073726360448201527f206f6e2064737420636861696e0000000000000000000000000000000000000060648201526084016108ff565b600083815260076020526040902060010154341461119b576040517f58d620b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6ec097ce7bc90715b34b9f10000000008111156111e4576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546112099073ffffffffffffffffffffffffffffffffffffffff163330846129e8565b6005546004546112339173ffffffffffffffffffffffffffffffffffffffff918216911683612cc1565b600554600084815260076020526040808220546004805492517f6fd3504e00000000000000000000000000000000000000000000000000000000815290810186905263ffffffff90911660248201526044810186905273ffffffffffffffffffffffffffffffffffffffff918216606482015291921690636fd3504e906084016020604051808303816000875af11580156112d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f69190614167565b600454604080518881526020810186905290810187905267ffffffffffffffff8316606082015273ffffffffffffffffffffffffffffffffffffffff909116608082015260a081018590523360c08201529091507f297a8bc8b87367a63661d6429dbab51be5cefd71ce6a3050fa900a8f276d66d99060e00160405180910390a1506109e4600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b7f539440820030c4994db4e31b6b800deafd503688728f932addfe7a410515c14c6113d1816128fe565b6113d9612dba565b6113e1612e2b565b50565b7f8b9e7a9f25b0aca3f51c01b8fee30790fb16f4d4deded8385ae6643d054bb07861140e816128fe565b8660010361145b57600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff881617905561154d565b86600203611484578484604051611473929190614022565b60405190819003902060025561154d565b8660030361154d5781831115611542576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f6d696e50617573655374616b65416d6f756e74206d757374206265206c65737360448201527f207468616e206f7220657175616c20746f206d617850617573655374616b654160648201527f6d6f756e74000000000000000000000000000000000000000000000000000000608482015260a4016108ff565b600a839055600b8290555b50505050505050565b61155e612908565b61158b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b611593612976565b80516ec097ce7bc90715b34b9f100000000010156115dd576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516020808301516040808501516060808701516080808901518551978801989098529386019490945284015273ffffffffffffffffffffffffffffffffffffffff9182169083015290911660a08201523060c082015260009060e001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600890935291205490915060ff16156116ba576040517f7448c64c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905560608201516117299073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b156117b85781513414611768576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080820151825160405173ffffffffffffffffffffffffffffffffffffffff9092169181156108fc0291906000818181858888f193505050501580156117b2573d6000803e3d6000fd5b506117e9565b6080820151825160608401516117e99273ffffffffffffffffffffffffffffffffffffffff909116913391906129e8565b7f0f3ca0b27903ec13ef88a7ea8be837cc19b0d7f71a735f2083215739a8004464813360066000815461181b90613f58565b91829055506040805193845273ffffffffffffffffffffffffffffffffffffffff90921660208401529082015260600160405180910390a1506113e1600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b61188b612976565b600d5460ff166118f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f436f6d6d756e6974792070617573652069732064697361626c6564000000000060448201526064016108ff565b600a54158015906119095750600b5415155b61196f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536574205374616b6520416d6f756e742052616e67650000000000000000000060448201526064016108ff565b600a5434101580156119835750600b543411155b6119e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5374616b6520616d6f756e74206f7574206f662072616e67650000000000000060448201526064016108ff565b600034600c546119f99190614191565b600c8190559050611a08612ea8565b60405134815233907f9593b43c20e09177a4170170ac564123ad8138e040e21eec96d1ae9db9ee5d6d9060200160405180910390a250565b611a48612908565b611a75600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b611a7d612976565b80516ec097ce7bc90715b34b9f10000000001015611ac7576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80516020808301516040808501516060860151608087015160a08801519351600097611afa9790969530929091016141a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600890935291205490915060ff1615611b7a576040517f7448c64c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556060820151611be99073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b15611c785781513414611c28576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6080820151825160405173ffffffffffffffffffffffffffffffffffffffff9092169181156108fc0291906000818181858888f19350505050158015611c72573d6000803e3d6000fd5b50611ca9565b608082015182516060840151611ca99273ffffffffffffffffffffffffffffffffffffffff909116913391906129e8565b60606000611cbb84608001513b151590565b8015611ccc575060008460a0015151115b15611e2b57836080015173ffffffffffffffffffffffffffffffffffffffff1663d00a2d5f60e01b856060015186600001518760a00151604051602401611d1593929190614204565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611d9e9190614242565b6000604051808303816000865af19150503d8060008114611ddb576040519150601f19603f3d011682016040523d82523d6000602084013e611de0565b606091505b509250905080158015611df457506009545a105b15611e2b576040517f9e82ca7900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f21937deaa62558dad619c8d730a7d1d7ef41731fc194c32973511e1455cb37ad8333600660008154611e5d90613f58565b9182905550604051611e75939291908690889061425e565b60405180910390a15050506113e1600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b7f8b9e7a9f25b0aca3f51c01b8fee30790fb16f4d4deded8385ae6643d054bb078611ed9816128fe565b50600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000611f2c816128fe565b611f34612908565b611f61600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff831603611fc45760405133904780156108fc02916000818181858888f19350505050158015611fbe573d6000803e3d6000fd5b50612076565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015261207690339073ffffffffffffffffffffffffffffffffffffffff8516906370a0823190602401602060405180830381865afa158015612034573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061205891906142a1565b73ffffffffffffffffffffffffffffffffffffffff85169190612ac4565b61104c600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b7f539440820030c4994db4e31b6b800deafd503688728f932addfe7a410515c14c6120cf816128fe565b6120d7612976565b6113e1612ea8565b60006120ea816128fe565b600c54471015612156576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e73756666696369656e742066756e6473000000000000000000000000000060448201526064016108ff565b600c80546000918290556040519091339183156108fc0291849190818181858888f19350505050158015610f98573d6000803e3d6000fd5b60608167ffffffffffffffff8111156121a9576121a9613543565b6040519080825280602002602001820160405280156121dc57816020015b60608152602001906001900390816121c75790505b50905060005b828110156122f9576000803086868581811061220057612200613efa565b905060200281019061221291906142ba565b604051612220929190614022565b600060405180830381855af49150503d806000811461225b576040519150601f19603f3d011682016040523d82523d6000602084013e612260565b606091505b5091509150816122c65760448151101561227957600080fd5b60048101905080806020019051810190612293919061431f565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ff9190613afc565b808484815181106122d9576122d9613efa565b6020026020010181905250505080806122f190613f58565b9150506121e2565b5092915050565b612308612908565b612335600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b61233d612976565b80156123d65734156123515761235161438d565b7f86896302632bf6dc8a3ac0ae7ddf17d5a5d5c1ca1aad37b4b920a587c51135b18460008460066000815461238590613f58565b91829055506040805173ffffffffffffffffffffffffffffffffffffffff90951685526020850193909352918301526060820152600160808201523360a082015260c00160405180910390a16125d0565b6ec097ce7bc90715b34b9f100000000083111561241f576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff85160361253257348314612489576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000420000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156124f157600080fd5b505af1158015612505573d6000803e3d6000fd5b50505050507f00000000000000000000000042000000000000000000000000000000000000069350612554565b61255473ffffffffffffffffffffffffffffffffffffffff85163330866129e8565b7f86896302632bf6dc8a3ac0ae7ddf17d5a5d5c1ca1aad37b4b920a587c51135b184848460066000815461258790613f58565b91829055506040805173ffffffffffffffffffffffffffffffffffffffff90951685526020850193909352918301526060820152600060808201523360a082015260c001610ce9565b6109e4600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b60008281526020819052604090206001015461261a816128fe565b610f988383612c0a565b61262c612908565b612659600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b612661612976565b6ec097ce7bc90715b34b9f1000000000836020015111156126ae576040517f0625040100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6126e5836060015173ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b156127ea5734836020015114612727576040517f2c5211c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000420000000000000000000000000000000000000673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561278f57600080fd5b505af11580156127a3573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000042000000000000000000000000000000000000061660608601525061281f9050565b61281f33308560200151866060015173ffffffffffffffffffffffffffffffffffffffff166129e8909392919063ffffffff16565b7f6f223106c8e3df857d691613d18d1478cc7c629a1fdf16c7b461d36729fcc7ad836000015184602001518560a00151866040015160066000815461286390613f58565b9182905550606089015160808a015160405161288997969594939291908a908c906143bc565b60405180910390a1610f98600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681179055565b60006128cb816128fe565b50600d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00811660ff90911615179055565b6113e18133612f04565b60015460ff16612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016108ff565b565b600154610100900460ff1615612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016108ff565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526109e49085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612fbc565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610f989084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401612a42565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661104c5760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055612bac3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff161561104c5760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff83811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d5b91906142a1565b90506109e4847f095ea7b30000000000000000000000000000000000000000000000000000000085612d8d8686614191565b60405173ffffffffffffffffffffffffffffffffffffffff90921660248301526044820152606401612a42565b600154610100900460ff16612974576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016108ff565b612e33612dba565b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b612eb0612976565b600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612e7e3390565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1661104c57612f42816130cb565b612f4d8360206130ea565b604051602001612f5e929190614439565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526108ff91600401613afc565b600061301e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166133349092919063ffffffff16565b905080516000148061303f57508080602001905181019061303f91906144ba565b610f98576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016108ff565b6060610a7d73ffffffffffffffffffffffffffffffffffffffff831660145b606060006130f98360026144d7565b613104906002614191565b67ffffffffffffffff81111561311c5761311c613543565b6040519080825280601f01601f191660200182016040528015613146576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061317d5761317d613efa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106131e0576131e0613efa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061321c8460026144d7565b613227906001614191565b90505b60018111156132c4577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061326857613268613efa565b1a60f81b82828151811061327e5761327e613efa565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936132bd816144ee565b905061322a565b50831561332d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ff565b9392505050565b6060613343848460008561334b565b949350505050565b6060824710156133dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016108ff565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516134069190614242565b60006040518083038185875af1925050503d8060008114613443576040519150601f19603f3d011682016040523d82523d6000602084013e613448565b606091505b509150915061345987838387613464565b979650505050505050565b606083156134fa5782516000036134f35773ffffffffffffffffffffffffffffffffffffffff85163b6134f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016108ff565b5081613343565b613343838381511561350f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ff9190613afc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561359557613595613543565b60405290565b60405160c0810167ffffffffffffffff8111828210171561359557613595613543565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561360557613605613543565b604052919050565b600067ffffffffffffffff82111561362757613627613543565b5060051b60200190565b80151581146113e157600080fd5b600082601f83011261365057600080fd5b813560206136656136608361360d565b6135be565b8281526060928302850182019282820191908785111561368457600080fd5b8387015b858110156136e75781818a0312156136a05760008081fd5b6136a8613572565b813563ffffffff811681146136bd5760008081fd5b815281860135868201526040808301356136d681613631565b908201528452928401928101613688565b5090979650505050505050565b6000806040838503121561370757600080fd5b823567ffffffffffffffff8082111561371f57600080fd5b818501915085601f83011261373357600080fd5b813560206137436136608361360d565b82815260059290921b8401810191818101908984111561376257600080fd5b948201945b8386101561378057853582529482019490820190613767565b9650508601359250508082111561379657600080fd5b506137a38582860161363f565b9150509250929050565b6000602082840312156137bf57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461332d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff811681146113e157600080fd5b600060c0828403121561382357600080fd5b61382b61359b565b90508135815260208201356020820152604082013560408201526060820135613853816137ef565b60608201526080820135613866816137ef565b8060808301525060a082013560a082015292915050565b600067ffffffffffffffff82111561389757613897613543565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126138d457600080fd5b81356138e26136608261387d565b8181528460208386010111156138f757600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080610120858703121561392b57600080fd5b6139358686613811565b935060c085013567ffffffffffffffff8082111561395257600080fd5b61395e888389016138c3565b945060e087013591508082111561397457600080fd5b613980888389016138c3565b935061010087013591508082111561399757600080fd5b506139a4878288016138c3565b91505092959194509250565b60008083601f8401126139c257600080fd5b50813567ffffffffffffffff8111156139da57600080fd5b6020830191508360208285010111156139f257600080fd5b9250929050565b600080600080600060608688031215613a1157600080fd5b853567ffffffffffffffff80821115613a2957600080fd5b613a3589838a016139b0565b90975095506020880135915080821115613a4e57600080fd5b613a5a89838a016138c3565b94506040880135915080821115613a7057600080fd5b50613a7d888289016139b0565b969995985093965092949392505050565b60005b83811015613aa9578181015183820152602001613a91565b50506000910152565b60008151808452613aca816020860160208601613a8e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061332d6020830184613ab2565b600060208284031215613b2157600080fd5b5035919050565b60008060408385031215613b3b57600080fd5b823591506020830135613b4d816137ef565b809150509250929050565b60008060008060808587031215613b6e57600080fd5b5050823594602084013594506040840135936060013592509050565b60008060008060008060a08789031215613ba357600080fd5b863595506020870135613bb5816137ef565b9450604087013567ffffffffffffffff811115613bd157600080fd5b613bdd89828a016139b0565b979a9699509760608101359660809091013595509350505050565b600060a08284031215613c0a57600080fd5b60405160a0810181811067ffffffffffffffff82111715613c2d57613c2d613543565b80604052508235815260208301356020820152604083013560408201526060830135613c58816137ef565b60608201526080830135613c6b816137ef565b60808201529392505050565b600060208284031215613c8957600080fd5b813567ffffffffffffffff80821115613ca157600080fd5b9083019060c08286031215613cb557600080fd5b613cbd61359b565b8235815260208301356020820152604083013560408201526060830135613ce3816137ef565b60608201526080830135613cf6816137ef565b608082015260a083013582811115613d0d57600080fd5b613d19878286016138c3565b60a08301525095945050505050565b600060208284031215613d3a57600080fd5b813561332d816137ef565b60008060208385031215613d5857600080fd5b823567ffffffffffffffff80821115613d7057600080fd5b818501915085601f830112613d8457600080fd5b813581811115613d9357600080fd5b8660208260051b8501011115613da857600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613e2d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613e1b858351613ab2565b94509285019290850190600101613de1565b5092979650505050505050565b60008060008060808587031215613e5057600080fd5b8435613e5b816137ef565b935060208501359250604085013591506060850135613e7981613631565b939692955090935050565b60008060006101008486031215613e9a57600080fd5b613ea48585613811565b925060c084013567ffffffffffffffff80821115613ec157600080fd5b613ecd878388016138c3565b935060e0860135915080821115613ee357600080fd5b50613ef0868287016138c3565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f8957613f89613f29565b5060010190565b60006101408c83528b60208401528a604084015289606084015288608084015273ffffffffffffffffffffffffffffffffffffffff80891660a08501528160c0850152613fdf82850189613ab2565b90871660e08501528381036101008501529050613ffc8186613ab2565b90508281036101208401526140118185613ab2565b9d9c50505050505050505050505050565b8183823760009101908152919050565b600082601f83011261404357600080fd5b815160206140536136608361360d565b82815260059290921b8401810191818101908684111561407257600080fd5b8286015b8481101561408d5780518352918301918301614076565b509695505050505050565b6000806000606084860312156140ad57600080fd5b83516140b8816137ef565b8093505060208085015167ffffffffffffffff808211156140d857600080fd5b818701915087601f8301126140ec57600080fd5b81516140fa6136608261360d565b81815260059190911b8301840190848101908a83111561411957600080fd5b938501935b82851015614140578451614131816137ef565b8252938501939085019061411e565b60408a0151909750945050508083111561415957600080fd5b5050613ef086828701614032565b60006020828403121561417957600080fd5b815167ffffffffffffffff8116811461332d57600080fd5b80820180821115610a7d57610a7d613f29565b878152866020820152856040820152600073ffffffffffffffffffffffffffffffffffffffff8087166060840152808616608084015280851660a08401525060e060c08301526141f760e0830184613ab2565b9998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff841681528260208201526060604082015260006142396060830184613ab2565b95945050505050565b60008251614254818460208701613a8e565b9190910192915050565b85815273ffffffffffffffffffffffffffffffffffffffff85166020820152836040820152821515606082015260a06080820152600061345960a0830184613ab2565b6000602082840312156142b357600080fd5b5051919050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126142ef57600080fd5b83018035915067ffffffffffffffff82111561430a57600080fd5b6020019150368190038213156139f257600080fd5b60006020828403121561433157600080fd5b815167ffffffffffffffff81111561434857600080fd5b8201601f8101841361435957600080fd5b80516143676136608261387d565b81815285602083850101111561437c57600080fd5b614239826020830160208601613a8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60006101208b83528a602084015289604084015288606084015287608084015273ffffffffffffffffffffffffffffffffffffffff80881660a085015280871660c0850152508060e084015261441481840186613ab2565b90508281036101008401526144298185613ab2565b9c9b505050505050505050505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614471816017850160208801613a8e565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516144ae816028840160208801613a8e565b01602801949350505050565b6000602082840312156144cc57600080fd5b815161332d81613631565b8082028115828204841417610a7d57610a7d613f29565b6000816144fd576144fd613f29565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220e11acc2a66d5e5b8998d9bd6bd0b9b67acf801449e3745dcaaa1c24c1a8e7a1e64736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000420000000000000000000000000000000000000600000000000000000000000086dfc31d9cb3280ee1eb1096caa9fc66299af973000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda029130000000000000000000000001682ae6375c4e4a97e4b583bc394c861a46d896200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000c3500000000000000000000000000000000000000000000000000000000000000041726f757465723134686a32746176713866706573647778786375343472747933686839307668756a7276636d73746c347a723374786d667677397330307a74766b00000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _wrappedNativeTokenAddress (address): 0x4200000000000000000000000000000000000006
Arg [1] : _gatewayContract (address): 0x86DFc31d9cB3280eE1eB1096caa9fC66299Af973
Arg [2] : _usdcAddress (address): 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Arg [3] : _tokenMessenger (address): 0x1682Ae6375C4E4A97e4B583BC394c861A46D8962
Arg [4] : _routerMiddlewareBase (bytes): 0x726f757465723134686a32746176713866706573647778786375343472747933686839307668756a7276636d73746c347a723374786d667677397330307a74766b
Arg [5] : _minGasThreshhold (uint256): 50000
-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 0000000000000000000000004200000000000000000000000000000000000006
Arg [1] : 00000000000000000000000086dfc31d9cb3280ee1eb1096caa9fc66299af973
Arg [2] : 000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913
Arg [3] : 0000000000000000000000001682ae6375c4e4a97e4b583bc394c861a46d8962
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [5] : 000000000000000000000000000000000000000000000000000000000000c350
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000041
Arg [7] : 726f757465723134686a32746176713866706573647778786375343472747933
Arg [8] : 686839307668756a7276636d73746c347a723374786d667677397330307a7476
Arg [9] : 6b00000000000000000000000000000000000000000000000000000000000000
Deployed ByteCode Sourcemap
63811:14763:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67517:431;;;;;;;;;;-1:-1:-1;67517:431:0;;;;;:::i;:::-;;:::i;:::-;;27802:204;;;;;;;;;;-1:-1:-1;27802:204:0;;;;;:::i;:::-;;:::i;:::-;;;4376:14:1;;4369:22;4351:41;;4339:2;4324:18;27802:204:0;;;;;;;;71415:1165;;;;;;:::i;:::-;;:::i;63977:41::-;;;;;;;;;;;;;;;;;;7039:42:1;7027:55;;;7009:74;;6997:2;6982:18;63977:41:0;6849:240:1;75676:962:0;;;;;;;;;;-1:-1:-1;75676:962:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;29625:131::-;;;;;;;;;;-1:-1:-1;29625:131:0;;;;;:::i;:::-;29699:7;29726:12;;;;;;;;;;:22;;;;29625:131;;;;9513:25:1;;;9501:2;9486:18;29625:131:0;9367:177:1;30066:147:0;;;;;;;;;;-1:-1:-1;30066:147:0;;;;;:::i;:::-;;:::i;31210:218::-;;;;;;;;;;-1:-1:-1;31210:218:0;;;;;:::i;:::-;;:::i;67956:1107::-;;;;;;:::i;:::-;;:::i;64128:19::-;;;;;;;;;;-1:-1:-1;64128:19:0;;;;;;;;67305:85;;;;;;;;;;;;;:::i;64724:42::-;;;;;;;;;;-1:-1:-1;64724:42:0;;;;;;;;64183:37;;;;;;;;;;-1:-1:-1;64183:37:0;;;;;;;;64563:33;;;;;;;;;;;;;;;;64685:32;;;;;;;;;;;;;;;;65935:768;;;;;;;;;;-1:-1:-1;65935:768:0;;;;;:::i;:::-;;:::i;2454:86::-;;;;;;;;;;-1:-1:-1;2525:7:0;;;;;;;2454:86;;72588:1193;;;;;;:::i;:::-;;:::i;77518:703::-;;;:::i;73789:1879::-;;;;;;:::i;:::-;;:::i;66899:174::-;;;;;;;;;;-1:-1:-1;66899:174:0;;;;;:::i;:::-;;:::i;76988:375::-;;;;;;;;;;-1:-1:-1;76988:375:0;;;;;:::i;:::-;;:::i;67081:84::-;;;;;;;;;;;;;:::i;78229:342::-;;;;;;;;;;;;;:::i;28098:147::-;;;;;;;;;;-1:-1:-1;28098:147:0;;;;;:::i;:::-;28184:4;28208:12;;;;;;;;;;;:29;;;;;;;;;;;;;;;;28098:147;64263:50;;;;;;;;;;-1:-1:-1;64263:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14074:10:1;14062:23;;;14044:42;;14117:2;14102:18;;14095:34;;;;14172:14;14165:22;14145:18;;;14138:50;14032:2;14017:18;64263:50:0;13850:344:1;27203:49:0;;;;;;;;;;-1:-1:-1;27203:49:0;27248:4;27203:49;;63150:654;;;;;;;;;;-1:-1:-1;63150:654:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;70199:1208::-;;;;;;:::i;:::-;;:::i;64603:34::-;;;;;;;;;;;;;;;;64025:35;;;;;;;;;;;;;;;;30506:149;;;;;;;;;;-1:-1:-1;30506:149:0;;;;;:::i;:::-;;:::i;64452:52::-;;;;;;;;;;;;64485:19;64452:52;;64375:70;;;;;;;;;;;;64417:28;64375:70;;64320:48;;;;;;;;;;;;64364:4;64320:48;;64229:27;;;;;;;;;;;;;;;;64067:30;;;;;;;;;;-1:-1:-1;64067:30:0;;;;;;;;64644:34;;;;;;;;;;;;;;;;69097:1094;;;;;;:::i;:::-;;:::i;77371:139::-;;;;;;;;;;;;;:::i;64511:45::-;;;;;;;;;;-1:-1:-1;64511:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;67517:431;64417:28;27694:16;27705:4;27694:10;:16::i;:::-;67731:12:::1;:19;67703:17;:24;:47;67681:111;;;::::0;::::1;::::0;;17090:2:1;67681:111:0::1;::::0;::::1;17072:21:1::0;17129:2;17109:18;;;17102:30;17168:16;17148:18;;;17141:44;17202:18;;67681:111:0::1;;;;;;;;;67808:11;67803:138;67831:12;:19;67825:3;:25;67803:138;;;67912:12;67925:3;67912:17;;;;;;;;:::i;:::-;;;;;;;67874:11;:35;67886:17;67904:3;67886:22;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;67874:35;;;;::::1;::::0;;;;;;;;-1:-1:-1;67874:35:0;:55;;;;;::::1;;::::0;;::::1;;::::0;;;;::::1;::::0;-1:-1:-1;67874:55:0;::::1;::::0;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;67852:5;::::1;::::0;::::1;:::i;:::-;;;;67803:138;;;;67517:431:::0;;;:::o;27802:204::-;27887:4;27911:47;;;27926:32;27911:47;;:87;;-1:-1:-1;25234:25:0;25219:40;;;;27962:36;27904:94;27802:204;-1:-1:-1;;27802:204:0:o;71415:1165::-;56488:19;:17;:19::i;:::-;56518:17;58248:11;:19;;;;;;58136:139;56518:17;2059:19:::1;:17;:19::i;:::-;64364:4:::2;71644:11;:18;;;:38;71640:67;;;71691:16;;;;;;;;;;;;;;71640:67;71724:30;71733:11;:20;;;67478:23:::0;;64826:42;67478:23;;67398:111;71724:30:::2;71720:474;;;71797:9;71775:11;:18;;;:31;71771:59;;71815:15;;;;;;;;;;;;;;71771:59;71845:18;:26;;;71879:9;71845:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;;71941:50:0::2;71972:18;71941:50;:20;::::0;::::2;:50:::0;-1:-1:-1;71720:474:0::2;::::0;-1:-1:-1;71720:474:0::2;;72024:158;72088:10;72125:4;72149:11;:18;;;72031:11;:20;;;72024:45;;;;:158;;;;;;:::i;:::-;72211:361;72251:11;:21;;;72287:11;:18;;;72320:11;:28;;;72363:11;:22;;;72402:12;;72400:14;;;;;:::i;:::-;::::0;;;;-1:-1:-1;72429:20:0::2;::::0;::::2;::::0;72488:27:::2;::::0;::::2;::::0;72211:361:::2;::::0;::::2;::::0;;;;;72400:14;72429:20;72464:9;;72530;;72554:7;;72211:361:::2;:::i;:::-;;;;;;;;56558:20:::0;58481:4;58467:18;;;;;;;;58283:210;75676:962;75866:15;;75815:12;;75866:15;;75844:10;:38;75840:67;;75891:16;;;;;;;;;;;;;;75840:67;75962:13;;75946:31;;;;;;;:::i;:::-;;;;;;;;75922:20;;:55;75918:103;;75999:22;;;;;;;;;;;;;;75918:103;76049:17;76081:23;76119:24;76168:6;76157:51;;;;;;;;;;;;:::i;:::-;76034:174;;;;;;76219:13;76235:6;:13;76219:29;;76274:7;:14;76265:5;:23;76261:55;;76297:19;;;;;;;;;;;;;;76261:55;76334:9;76329:282;76353:5;76349:1;:9;76329:282;;;76385:19;76394:6;76401:1;76394:9;;;;;;;;:::i;:::-;;;;;;;67478:23;;64826:42;67478:23;;67398:111;76385:19;76380:219;;76423:53;76454:9;76465:7;76473:1;76465:10;;;;;;;;:::i;:::-;;;;;;;76430:6;76437:1;76430:9;;;;;;;;:::i;:::-;;;;;;;76423:30;;;;:53;;;;;:::i;:::-;76380:219;;;76568:9;76560:27;;:39;76588:7;76596:1;76588:10;;;;;;;;:::i;:::-;;;;;;;76560:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76380:219;76360:3;;;;:::i;:::-;;;;76329:282;;;-1:-1:-1;;76621:9:0;;;;;;;;;-1:-1:-1;76621:9:0;;;75676:962;-1:-1:-1;;;;;;;;;75676:962:0:o;30066:147::-;29699:7;29726:12;;;;;;;;;;:22;;;27694:16;27705:4;27694:10;:16::i;:::-;30180:25:::1;30191:4;30197:7;30180:10;:25::i;:::-;30066:147:::0;;;:::o;31210:218::-;31306:23;;;811:10;31306:23;31298:83;;;;;;;21451:2:1;31298:83:0;;;21433:21:1;21490:2;21470:18;;;21463:30;21529:34;21509:18;;;21502:62;21600:17;21580:18;;;21573:45;21635:19;;31298:83:0;21249:411:1;31298:83:0;31394:26;31406:4;31412:7;31394:11;:26::i;:::-;31210:218;;:::o;67956:1107::-;56488:19;:17;:19::i;:::-;56518:17;58248:11;:19;;;;;;58136:139;56518:17;2059:19:::1;:17;:19::i;:::-;68178:29:::2;::::0;;;:11:::2;:29;::::0;;;;:35:::2;;::::0;::::2;;:57:::0;::::2;;;-1:-1:-1::0;68217:4:0::2;::::0;:18:::2;:4;:18:::0;::::2;68178:57;68156:152;;;::::0;::::2;::::0;;21867:2:1;68156:152:0::2;::::0;::::2;21849:21:1::0;21906:2;21886:18;;;21879:30;21945:34;21925:18;;;21918:62;22016:15;21996:18;;;21989:43;22049:19;;68156:152:0::2;21665:409:1::0;68156:152:0::2;68336:29;::::0;;;:11:::2;:29;::::0;;;;:33:::2;;::::0;68323:9:::2;:46;68319:71;;68378:12;;;;;;;;;;;;;;68319:71;64364:4;68405:6;:26;68401:55;;;68440:16;;;;;;;;;;;;;;68401:55;68476:4;::::0;68469:64:::2;::::0;68476:4:::2;;68499:10;68519:4;68526:6:::0;68469:29:::2;:64::i;:::-;68587:14;::::0;68551:4:::2;::::0;68544:67:::2;::::0;68587:14:::2;68551:4:::0;;::::2;::::0;68587:14:::2;68604:6:::0;68544:34:::2;:67::i;:::-;68639:14;::::0;68624:12:::2;68704:29:::0;;;:11:::2;:29;::::0;;;;;:38;68781:4:::2;::::0;;68639:157;;;;;;;::::2;22308:25:1::0;;;68704:38:0::2;::::0;;::::2;22349:18:1::0;;;22342:51;22409:18;;;22402:34;;;68639:14:0::2;68781:4:::0;;::::2;22452:18:1::0;;;22445:83;68624:12:0;;68639:14:::2;::::0;:29:::2;::::0;22280:19:1;;68639:157:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68991:4;::::0;68866:189:::2;::::0;;23146:25:1;;;23202:2;23187:18;;23180:34;;;23230:18;;;23223:34;;;23305:18;23293:31;;23288:2;23273:18;;23266:59;68991:4:0::2;::::0;;::::2;23417:3:1::0;23402:19;;23395:44;23470:3;23455:19;;23448:35;;;69034:10:0::2;23514:3:1::0;23499:19;;23492:44;68624:172:0;;-1:-1:-1;68866:189:0::2;::::0;23133:3:1;23118:19;68866:189:0::2;;;;;;;68145:918;56558:20:::0;58481:4;58467:18;;;;;;;;58283:210;67305:85;64485:19;27694:16;27705:4;27694:10;:16::i;:::-;2318::::1;:14;:16::i;:::-;67372:10:::2;:8;:10::i;:::-;67305:85:::0;:::o;65935:768::-;64417:28;27694:16;27705:4;27694:10;:16::i;:::-;66185:5:::1;66194:1;66185:10:::0;66181:515:::1;;66212:15;:34:::0;;;::::1;;::::0;::::1;;::::0;;66181:515:::1;;;66268:5;66277:1;66268:10:::0;66264:432:::1;;66328:21;;66318:32;;;;;;;:::i;:::-;;::::0;;;;::::1;::::0;;66295:20:::1;:55:::0;66264:432:::1;;;66372:5;66381:1;66372:10:::0;66368:328:::1;;66448:19;66425;:42;;66399:173;;;::::0;::::1;::::0;;23749:2:1;66399:173:0::1;::::0;::::1;23731:21:1::0;23788:2;23768:18;;;23761:30;23827:34;23807:18;;;23800:62;23898:34;23878:18;;;23871:62;23970:7;23949:19;;;23942:36;23995:19;;66399:173:0::1;23547:473:1::0;66399:173:0::1;66587:19;:41:::0;;;66643:19:::1;:41:::0;;;66368:328:::1;65935:768:::0;;;;;;;:::o;72588:1193::-;56488:19;:17;:19::i;:::-;56518:17;58248:11;:19;;;;;;58136:139;56518:17;2059:19:::1;:17;:19::i;:::-;72756:16:::0;;64364:4:::2;-1:-1:-1::0;72752:65:0::2;;;72801:16;;;;;;;;;;;;;;72752:65;72903:16:::0;;72938:20:::2;::::0;;::::2;::::0;72977:19:::2;::::0;;::::2;::::0;73015::::2;::::0;;::::2;::::0;73053::::2;::::0;;::::2;::::0;72874:245;;;;::::2;24312:25:1::0;;;;24353:18;;;24346:34;;;;24396:18;;24389:34;24442:42;24520:15;;;24500:18;;;24493:43;24573:15;;;24552:19;;;24545:44;73099:4:0::2;24605:19:1::0;;;24598:44;72828:19:0::2;::::0;24284::1;;72874:245:0::2;::::0;;;;;::::2;::::0;;;;;;72850:280;;72874:245:::2;72850:280:::0;;::::2;::::0;73145:26:::2;::::0;;;:13:::2;:26:::0;;;;;;72850:280;;-1:-1:-1;73145:26:0::2;;73141:63;;;73180:24;;;;;;;;;;;;;;73141:63;73215:26;::::0;;;:13:::2;:26;::::0;;;;:33;;;::::2;73244:4;73215:33;::::0;;73274:19:::2;::::0;::::2;::::0;73265:29:::2;::::0;67478:23;;64826:42;67478:23;;67398:111;73265:29:::2;73261:445;;;73315:16:::0;;73335:9:::2;73315:29;73311:57;;73353:15;;;;;;;;;;;;;;73311:57;73453:19;::::0;::::2;::::0;73483:16;;73445:55:::2;::::0;:37:::2;::::0;;::::2;::::0;:55;::::2;;;::::0;73483:16;::::2;73445:55:::0;73483:16;73445:55;73483:16;73445:37;:55;::::2;;;;;;;;;;;;;::::0;::::2;;;;;;73261:445;;;73625:19;::::0;::::2;::::0;73663:16;;73540:19:::2;::::0;::::2;::::0;73533:161:::2;::::0;:44:::2;::::0;;::::2;::::0;73596:10:::2;::::0;73625:19;73533:44:::2;:161::i;:::-;73723:50;73733:11;73746:10;73760:12;;73758:14;;;;;:::i;:::-;::::0;;;;-1:-1:-1;73723:50:0::2;::::0;;24855:25:1;;;24928:42;24916:55;;;24911:2;24896:18;;24889:83;24988:18;;;24981:34;24843:2;24828:18;73723:50:0::2;;;;;;;72692:1089;56558:20:::0;58481:4;58467:18;;;;;;;;58283:210;77518:703;2059:19;:17;:19::i;:::-;77653:23:::1;::::0;::::1;;77645:63;;;::::0;::::1;::::0;;25228:2:1;77645:63:0::1;::::0;::::1;25210:21:1::0;25267:2;25247:18;;;25240:30;25306:29;25286:18;;;25279:57;25353:18;;77645:63:0::1;25026:351:1::0;77645:63:0::1;77741:19;::::0;:24;;::::1;::::0;:52:::1;;-1:-1:-1::0;77769:19:0::1;::::0;:24;::::1;77741:52;77719:124;;;::::0;::::1;::::0;;25584:2:1;77719:124:0::1;::::0;::::1;25566:21:1::0;25623:2;25603:18;;;25596:30;25662:24;25642:18;;;25635:52;25704:18;;77719:124:0::1;25382:346:1::0;77719:124:0::1;77889:19;;77876:9;:32;;:85;;;;;77942:19;;77929:9;:32;;77876:85;77854:160;;;::::0;::::1;::::0;;25935:2:1;77854:160:0::1;::::0;::::1;25917:21:1::0;25974:2;25954:18;;;25947:30;26013:27;25993:18;;;25986:55;26058:18;;77854:160:0::1;25733:349:1::0;77854:160:0::1;78025:28;78076:9;78056:17;;:29;;;;:::i;:::-;78096:17;:40:::0;;;78025:60;-1:-1:-1;78149:8:0::1;:6;:8::i;:::-;78175:38;::::0;78203:9:::1;9513:25:1::0;;78191:10:0::1;::::0;78175:38:::1;::::0;9501:2:1;9486:18;78175:38:0::1;;;;;;;77575:646;77518:703::o:0;73789:1879::-;56488:19;:17;:19::i;:::-;56518:17;58248:11;:19;;;;;;58136:139;56518:17;2059:19:::1;:17;:19::i;:::-;73922:16:::0;;64364:4:::2;-1:-1:-1::0;73918:65:0::2;;;73967:16;;;;;;;;;;;;;;73918:65;74120:16:::0;;74155:20:::2;::::0;;::::2;::::0;74194:19:::2;::::0;;::::2;::::0;74232::::2;::::0;::::2;::::0;74270::::2;::::0;::::2;::::0;74340:17:::2;::::0;::::2;::::0;74091:281;;74045:19:::2;::::0;74091:281:::2;::::0;74120:16;;74155:20;74316:4:::2;::::0;74340:17;;74091:281:::2;;:::i;:::-;;::::0;;;;;::::2;::::0;;;;;;74067:316;;74091:281:::2;74067:316:::0;;::::2;::::0;74398:26:::2;::::0;;;:13:::2;:26:::0;;;;;;74067:316;;-1:-1:-1;74398:26:0::2;;74394:63;;;74433:24;;;;;;;;;;;;;;74394:63;74468:26;::::0;;;:13:::2;:26;::::0;;;;:33;;;::::2;74497:4;74468:33;::::0;;74527:19:::2;::::0;::::2;::::0;74518:29:::2;::::0;67478:23;;64826:42;67478:23;;67398:111;74518:29:::2;74514:383;;;74568:16:::0;;74588:9:::2;74568:29;74564:57;;74606:15;;;;;;;;;;;;;;74564:57;74644:19;::::0;::::2;::::0;74674:16;;74636:55:::2;::::0;:37:::2;::::0;;::::2;::::0;:55;::::2;;;::::0;74674:16;::::2;74636:55:::0;74674:16;74636:55;74674:16;74636:37;:55;::::2;;;;;;;;;;;;;::::0;::::2;;;;;;74514:383;;;74816:19;::::0;::::2;::::0;74854:16;;74731:19:::2;::::0;::::2;::::0;74724:161:::2;::::0;:44:::2;::::0;;::::2;::::0;74787:10:::2;::::0;74816:19;74724:44:::2;:161::i;:::-;74909:21;74941:13;74969:31;74980:9;:19;;;76775:17:::0;76820:8;;;76646:190;74969:31:::2;:63;;;;;75031:1;75004:9;:17;;;:24;:28;74969:63;74965:523;;;75072:9;:19;;;:24;;75160:38;;;75221:9;:19;;;75263:9;:16;;;75302:9;:17;;;75115:223;;;;;;;;;;:::i;:::-;;::::0;;;;;::::2;::::0;;;;;;::::2;::::0;::::2;::::0;;::::2;;::::0;;;::::2;::::0;;;::::2;::::0;;;75072:281;;::::2;::::0;75115:223;75072:281:::2;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;75049:304:0;-1:-1:-1;75049:304:0;-1:-1:-1;75372:9:0;::::2;:43:::0;::::2;;;;75397:18;;75385:9;:30;75372:43;75368:108;;;75441:35;;;;;;;;;;;;;;75368:108;75503:157;75538:11;75564:10;75591:12;;75589:14;;;;;:::i;:::-;::::0;;;;-1:-1:-1;75503:157:0::2;::::0;::::2;::::0;;;75589:14;75618:8;;75641;;75503:157:::2;:::i;:::-;;;;;;;;73907:1761;;;56558:20:::0;58481:4;58467:18;;;;;;;;58283:210;66899:174;64417:28;27694:16;27705:4;27694:10;:16::i;:::-;-1:-1:-1;67016:14:0::1;:49:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;66899:174::o;76988:375::-;27248:4;27694:16;27248:4;27694:10;:16::i;:::-;56488:19:::1;:17;:19::i;:::-;56518:17;58248:11:::0;:19;;;;;;58136:139;56518:17:::1;64826:42:::0;67478:23;;;;77097:259:::2;;77133:51;::::0;77141:10:::2;::::0;77162:21:::2;77133:51:::0;::::2;;;::::0;::::2;::::0;;;77162:21;77141:10;77133:51;::::2;;;;;;;;;;;;;::::0;::::2;;;;;;77097:259;;;77291:38;::::0;;;;77323:4:::2;77291:38;::::0;::::2;7009:74:1::0;77217:127:0::2;::::0;77262:10:::2;::::0;77291:23:::2;::::0;::::2;::::0;::::2;::::0;6982:18:1;;77291:38:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77217:26;::::0;::::2;::::0;:127;:26:::2;:127::i;:::-;56558:20:::1;58481:4:::0;58467:18;;;;;;;;58283:210;67081:84;64485:19;27694:16;27705:4;27694:10;:16::i;:::-;2059:19:::1;:17;:19::i;:::-;67149:8:::2;:6;:8::i;78229:342::-:0;27248:4;27694:16;27248:4;27694:10;:16::i;:::-;78356:17:::1;;78331:21;:42;;78309:110;;;::::0;::::1;::::0;;28622:2:1;78309:110:0::1;::::0;::::1;28604:21:1::0;28661:2;28641:18;;;28634:30;28700:20;28680:18;;;28673:48;28738:18;;78309:110:0::1;28420:342:1::0;78309:110:0::1;78457:17;::::0;;78430:24:::1;78485:21:::0;;;;78517:46:::1;::::0;78457:17;;78525:10:::1;::::0;78517:46;::::1;;;::::0;78457:17;;78517:46;;78430:24;78517:46;78457:17;78525:10;78517:46;::::1;;;;;;;;;;;;;::::0;::::1;;;;63150:654:::0;63210:22;63267:4;63255:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63245:34;;63295:9;63290:507;63310:15;;;63290:507;;;63348:12;;63393:4;63412;;63417:1;63412:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;63385:35;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63347:73;;;;63442:7;63437:313;;63571:2;63555:6;:13;:18;63551:32;;;63575:8;;;63551:32;63656:4;63648:6;63644:17;63634:27;;63716:6;63705:28;;;;;;;;;;;;:::i;:::-;63698:36;;;;;;;;;;;:::i;63437:313::-;63779:6;63766:7;63774:1;63766:10;;;;;;;;:::i;:::-;;;;;;:19;;;;63332:465;;63327:3;;;;;:::i;:::-;;;;63290:507;;;;63150:654;;;;:::o;70199:1208::-;56488:19;:17;:19::i;:::-;56518:17;58248:11;:19;;;;;;58136:139;56518:17;2059:19:::1;:17;:19::i;:::-;70410:18:::2;70406:306;;;70452:9;:14:::0;70445:22:::2;;;;:::i;:::-;70487:192;70523:8;70550:1;70570:9;70600:12;;70598:14;;;;;:::i;:::-;::::0;;;;-1:-1:-1;70487:192:0::2;::::0;;30717:42:1;30786:15;;;30768:34;;30833:2;30818:18;;30811:34;;;;30861:18;;;30854:34;30919:2;30904:18;;30897:34;70631:4:0::2;30962:3:1::0;30947:19;;30940:51;70654:10:0::2;31022:3:1::0;31007:19;;31000:44;30694:3;30679:19;70487:192:0::2;;;;;;;70694:7;;70406:306;64364:4;70726:9;:29;70722:58;;;70764:16;;;;;;;;;;;;;;70722:58;64826:42:::0;67478:23;;;;70791:420:::2;;70847:9;70834;:22;70830:50;;70865:15;;;;;;;;;;;;;;70830:50;70895:18;:26;;;70929:9;70895:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;71010:18;70991:38;;70791:420;;;71062:137;:33;::::0;::::2;71114:10;71151:4;71175:9:::0;71062:33:::2;:137::i;:::-;71226:173;71258:8;71281:9;71305;71331:12;;71329:14;;;;;:::i;:::-;::::0;;;;-1:-1:-1;71226:173:0::2;::::0;;30717:42:1;30786:15;;;30768:34;;30833:2;30818:18;;30811:34;;;;30861:18;;;30854:34;30919:2;30904:18;;30897:34;71358:5:0::2;30962:3:1::0;30947:19;;30940:51;71378:10:0::2;31022:3:1::0;31007:19;;31000:44;30694:3;30679:19;71226:173:0::2;30418:632:1::0;2089:1:0::2;56558:20:::0;58481:4;58467:18;;;;;;;;58283:210;30506:149;29699:7;29726:12;;;;;;;;;;:22;;;27694:16;27705:4;27694:10;:16::i;:::-;30621:26:::1;30633:4;30639:7;30621:11;:26::i;69097:1094::-:0;56488:19;:17;:19::i;:::-;56518:17;58248:11;:19;;;;;;58136:139;56518:17;2059:19:::1;:17;:19::i;:::-;64364:4:::2;69288:11;:18;;;:38;69284:67;;;69335:16;;;;;;;;;;;;;;69284:67;69368:30;69377:11;:20;;;67478:23:::0;;64826:42;67478:23;;67398:111;69368:30:::2;69364:474;;;69441:9;69419:11;:18;;;:31;69415:59;;69459:15;;;;;;;;;;;;;;69415:59;69489:18;:26;;;69523:9;69489:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;;69585:50:0::2;69616:18;69585:50;:20;::::0;::::2;:50:::0;-1:-1:-1;69364:474:0::2;::::0;-1:-1:-1;69364:474:0::2;;69668:158;69732:10;69769:4;69793:11;:18;;;69675:11;:20;;;69668:45;;;;:158;;;;;;:::i;:::-;69855:328;69884:11;:21;;;69920:11;:18;;;69953:11;:28;;;69996:11;:22;;;70035:12;;70033:14;;;;;:::i;:::-;::::0;;;;-1:-1:-1;70062:20:0::2;::::0;::::2;::::0;70097:27:::2;::::0;::::2;::::0;69855:328:::2;::::0;::::2;::::0;;;;;70033:14;70062:20;70097:27;70139:9;;70163;;69855:328:::2;:::i;:::-;;;;;;;;56558:20:::0;58481:4;58467:18;;;;;;;;58283:210;77371:139;27248:4;27694:16;27248:4;27694:10;:16::i;:::-;-1:-1:-1;77479:23:0::1;::::0;;77452:50;;::::1;77479:23;::::0;;::::1;77478:24;77452:50;::::0;;77371:139::o;28549:105::-;28616:30;28627:4;811:10;28616;:30::i;57939:189::-;58073:11;;;;58065:55;;;;;;;32871:2:1;58065:55:0;;;32853:21:1;32910:2;32890:18;;;32883:30;32949:33;32929:18;;;32922:61;33000:18;;58065:55:0;32669:355:1;58065:55:0;57939:189::o;2613:108::-;2525:7;;;;;;;2683:9;2675:38;;;;;;;33231:2:1;2675:38:0;;;33213:21:1;33270:2;33250:18;;;33243:30;33309:18;33289;;;33282:46;33345:18;;2675:38:0;33029:340:1;49262:205:0;49390:68;;33586:42:1;33655:15;;;49390:68:0;;;33637:34:1;33707:15;;33687:18;;;33680:43;33739:18;;;33732:34;;;49363:96:0;;49383:5;;49413:27;;33549:18:1;;49390:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49363:19;:96::i;48840:177::-;48950:58;;33981:42:1;33969:55;;48950:58:0;;;33951:74:1;34041:18;;;34034:34;;;48923:86:0;;48943:5;;48973:23;;33924:18:1;;48950:58:0;33777:297:1;32807:238:0;28184:4;28208:12;;;;;;;;;;;:29;;;;;;;;;;;;;32886:152;;32930:6;:12;;;;;;;;;;;:29;;;;;;;;;;:36;;;;32962:4;32930:36;;;33013:12;811:10;;731:98;33013:12;32986:40;;33004:7;32986:40;;32998:4;32986:40;;;;;;;;;;32807:238;;:::o;33225:239::-;28184:4;28208:12;;;;;;;;;;;:29;;;;;;;;;;;;;33305:152;;;33380:5;33348:12;;;;;;;;;;;:29;;;;;;;;;;;:37;;;;;;33405:40;811:10;;33348:12;;33405:40;;33380:5;33405:40;33225:239;;:::o;50515:283::-;50635:39;;;;;50659:4;50635:39;;;34314:34:1;50635:15:0;34384::1;;;34364:18;;;34357:43;50612:20:0;;50635:15;;;;;;34226:18:1;;50635:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50612:62;-1:-1:-1;50685:105:0;50705:5;50735:22;50759:7;50768:20;50783:5;50612:62;50768:20;:::i;:::-;50712:77;;33981:42:1;33969:55;;;50712:77:0;;;33951:74:1;34041:18;;;34034:34;33924:18;;50712:77:0;33777:297:1;2798:108:0;2525:7;;;;;;;2857:41;;;;;;;34613:2:1;2857:41:0;;;34595:21:1;34652:2;34632:18;;;34625:30;34691:22;34671:18;;;34664:50;34731:18;;2857:41:0;34411:344:1;3309:120:0;2318:16;:14;:16::i;:::-;3368:7:::1;:15:::0;;;::::1;::::0;;3399:22:::1;811:10:::0;3408:12:::1;3399:22;::::0;7039:42:1;7027:55;;;7009:74;;6997:2;6982:18;3399:22:0::1;;;;;;;3309:120::o:0;3050:118::-;2059:19;:17;:19::i;:::-;3120:4:::1;3110:14:::0;;;::::1;;;::::0;;3140:20:::1;3147:12;811:10:::0;;731:98;28944:492;28184:4;28208:12;;;;;;;;;;;:29;;;;;;;;;;;;;29028:401;;29221:28;29241:7;29221:19;:28::i;:::-;29322:38;29350:4;29357:2;29322:19;:38::i;:::-;29126:257;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;29072:345;;;;;;;;:::i;53186:649::-;53610:23;53636:69;53664:4;53636:69;;;;;;;;;;;;;;;;;53644:5;53636:27;;;;:69;;;;;:::i;:::-;53610:95;;53724:10;:17;53745:1;53724:22;:56;;;;53761:10;53750:30;;;;;;;;;;;;:::i;:::-;53716:111;;;;;;;36029:2:1;53716:111:0;;;36011:21:1;36068:2;36048:18;;;36041:30;36107:34;36087:18;;;36080:62;36178:12;36158:18;;;36151:40;36208:19;;53716:111:0;35827:406:1;23137:151:0;23195:13;23228:52;23240:22;;;21012:2;22533:447;22608:13;22634:19;22666:10;22670:6;22666:1;:10;:::i;:::-;:14;;22679:1;22666:14;:::i;:::-;22656:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22656:25:0;;22634:47;;22692:15;:6;22699:1;22692:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;;22718;:6;22725:1;22718:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;-1:-1:-1;22749:9:0;22761:10;22765:6;22761:1;:10;:::i;:::-;:14;;22774:1;22761:14;:::i;:::-;22749:26;;22744:131;22781:1;22777;:5;22744:131;;;22816:8;22825:5;22833:3;22825:11;22816:21;;;;;;;:::i;:::-;;;;22804:6;22811:1;22804:9;;;;;;;;:::i;:::-;;;;:33;;;;;;;;;;-1:-1:-1;22862:1:0;22852:11;;;;;22784:3;;;:::i;:::-;;;22744:131;;;-1:-1:-1;22893:10:0;;22885:55;;;;;;;36814:2:1;22885:55:0;;;36796:21:1;;;36833:18;;;36826:30;36892:34;36872:18;;;36865:62;36944:18;;22885:55:0;36612:356:1;22885:55:0;22965:6;22533:447;-1:-1:-1;;;22533:447:0:o;42722:229::-;42859:12;42891:52;42913:6;42921:4;42927:1;42930:12;42891:21;:52::i;:::-;42884:59;42722:229;-1:-1:-1;;;;42722:229:0:o;43808:455::-;43978:12;44036:5;44011:21;:30;;44003:81;;;;;;;37175:2:1;44003:81:0;;;37157:21:1;37214:2;37194:18;;;37187:30;37253:34;37233:18;;;37226:62;37324:8;37304:18;;;37297:36;37350:19;;44003:81:0;36973:402:1;44003:81:0;44096:12;44110:23;44137:6;:11;;44156:5;44163:4;44137:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44095:73;;;;44186:69;44213:6;44221:7;44230:10;44242:12;44186:26;:69::i;:::-;44179:76;43808:455;-1:-1:-1;;;;;;;43808:455:0:o;46381:644::-;46566:12;46595:7;46591:427;;;46623:10;:17;46644:1;46623:22;46619:290;;40262:19;;;;46833:60;;;;;;;37582:2:1;46833:60:0;;;37564:21:1;37621:2;37601:18;;;37594:30;37660:31;37640:18;;;37633:59;37709:18;;46833:60:0;37380:353:1;46833:60:0;-1:-1:-1;46930:10:0;46923:17;;46591:427;46973:33;46981:10;46993:12;47728:17;;:21;47724:388;;47960:10;47954:17;48017:15;48004:10;48000:2;47996:19;47989:44;47724:388;48087:12;48080:20;;;;;;;;;;;:::i;14:184:1:-;66:77;63:1;56:88;163:4;160:1;153:15;187:4;184:1;177:15;203:253;275:2;269:9;317:4;305:17;;352:18;337:34;;373:22;;;334:62;331:88;;;399:18;;:::i;:::-;435:2;428:22;203:253;:::o;461:::-;533:2;527:9;575:4;563:17;;610:18;595:34;;631:22;;;592:62;589:88;;;657:18;;:::i;719:334::-;790:2;784:9;846:2;836:13;;851:66;832:86;820:99;;949:18;934:34;;970:22;;;931:62;928:88;;;996:18;;:::i;:::-;1032:2;1025:22;719:334;;-1:-1:-1;719:334:1:o;1058:183::-;1118:4;1151:18;1143:6;1140:30;1137:56;;;1173:18;;:::i;:::-;-1:-1:-1;1218:1:1;1214:14;1230:4;1210:25;;1058:183::o;1246:118::-;1332:5;1325:13;1318:21;1311:5;1308:32;1298:60;;1354:1;1351;1344:12;1369:1315;1434:5;1487:3;1480:4;1472:6;1468:17;1464:27;1454:55;;1505:1;1502;1495:12;1454:55;1541:6;1528:20;1567:4;1591:60;1607:43;1647:2;1607:43;:::i;:::-;1591:60;:::i;:::-;1685:15;;;1747:4;1790:11;;;1778:24;;1774:33;;;1716:12;;;;1673:3;1819:15;;;1816:35;;;1847:1;1844;1837:12;1816:35;1883:2;1875:6;1871:15;1895:760;1911:6;1906:3;1903:15;1895:760;;;1987:2;1981:3;1976;1972:13;1968:22;1965:112;;;2031:1;2060:2;2056;2049:14;1965:112;2103:22;;:::i;:::-;2166:3;2153:17;2218:10;2209:7;2205:24;2196:7;2193:37;2183:135;;2272:1;2301:2;2297;2290:14;2183:135;2331:22;;2402:12;;;2389:26;2373:14;;;2366:50;2439:2;2482:12;;;2469:26;2508:30;2469:26;2508:30;:::i;:::-;2558:14;;;2551:31;2595:18;;2633:12;;;;1928;;1895:760;;;-1:-1:-1;2673:5:1;;1369:1315;-1:-1:-1;;;;;;;1369:1315:1:o;2689:1180::-;2836:6;2844;2897:2;2885:9;2876:7;2872:23;2868:32;2865:52;;;2913:1;2910;2903:12;2865:52;2953:9;2940:23;2982:18;3023:2;3015:6;3012:14;3009:34;;;3039:1;3036;3029:12;3009:34;3077:6;3066:9;3062:22;3052:32;;3122:7;3115:4;3111:2;3107:13;3103:27;3093:55;;3144:1;3141;3134:12;3093:55;3180:2;3167:16;3202:4;3226:60;3242:43;3282:2;3242:43;:::i;3226:60::-;3320:15;;;3402:1;3398:10;;;;3390:19;;3386:28;;;3351:12;;;;3426:19;;;3423:39;;;3458:1;3455;3448:12;3423:39;3482:11;;;;3502:142;3518:6;3513:3;3510:15;3502:142;;;3584:17;;3572:30;;3535:12;;;;3622;;;;3502:142;;;3663:5;-1:-1:-1;;3706:18:1;;3693:32;;-1:-1:-1;;3737:16:1;;;3734:36;;;3766:1;3763;3756:12;3734:36;;3789:74;3855:7;3844:8;3833:9;3829:24;3789:74;:::i;:::-;3779:84;;;2689:1180;;;;;:::o;3874:332::-;3932:6;3985:2;3973:9;3964:7;3960:23;3956:32;3953:52;;;4001:1;3998;3991:12;3953:52;4040:9;4027:23;4090:66;4083:5;4079:78;4072:5;4069:89;4059:117;;4172:1;4169;4162:12;4403:154;4489:42;4482:5;4478:54;4471:5;4468:65;4458:93;;4547:1;4544;4537:12;4562:696;4620:5;4668:4;4656:9;4651:3;4647:19;4643:30;4640:50;;;4686:1;4683;4676:12;4640:50;4708:22;;:::i;:::-;4699:31;;4766:9;4753:23;4746:5;4739:38;4837:2;4826:9;4822:18;4809:32;4804:2;4797:5;4793:14;4786:56;4902:2;4891:9;4887:18;4874:32;4869:2;4862:5;4858:14;4851:56;4959:2;4948:9;4944:18;4931:32;4972:33;4997:7;4972:33;:::i;:::-;5032:2;5021:14;;5014:31;5097:3;5082:19;;5069:33;5111;5069;5111;:::i;:::-;5177:7;5171:3;5164:5;5160:15;5153:32;;5246:3;5235:9;5231:19;5218:33;5212:3;5205:5;5201:15;5194:58;4562:696;;;;:::o;5263:245::-;5311:4;5344:18;5336:6;5333:30;5330:56;;;5366:18;;:::i;:::-;-1:-1:-1;5423:2:1;5411:15;5428:66;5407:88;5497:4;5403:99;;5263:245::o;5513:462::-;5555:5;5608:3;5601:4;5593:6;5589:17;5585:27;5575:55;;5626:1;5623;5616:12;5575:55;5662:6;5649:20;5693:48;5709:31;5737:2;5709:31;:::i;5693:48::-;5766:2;5757:7;5750:19;5812:3;5805:4;5800:2;5792:6;5788:15;5784:26;5781:35;5778:55;;;5829:1;5826;5819:12;5778:55;5894:2;5887:4;5879:6;5875:17;5868:4;5859:7;5855:18;5842:55;5942:1;5917:16;;;5935:4;5913:27;5906:38;;;;5921:7;5513:462;-1:-1:-1;;;5513:462:1:o;5980:864::-;6122:6;6130;6138;6146;6199:3;6187:9;6178:7;6174:23;6170:33;6167:53;;;6216:1;6213;6206:12;6167:53;6239:49;6280:7;6269:9;6239:49;:::i;:::-;6229:59;;6339:3;6328:9;6324:19;6311:33;6363:18;6404:2;6396:6;6393:14;6390:34;;;6420:1;6417;6410:12;6390:34;6443:49;6484:7;6475:6;6464:9;6460:22;6443:49;:::i;:::-;6433:59;;6545:3;6534:9;6530:19;6517:33;6501:49;;6575:2;6565:8;6562:16;6559:36;;;6591:1;6588;6581:12;6559:36;6614:51;6657:7;6646:8;6635:9;6631:24;6614:51;:::i;:::-;6604:61;;6718:3;6707:9;6703:19;6690:33;6674:49;;6748:2;6738:8;6735:16;6732:36;;;6764:1;6761;6754:12;6732:36;;6787:51;6830:7;6819:8;6808:9;6804:24;6787:51;:::i;:::-;6777:61;;;5980:864;;;;;;;:::o;7094:348::-;7146:8;7156:6;7210:3;7203:4;7195:6;7191:17;7187:27;7177:55;;7228:1;7225;7218:12;7177:55;-1:-1:-1;7251:20:1;;7294:18;7283:30;;7280:50;;;7326:1;7323;7316:12;7280:50;7363:4;7355:6;7351:17;7339:29;;7415:3;7408:4;7399:6;7391;7387:19;7383:30;7380:39;7377:59;;;7432:1;7429;7422:12;7377:59;7094:348;;;;;:::o;7447:919::-;7557:6;7565;7573;7581;7589;7642:2;7630:9;7621:7;7617:23;7613:32;7610:52;;;7658:1;7655;7648:12;7610:52;7698:9;7685:23;7727:18;7768:2;7760:6;7757:14;7754:34;;;7784:1;7781;7774:12;7754:34;7823:59;7874:7;7865:6;7854:9;7850:22;7823:59;:::i;:::-;7901:8;;-1:-1:-1;7797:85:1;-1:-1:-1;7989:2:1;7974:18;;7961:32;;-1:-1:-1;8005:16:1;;;8002:36;;;8034:1;8031;8024:12;8002:36;8057:51;8100:7;8089:8;8078:9;8074:24;8057:51;:::i;:::-;8047:61;;8161:2;8150:9;8146:18;8133:32;8117:48;;8190:2;8180:8;8177:16;8174:36;;;8206:1;8203;8196:12;8174:36;;8245:61;8298:7;8287:8;8276:9;8272:24;8245:61;:::i;:::-;7447:919;;;;-1:-1:-1;7447:919:1;;-1:-1:-1;8325:8:1;;8219:87;7447:919;-1:-1:-1;;;7447:919:1:o;8371:250::-;8456:1;8466:113;8480:6;8477:1;8474:13;8466:113;;;8556:11;;;8550:18;8537:11;;;8530:39;8502:2;8495:10;8466:113;;;-1:-1:-1;;8613:1:1;8595:16;;8588:27;8371:250::o;8626:329::-;8667:3;8705:5;8699:12;8732:6;8727:3;8720:19;8748:76;8817:6;8810:4;8805:3;8801:14;8794:4;8787:5;8783:16;8748:76;:::i;:::-;8869:2;8857:15;8874:66;8853:88;8844:98;;;;8944:4;8840:109;;8626:329;-1:-1:-1;;8626:329:1:o;8960:217::-;9107:2;9096:9;9089:21;9070:4;9127:44;9167:2;9156:9;9152:18;9144:6;9127:44;:::i;9182:180::-;9241:6;9294:2;9282:9;9273:7;9269:23;9265:32;9262:52;;;9310:1;9307;9300:12;9262:52;-1:-1:-1;9333:23:1;;9182:180;-1:-1:-1;9182:180:1:o;9549:315::-;9617:6;9625;9678:2;9666:9;9657:7;9653:23;9649:32;9646:52;;;9694:1;9691;9684:12;9646:52;9730:9;9717:23;9707:33;;9790:2;9779:9;9775:18;9762:32;9803:31;9828:5;9803:31;:::i;:::-;9853:5;9843:15;;;9549:315;;;;;:::o;9869:385::-;9955:6;9963;9971;9979;10032:3;10020:9;10011:7;10007:23;10003:33;10000:53;;;10049:1;10046;10039:12;10000:53;-1:-1:-1;;10072:23:1;;;10142:2;10127:18;;10114:32;;-1:-1:-1;10193:2:1;10178:18;;10165:32;;10244:2;10229:18;10216:32;;-1:-1:-1;9869:385:1;-1:-1:-1;9869:385:1:o;10927:751::-;11033:6;11041;11049;11057;11065;11073;11126:3;11114:9;11105:7;11101:23;11097:33;11094:53;;;11143:1;11140;11133:12;11094:53;11179:9;11166:23;11156:33;;11239:2;11228:9;11224:18;11211:32;11252:31;11277:5;11252:31;:::i;:::-;11302:5;-1:-1:-1;11358:2:1;11343:18;;11330:32;11385:18;11374:30;;11371:50;;;11417:1;11414;11407:12;11371:50;11456:59;11507:7;11498:6;11487:9;11483:22;11456:59;:::i;:::-;10927:751;;;;-1:-1:-1;11534:8:1;11616:2;11601:18;;11588:32;;11667:3;11652:19;;;11639:33;;-1:-1:-1;10927:751:1;-1:-1:-1;;;;10927:751:1:o;11683:848::-;11769:6;11822:3;11810:9;11801:7;11797:23;11793:33;11790:53;;;11839:1;11836;11829:12;11790:53;11872:2;11866:9;11914:3;11906:6;11902:16;11984:6;11972:10;11969:22;11948:18;11936:10;11933:34;11930:62;11927:88;;;11995:18;;:::i;:::-;12035:10;12031:2;12024:22;;12083:9;12070:23;12062:6;12055:39;12155:2;12144:9;12140:18;12127:32;12122:2;12114:6;12110:15;12103:57;12221:2;12210:9;12206:18;12193:32;12188:2;12180:6;12176:15;12169:57;12276:2;12265:9;12261:18;12248:32;12289:31;12314:5;12289:31;:::i;:::-;12348:2;12336:15;;12329:30;12411:3;12396:19;;12383:33;12425;12383;12425;:::i;:::-;12486:3;12474:16;;12467:33;12478:6;11683:848;-1:-1:-1;;;11683:848:1:o;12536:1057::-;12629:6;12682:2;12670:9;12661:7;12657:23;12653:32;12650:52;;;12698:1;12695;12688:12;12650:52;12738:9;12725:23;12767:18;12808:2;12800:6;12797:14;12794:34;;;12824:1;12821;12814:12;12794:34;12847:22;;;;12903:4;12885:16;;;12881:27;12878:47;;;12921:1;12918;12911:12;12878:47;12947:22;;:::i;:::-;13005:2;12992:16;12985:5;12978:31;13062:2;13058;13054:11;13041:25;13036:2;13029:5;13025:14;13018:49;13120:2;13116;13112:11;13099:25;13094:2;13087:5;13083:14;13076:49;13170:2;13166;13162:11;13149:25;13183:33;13208:7;13183:33;:::i;:::-;13243:2;13232:14;;13225:31;13301:3;13293:12;;13280:26;13315:33;13280:26;13315:33;:::i;:::-;13375:3;13364:15;;13357:32;13435:3;13427:12;;13414:26;13452:16;;;13449:36;;;13481:1;13478;13471:12;13449:36;13518:44;13554:7;13543:8;13539:2;13535:17;13518:44;:::i;:::-;13512:3;13501:15;;13494:69;-1:-1:-1;13505:5:1;12536:1057;-1:-1:-1;;;;;12536:1057:1:o;13598:247::-;13657:6;13710:2;13698:9;13689:7;13685:23;13681:32;13678:52;;;13726:1;13723;13716:12;13678:52;13765:9;13752:23;13784:31;13809:5;13784:31;:::i;14199:626::-;14296:6;14304;14357:2;14345:9;14336:7;14332:23;14328:32;14325:52;;;14373:1;14370;14363:12;14325:52;14413:9;14400:23;14442:18;14483:2;14475:6;14472:14;14469:34;;;14499:1;14496;14489:12;14469:34;14537:6;14526:9;14522:22;14512:32;;14582:7;14575:4;14571:2;14567:13;14563:27;14553:55;;14604:1;14601;14594:12;14553:55;14644:2;14631:16;14670:2;14662:6;14659:14;14656:34;;;14686:1;14683;14676:12;14656:34;14739:7;14734:2;14724:6;14721:1;14717:14;14713:2;14709:23;14705:32;14702:45;14699:65;;;14760:1;14757;14750:12;14699:65;14791:2;14783:11;;;;;14813:6;;-1:-1:-1;14199:626:1;;-1:-1:-1;;;;14199:626:1:o;14830:859::-;14990:4;15019:2;15059;15048:9;15044:18;15089:2;15078:9;15071:21;15112:6;15147;15141:13;15178:6;15170;15163:22;15216:2;15205:9;15201:18;15194:25;;15278:2;15268:6;15265:1;15261:14;15250:9;15246:30;15242:39;15228:53;;15316:2;15308:6;15304:15;15337:1;15347:313;15361:6;15358:1;15355:13;15347:313;;;15450:66;15438:9;15430:6;15426:22;15422:95;15417:3;15410:108;15541:39;15573:6;15564;15558:13;15541:39;:::i;:::-;15531:49;-1:-1:-1;15638:12:1;;;;15603:15;;;;15383:1;15376:9;15347:313;;;-1:-1:-1;15677:6:1;;14830:859;-1:-1:-1;;;;;;;14830:859:1:o;15694:519::-;15777:6;15785;15793;15801;15854:3;15842:9;15833:7;15829:23;15825:33;15822:53;;;15871:1;15868;15861:12;15822:53;15910:9;15897:23;15929:31;15954:5;15929:31;:::i;:::-;15979:5;-1:-1:-1;16031:2:1;16016:18;;16003:32;;-1:-1:-1;16082:2:1;16067:18;;16054:32;;-1:-1:-1;16138:2:1;16123:18;;16110:32;16151:30;16110:32;16151:30;:::i;:::-;15694:519;;;;-1:-1:-1;15694:519:1;;-1:-1:-1;;15694:519:1:o;16218:665::-;16342:6;16350;16358;16411:3;16399:9;16390:7;16386:23;16382:33;16379:53;;;16428:1;16425;16418:12;16379:53;16451:49;16492:7;16481:9;16451:49;:::i;:::-;16441:59;;16551:3;16540:9;16536:19;16523:33;16575:18;16616:2;16608:6;16605:14;16602:34;;;16632:1;16629;16622:12;16602:34;16655:49;16696:7;16687:6;16676:9;16672:22;16655:49;:::i;:::-;16645:59;;16757:3;16746:9;16742:19;16729:33;16713:49;;16787:2;16777:8;16774:16;16771:36;;;16803:1;16800;16793:12;16771:36;;16826:51;16869:7;16858:8;16847:9;16843:24;16826:51;:::i;:::-;16816:61;;;16218:665;;;;;:::o;17231:184::-;17283:77;17280:1;17273:88;17380:4;17377:1;17370:15;17404:4;17401:1;17394:15;17420:184;17472:77;17469:1;17462:88;17569:4;17566:1;17559:15;17593:4;17590:1;17583:15;17609:195;17648:3;17679:66;17672:5;17669:77;17666:103;;17749:18;;:::i;:::-;-1:-1:-1;17796:1:1;17785:13;;17609:195::o;17809:1141::-;18207:4;18236:3;18266:6;18255:9;18248:25;18309:6;18304:2;18293:9;18289:18;18282:34;18352:6;18347:2;18336:9;18332:18;18325:34;18395:6;18390:2;18379:9;18375:18;18368:34;18439:6;18433:3;18422:9;18418:19;18411:35;18465:42;18556:2;18548:6;18544:15;18538:3;18527:9;18523:19;18516:44;18597:2;18591:3;18580:9;18576:19;18569:31;18623:44;18663:2;18652:9;18648:18;18640:6;18623:44;:::i;:::-;18704:15;;;18698:3;18683:19;;18676:44;18757:22;;;18751:3;18736:19;;18729:51;18609:58;-1:-1:-1;18803:32:1;18609:58;18820:6;18803:32;:::i;:::-;18789:46;;18884:9;18876:6;18872:22;18866:3;18855:9;18851:19;18844:51;18912:32;18937:6;18929;18912:32;:::i;:::-;18904:40;17809:1141;-1:-1:-1;;;;;;;;;;;;;17809:1141:1:o;18955:271::-;19138:6;19130;19125:3;19112:33;19094:3;19164:16;;19189:13;;;19164:16;18955:271;-1:-1:-1;18955:271:1:o;19231:659::-;19296:5;19349:3;19342:4;19334:6;19330:17;19326:27;19316:55;;19367:1;19364;19357:12;19316:55;19396:6;19390:13;19422:4;19446:60;19462:43;19502:2;19462:43;:::i;19446:60::-;19540:15;;;19626:1;19622:10;;;;19610:23;;19606:32;;;19571:12;;;;19650:15;;;19647:35;;;19678:1;19675;19668:12;19647:35;19714:2;19706:6;19702:15;19726:135;19742:6;19737:3;19734:15;19726:135;;;19808:10;;19796:23;;19839:12;;;;19759;;19726:135;;;-1:-1:-1;19879:5:1;19231:659;-1:-1:-1;;;;;;19231:659:1:o;19895:1349::-;20041:6;20049;20057;20110:2;20098:9;20089:7;20085:23;20081:32;20078:52;;;20126:1;20123;20116:12;20078:52;20158:9;20152:16;20177:31;20202:5;20177:31;:::i;:::-;20227:5;20217:15;;;20251:2;20297;20286:9;20282:18;20276:25;20320:18;20361:2;20353:6;20350:14;20347:34;;;20377:1;20374;20367:12;20347:34;20415:6;20404:9;20400:22;20390:32;;20460:7;20453:4;20449:2;20445:13;20441:27;20431:55;;20482:1;20479;20472:12;20431:55;20511:2;20505:9;20534:60;20550:43;20590:2;20550:43;:::i;20534:60::-;20628:15;;;20710:1;20706:10;;;;20698:19;;20694:28;;;20659:12;;;;20734:19;;;20731:39;;;20766:1;20763;20756:12;20731:39;20790:11;;;;20810:216;20826:6;20821:3;20818:15;20810:216;;;20901:3;20895:10;20918:33;20943:7;20918:33;:::i;:::-;20964:20;;20843:12;;;;21004;;;;20810:216;;;21096:2;21081:18;;21075:25;21045:5;;-1:-1:-1;21075:25:1;-1:-1:-1;;;21112:16:1;;;21109:36;;;21141:1;21138;21131:12;21109:36;;;21164:74;21230:7;21219:8;21208:9;21204:24;21164:74;:::i;22539:288::-;22608:6;22661:2;22649:9;22640:7;22636:23;22632:32;22629:52;;;22677:1;22674;22667:12;22629:52;22709:9;22703:16;22759:18;22752:5;22748:30;22741:5;22738:41;22728:69;;22793:1;22790;22783:12;26087:125;26152:9;;;26173:10;;;26170:36;;;26186:18;;:::i;26217:736::-;26532:6;26521:9;26514:25;26575:6;26570:2;26559:9;26555:18;26548:34;26618:6;26613:2;26602:9;26598:18;26591:34;26495:4;26644:42;26734:2;26726:6;26722:15;26717:2;26706:9;26702:18;26695:43;26787:2;26779:6;26775:15;26769:3;26758:9;26754:19;26747:44;26840:2;26832:6;26828:15;26822:3;26811:9;26807:19;26800:44;;26881:3;26875;26864:9;26860:19;26853:32;26902:45;26942:3;26931:9;26927:19;26919:6;26902:45;:::i;:::-;26894:53;26217:736;-1:-1:-1;;;;;;;;;26217:736:1:o;26958:408::-;27173:42;27165:6;27161:55;27150:9;27143:74;27253:6;27248:2;27237:9;27233:18;27226:34;27296:2;27291;27280:9;27276:18;27269:30;27124:4;27316:44;27356:2;27345:9;27341:18;27333:6;27316:44;:::i;:::-;27308:52;26958:408;-1:-1:-1;;;;;26958:408:1:o;27371:287::-;27500:3;27538:6;27532:13;27554:66;27613:6;27608:3;27601:4;27593:6;27589:17;27554:66;:::i;:::-;27636:16;;;;;27371:287;-1:-1:-1;;27371:287:1:o;27663:563::-;27916:6;27905:9;27898:25;27971:42;27963:6;27959:55;27954:2;27943:9;27939:18;27932:83;28051:6;28046:2;28035:9;28031:18;28024:34;28108:6;28101:14;28094:22;28089:2;28078:9;28074:18;28067:50;28154:3;28148;28137:9;28133:19;28126:32;27879:4;28175:45;28215:3;28204:9;28200:19;28192:6;28175:45;:::i;28231:184::-;28301:6;28354:2;28342:9;28333:7;28329:23;28325:32;28322:52;;;28370:1;28367;28360:12;28322:52;-1:-1:-1;28393:16:1;;28231:184;-1:-1:-1;28231:184:1:o;28767:580::-;28844:4;28850:6;28910:11;28897:25;29000:66;28989:8;28973:14;28969:29;28965:102;28945:18;28941:127;28931:155;;29082:1;29079;29072:12;28931:155;29109:33;;29161:20;;;-1:-1:-1;29204:18:1;29193:30;;29190:50;;;29236:1;29233;29226:12;29190:50;29269:4;29257:17;;-1:-1:-1;29300:14:1;29296:27;;;29286:38;;29283:58;;;29337:1;29334;29327:12;29352:648;29432:6;29485:2;29473:9;29464:7;29460:23;29456:32;29453:52;;;29501:1;29498;29491:12;29453:52;29534:9;29528:16;29567:18;29559:6;29556:30;29553:50;;;29599:1;29596;29589:12;29553:50;29622:22;;29675:4;29667:13;;29663:27;-1:-1:-1;29653:55:1;;29704:1;29701;29694:12;29653:55;29733:2;29727:9;29758:48;29774:31;29802:2;29774:31;:::i;29758:48::-;29829:2;29822:5;29815:17;29869:7;29864:2;29859;29855;29851:11;29847:20;29844:33;29841:53;;;29890:1;29887;29880:12;29841:53;29903:67;29967:2;29962;29955:5;29951:14;29946:2;29942;29938:11;29903:67;:::i;30229:184::-;30281:77;30278:1;30271:88;30378:4;30375:1;30368:15;30402:4;30399:1;30392:15;31684:980;32036:4;32065:3;32095:6;32084:9;32077:25;32138:6;32133:2;32122:9;32118:18;32111:34;32181:6;32176:2;32165:9;32161:18;32154:34;32224:6;32219:2;32208:9;32204:18;32197:34;32268:6;32262:3;32251:9;32247:19;32240:35;32294:42;32385:2;32377:6;32373:15;32367:3;32356:9;32352:19;32345:44;32438:2;32430:6;32426:15;32420:3;32409:9;32405:19;32398:44;;32479:2;32473:3;32462:9;32458:19;32451:31;32505:44;32545:2;32534:9;32530:18;32522:6;32505:44;:::i;:::-;32491:58;;32598:9;32590:6;32586:22;32580:3;32569:9;32565:19;32558:51;32626:32;32651:6;32643;32626:32;:::i;:::-;32618:40;31684:980;-1:-1:-1;;;;;;;;;;;;31684:980:1:o;34760:812::-;35171:25;35166:3;35159:38;35141:3;35226:6;35220:13;35242:75;35310:6;35305:2;35300:3;35296:12;35289:4;35281:6;35277:17;35242:75;:::i;:::-;35381:19;35376:2;35336:16;;;35368:11;;;35361:40;35426:13;;35448:76;35426:13;35510:2;35502:11;;35495:4;35483:17;;35448:76;:::i;:::-;35544:17;35563:2;35540:26;;34760:812;-1:-1:-1;;;;34760:812:1:o;35577:245::-;35644:6;35697:2;35685:9;35676:7;35672:23;35668:32;35665:52;;;35713:1;35710;35703:12;35665:52;35745:9;35739:16;35764:28;35786:5;35764:28;:::i;36238:168::-;36311:9;;;36342;;36359:15;;;36353:22;;36339:37;36329:71;;36380:18;;:::i;36411:196::-;36450:3;36478:5;36468:39;;36487:18;;:::i;:::-;-1:-1:-1;36534:66:1;36523:78;;36411:196::o
Swarm Source
ipfs://e11acc2a66d5e5b8998d9bd6bd0b9b67acf801449e3745dcaaa1c24c1a8e7a1e
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.