More Info
Private Name Tags
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x49d33cd9ed3c3c2c0cfd13ae77075c5fbdd4c3bac4dc2f12d324660f1e7aefcf | Withdraw | (pending) | 1 hr ago | IN | 0 ETH | (Pending) | |||
0x1592ed62869c4815c0f02f869c02650ee5b4a1f403385458f00013d93d55edd3 | Withdraw | (pending) | 2 days ago | IN | 0 ETH | (Pending) | |||
Convert | 21473852 | 3 hrs ago | IN | 0 ETH | 0.00062787 | ||||
Convert | 21473160 | 6 hrs ago | IN | 0 ETH | 0.00096665 | ||||
Convert | 21458074 | 2 days ago | IN | 0 ETH | 0.0004939 | ||||
Convert | 21448880 | 3 days ago | IN | 0 ETH | 0.00051537 | ||||
Convert | 21441578 | 4 days ago | IN | 0 ETH | 0.00070154 | ||||
Withdraw | 21439471 | 4 days ago | IN | 0 ETH | 0.00115009 | ||||
Withdraw | 21428353 | 6 days ago | IN | 0 ETH | 0.00092828 | ||||
Convert | 21428313 | 6 days ago | IN | 0 ETH | 0.00074334 | ||||
Withdraw | 21405641 | 9 days ago | IN | 0 ETH | 0.00078793 | ||||
Convert | 21405599 | 9 days ago | IN | 0 ETH | 0.00067841 | ||||
Withdraw | 21400565 | 10 days ago | IN | 0 ETH | 0.00083759 | ||||
Withdraw | 21395633 | 11 days ago | IN | 0 ETH | 0.00165835 | ||||
Convert | 21394170 | 11 days ago | IN | 0 ETH | 0.0013186 | ||||
Convert | 21393416 | 11 days ago | IN | 0 ETH | 0.00094785 | ||||
Convert | 21381866 | 13 days ago | IN | 0 ETH | 0.00220313 | ||||
Withdraw | 21379131 | 13 days ago | IN | 0 ETH | 0.00146141 | ||||
Convert | 21379083 | 13 days ago | IN | 0 ETH | 0.00107485 | ||||
Withdraw | 21378835 | 13 days ago | IN | 0 ETH | 0.00132298 | ||||
Withdraw | 21378434 | 13 days ago | IN | 0 ETH | 0.0014671 | ||||
Convert | 21378412 | 13 days ago | IN | 0 ETH | 0.00108743 | ||||
Withdraw | 21378183 | 13 days ago | IN | 0 ETH | 0.0010287 | ||||
Withdraw | 21377765 | 13 days ago | IN | 0 ETH | 0.00037116 | ||||
Withdraw | 21375033 | 13 days ago | IN | 0 ETH | 0.0013003 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
SeedTokenSale
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-06-17 */ // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); } // File: @openzeppelin/contracts/access/IAccessControl.sol // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/utils/math/Math.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } // File: @openzeppelin/contracts/utils/math/SignedMath.sol // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File: @openzeppelin/contracts/access/AccessControl.sol // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to * 0 before setting it to a non-zero value. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } } // File: ScheduledTokenSale.sol pragma solidity ^0.8.17; /** * @title Abstract ScheduledTokenSale * @author https://codd.tech * @dev ScheduledTokenSale implements swapping unlocking schedule for early investors. * Unlock schedule managed by unlockSchedule and scheduleStartTimestamp variables. */ abstract contract ScheduledTokenSale is AccessControl { using SafeERC20 for IERC20; event Deposit( address sender, address indexed to, uint256 amount ); bytes32 public constant CONTROLLER_ROLE = keccak256("CONTROLLER_ROLE"); uint16 private constant PERCENT_DENOMINATOR = 10_000; uint256 public scheduleStartTimestamp = 0; mapping(address => uint256) private _balances; mapping(address => uint256) private _withdrawnBalances; uint256 public totalBalance; struct UnlockScheduleItem { uint256 unlockTimePass; uint16 totalPercentageUnlocked; } UnlockScheduleItem[] internal unlockSchedule; IERC20 public token; function _initUnlockSchedule() internal virtual; constructor(IERC20 token_) { require( address(token_) != address(0), "ScheduledTokenSale: New token address cannot be null" ); _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); token = token_; _initUnlockSchedule(); _validateUnlockSchedule(); } function launchSale() external onlyRole(CONTROLLER_ROLE) { require(scheduleStartTimestamp == 0, "ScheduledTokenSale: Sale already launched"); // solhint-disable-next-line not-rely-on-time scheduleStartTimestamp = block.timestamp; } function addBalance( address to, uint256 amount ) external virtual onlyRole(CONTROLLER_ROLE) { _addBalance(to, amount); } function withdraw(address to, uint256 amount) external returns (bool) { require( to != address(0), "ScheduledTokenSale: Recipient address cannot be null" ); require( amount > 0, "ScheduledTokenSale: Withdraw amount must be greater than zero" ); require( scheduleStartTimestamp > 0 && scheduleStartTimestamp < block.timestamp, // solhint-disable-line not-rely-on-time "ScheduledTokenSale: Unlock schedule not started yet" ); require( unlockedOf(msg.sender) >= amount, "ScheduledTokenSale: Amount to withdraw is greater than unlocked amount" ); _withdrawnBalances[msg.sender] += amount; totalBalance -= amount; token.safeTransfer(to, amount); return true; } function balanceOf(address account) external view returns (uint256) { return _balances[account] - _withdrawnBalances[account]; } function unlockedOf(address account) public view returns (uint256) { if (scheduleStartTimestamp > 0) { uint256 totalUnlocked = Math.mulDiv( _balances[account], getUnlockedPercent(block.timestamp - scheduleStartTimestamp), // solhint-disable-line not-rely-on-time PERCENT_DENOMINATOR ); if (totalUnlocked <= _withdrawnBalances[account]) { return 0; } return totalUnlocked - _withdrawnBalances[account]; } return 0; } function getUnlockedPercent( uint256 secondsPassed ) internal view returns (uint16) { uint8 index = 0; while(index < unlockSchedule.length && unlockSchedule[index].unlockTimePass < secondsPassed) { index++; } return index > 0 ? unlockSchedule[index - 1].totalPercentageUnlocked : 0; } function _addBalance(address to, uint256 amount) internal { require( to != address(0), "ScheduledTokenSale: Recipient address cannot be null" ); require( amount > 0, "ScheduledTokenSale: Balance amount must be greater than zero" ); require( totalBalance + amount <= token.balanceOf(address(this)), "ScheduledTokenSale: Total balance exceeds available balance" ); _balances[to] += amount; totalBalance += amount; emit Deposit(msg.sender, to, amount); } function _validateUnlockSchedule() private view { assert(unlockSchedule.length > 1); assert(unlockSchedule[unlockSchedule.length - 1].totalPercentageUnlocked == PERCENT_DENOMINATOR); for (uint8 i = 1; i < unlockSchedule.length; ++i) { assert( unlockSchedule[i - 1].unlockTimePass < unlockSchedule[i].unlockTimePass ); assert( unlockSchedule[i - 1].totalPercentageUnlocked < unlockSchedule[i].totalPercentageUnlocked ); } assert( unlockSchedule[unlockSchedule.length - 1].totalPercentageUnlocked == PERCENT_DENOMINATOR ); } } // File: Claimable.sol pragma solidity ^0.8.17; /** * @title Claimable * @dev Claimable contract, where the ownership needs to be claimed. * This allows the new owner to accept the transfer. * * Deprecated */ contract Claimable { address public owner; address public pendingOwner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The Claimable constructor sets the original `owner` of the contract to the sender * account. */ constructor() { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require( msg.sender == owner, "Claimable: Message sender is not owner!" ); _; } /** * @dev Modifier throws if called by any account other than the pendingOwner. */ modifier onlyPendingOwner() { require( msg.sender == pendingOwner, "Claimable: Message sender is not pending owner!" ); _; } /** * @dev Allows the current owner to set the pendingOwner address. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { require( address(newOwner) != address(0), "Claimable: New owner address cannot be null" ); pendingOwner = newOwner; } /** * @dev Allows the pendingOwner address to finalize the transfer. */ function claimOwnership() public onlyPendingOwner { emit OwnershipTransferred(owner, pendingOwner); owner = pendingOwner; pendingOwner = address(0); } } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin/contracts/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} } // File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol) pragma solidity ^0.8.0; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { _spendAllowance(account, _msgSender(), amount); _burn(account, amount); } } // File: LegacyToken.sol pragma solidity ^0.8.17; /** * @dev deprecated legacy token */ contract LegacyToken is ERC20, ERC20Burnable, Claimable { constructor() ERC20("Legacy Token", "LGS") {} function decimals() public view virtual override returns (uint8) { return 8; } /** * @dev Function to mint tokens * @param to The address that will receive the minted tokens. * @param value The amount of tokens to mint. * @return A boolean that indicates if the operation was successful. */ function mint(address to, uint256 value) public onlyOwner returns (bool) { require( value > 0, "LegacyToken: Mint amount amount must be greater than zero" ); _mint(to, value); return true; } } // File: SeedTokenSale.sol pragma solidity ^0.8.17; /** * @title Smartcontract for exchanging LegacyToken to SWGT with unlock schedule * @author https://codd.tech * @dev SeedTokenSale contract implements swapping Legacy tokens for SWGT and unlock schedule * SWG tokens are burned in the process. * It should be deployed in several steps: * 1. Deploy Exchanger with proper token addresses * 2. Transfer round cap to contract's address * Swap performed in two steps also: * 1. User should approve required amount to swap to the SeedTokenSale * 2. User should call SeedTokenSale.convert method * 3. After some time, when funds unlocked according to schedule, user can call method SeedTokenSale.withdraw * see ScheduledTokenSale contract for details */ contract SeedTokenSale is ScheduledTokenSale, ReentrancyGuard { event TokenExchanged(address indexed from, address indexed to, uint256 amount); LegacyToken private tokenOld; constructor( IERC20 token, LegacyToken tokenOld_ ) ScheduledTokenSale(token) { require( address(tokenOld_) != address(0), "SeedTokenSale: Old token address cannot be null" ); tokenOld = tokenOld_; } function convert( address to, uint256 amount ) external virtual returns (bool) { _convert(msg.sender, to, amount); return true; } function convert( address[] calldata to, uint256[] calldata amount ) external virtual onlyRole(CONTROLLER_ROLE) returns (bool) { require( to.length == amount.length, "SeedTokenSale: Number of recipients should match number of amounts" ); require(to.length > 0, "SeedTokenSale: No recipients"); address tokenOldOwner = tokenOld.owner(); for (uint256 i = 0; i < to.length; i++) { _convert(tokenOldOwner, to[i], amount[i]); } return true; } function _convert( address from, address to, uint256 amount ) internal virtual nonReentrant { require( tokenOld.balanceOf(from) >= amount, "SeedTokenSale: Insufficient LegacyToken balance" ); require( tokenOld.allowance(from, address(this)) >= amount, "SeedTokenSale: Not enough LegacyToken allowance" ); tokenOld.burnFrom(from, amount); _addBalance(to, amount); emit TokenExchanged(from, to, amount); } function _initUnlockSchedule() internal override { unlockSchedule.push(UnlockScheduleItem(28 days, 1000)); unlockSchedule.push(UnlockScheduleItem(120 days, 2500)); unlockSchedule.push(UnlockScheduleItem(210 days, 4000)); unlockSchedule.push(UnlockScheduleItem(300 days, 5000)); unlockSchedule.push(UnlockScheduleItem(390 days, 6000)); unlockSchedule.push(UnlockScheduleItem(480 days, 7000)); unlockSchedule.push(UnlockScheduleItem(570 days, 8000)); unlockSchedule.push(UnlockScheduleItem(660 days, 9000)); unlockSchedule.push(UnlockScheduleItem(870 days, 10000)); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"contract LegacyToken","name":"tokenOld_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenExchanged","type":"event"},{"inputs":[],"name":"CONTROLLER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"convert","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint256[]","name":"amount","type":"uint256[]"}],"name":"convert","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"scheduleStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unlockedOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260006001553480156200001657600080fd5b5060405162003d6438038062003d6483398181016040528101906200003c919062000a76565b81600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000af576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000a69062000b44565b60405180910390fd5b620000c46000801b33620001e960201b60201c565b80600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000115620002da60201b60201c565b620001256200071b60201b60201c565b506001600781905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620001a0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001979062000bdc565b60405180910390fd5b80600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505062000d47565b620001fb82826200094160201b60201c565b620002d657600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200027b620009ab60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600560405180604001604052806224ea0081526020016103e861ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff160217905550505060056040518060400160405280629e340081526020016109c461ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff160217905550505060056040518060400160405280630114db008152602001610fa061ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff16021790555050506005604051806040016040528063018b8200815260200161138861ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff1602179055505050600560405180604001604052806302022900815260200161177061ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff160217905550505060056040518060400160405280630278d0008152602001611b5861ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff1602179055505050600560405180604001604052806302ef77008152602001611f4061ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff1602179055505050600560405180604001604052806303661e00815260200161232861ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff16021790555050506005604051806040016040528063047af900815260200161271061ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff1602179055505050565b60016005805490501162000734576200073362000bfe565b5b61271061ffff166005600160058054905062000751919062000c66565b8154811062000765576200076462000ca1565b5b906000526020600020906002020160010160009054906101000a900461ffff1661ffff16146200079a576200079962000bfe565b5b6000600190505b6005805490508160ff161015620008d85760058160ff1681548110620007cc57620007cb62000ca1565b5b9060005260206000209060020201600001546005600183620007ef919062000cdd565b60ff168154811062000806576200080562000ca1565b5b9060005260206000209060020201600001541062000829576200082862000bfe565b5b60058160ff168154811062000843576200084262000ca1565b5b906000526020600020906002020160010160009054906101000a900461ffff1661ffff16600560018362000878919062000cdd565b60ff16815481106200088f576200088e62000ca1565b5b906000526020600020906002020160010160009054906101000a900461ffff1661ffff1610620008c457620008c362000bfe565b5b80620008d09062000d19565b9050620007a1565b5061271061ffff1660056001600580549050620008f6919062000c66565b815481106200090a576200090962000ca1565b5b906000526020600020906002020160010160009054906101000a900461ffff1661ffff16146200093f576200093e62000bfe565b5b565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620009e582620009b8565b9050919050565b6000620009f982620009d8565b9050919050565b62000a0b81620009ec565b811462000a1757600080fd5b50565b60008151905062000a2b8162000a00565b92915050565b600062000a3e82620009d8565b9050919050565b62000a508162000a31565b811462000a5c57600080fd5b50565b60008151905062000a708162000a45565b92915050565b6000806040838503121562000a905762000a8f620009b3565b5b600062000aa08582860162000a1a565b925050602062000ab38582860162000a5f565b9150509250929050565b600082825260208201905092915050565b7f5363686564756c6564546f6b656e53616c653a204e657720746f6b656e20616460008201527f64726573732063616e6e6f74206265206e756c6c000000000000000000000000602082015250565b600062000b2c60348362000abd565b915062000b398262000ace565b604082019050919050565b6000602082019050818103600083015262000b5f8162000b1d565b9050919050565b7f53656564546f6b656e53616c653a204f6c6420746f6b656e206164647265737360008201527f2063616e6e6f74206265206e756c6c0000000000000000000000000000000000602082015250565b600062000bc4602f8362000abd565b915062000bd18262000b66565b604082019050919050565b6000602082019050818103600083015262000bf78162000bb5565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000c738262000c2d565b915062000c808362000c2d565b925082820390508181111562000c9b5762000c9a62000c37565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff82169050919050565b600062000cea8262000cd0565b915062000cf78362000cd0565b9250828203905060ff81111562000d135762000d1262000c37565b5b92915050565b600062000d268262000cd0565b915060ff820362000d3c5762000d3b62000c37565b5b600182019050919050565b61300d8062000d576000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c806391d14854116100a2578063d547741f11610071578063d547741f146102f3578063dc4ff41a1461030f578063f313372d1461033f578063f3fef3a31461035d578063fc0c546a1461038d57610116565b806391d1485414610257578063a217fddf14610287578063ad7a672f146102a5578063caad546e146102c357610116565b80632f2ff15d116100e95780632f2ff15d146101b557806336568abe146101d157806367c6e39c146101ed57806370a082311461021d5780637f7376e81461024d57610116565b806301ffc9a71461011b578063092c5b3b1461014b57806321e5383a14610169578063248a9ca314610185575b600080fd5b61013560048036038101906101309190611c3b565b6103ab565b6040516101429190611c83565b60405180910390f35b610153610425565b6040516101609190611cb7565b60405180910390f35b610183600480360381019061017e9190611d66565b610449565b005b61019f600480360381019061019a9190611dd2565b610482565b6040516101ac9190611cb7565b60405180910390f35b6101cf60048036038101906101ca9190611dff565b6104a1565b005b6101eb60048036038101906101e69190611dff565b6104c2565b005b61020760048036038101906102029190611d66565b610545565b6040516102149190611c83565b60405180910390f35b61023760048036038101906102329190611e3f565b61055c565b6040516102449190611e7b565b60405180910390f35b6102556105ef565b005b610271600480360381019061026c9190611dff565b610668565b60405161027e9190611c83565b60405180910390f35b61028f6106d2565b60405161029c9190611cb7565b60405180910390f35b6102ad6106d9565b6040516102ba9190611e7b565b60405180910390f35b6102dd60048036038101906102d89190611e3f565b6106df565b6040516102ea9190611e7b565b60405180910390f35b61030d60048036038101906103089190611dff565b610805565b005b61032960048036038101906103249190611f51565b610826565b6040516103369190611c83565b60405180910390f35b6103476109f0565b6040516103549190611e7b565b60405180910390f35b61037760048036038101906103729190611d66565b6109f6565b6040516103849190611c83565b60405180910390f35b610395610c0c565b6040516103a29190612031565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061041e575061041d82610c32565b5b9050919050565b7f7b765e0e932d348852a6f810bfa1ab891e259123f02db8cdcde614c57022335781565b7f7b765e0e932d348852a6f810bfa1ab891e259123f02db8cdcde614c57022335761047381610c9c565b61047d8383610cb0565b505050565b6000806000838152602001908152602001600020600101549050919050565b6104aa82610482565b6104b381610c9c565b6104bd8383610f10565b505050565b6104ca610ff0565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e906120cf565b60405180910390fd5b6105418282610ff8565b5050565b60006105523384846110d9565b6001905092915050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546105e8919061211e565b9050919050565b7f7b765e0e932d348852a6f810bfa1ab891e259123f02db8cdcde614c57022335761061981610c9c565b60006001541461065e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610655906121c4565b60405180910390fd5b4260018190555050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000801b81565b60045481565b60008060015411156107fb576000610756600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461074660015442610741919061211e565b6113aa565b61ffff1661271061ffff16611466565b9050600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481116107a8576000915050610800565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054816107f3919061211e565b915050610800565b600090505b919050565b61080e82610482565b61081781610c9c565b6108218383610ff8565b505050565b60007f7b765e0e932d348852a6f810bfa1ab891e259123f02db8cdcde614c57022335761085281610c9c565b83839050868690501461089a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108919061227c565b60405180910390fd5b600086869050116108e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d7906122e8565b60405180910390fd5b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561094f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610973919061231d565b905060005b878790508110156109e1576109ce8289898481811061099a5761099961234a565b5b90506020020160208101906109af9190611e3f565b8888858181106109c2576109c161234a565b5b905060200201356110d9565b80806109d990612379565b915050610978565b50600192505050949350505050565b60015481565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5d90612433565b60405180910390fd5b60008211610aa9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa0906124c5565b60405180910390fd5b6000600154118015610abc575042600154105b610afb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af290612557565b60405180910390fd5b81610b05336106df565b1015610b46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3d9061260f565b60405180910390fd5b81600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610b95919061262f565b925050819055508160046000828254610bae919061211e565b92505081905550610c028383600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166115779092919063ffffffff16565b6001905092915050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610cad81610ca8610ff0565b6115fd565b50565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1690612433565b60405180910390fd5b60008111610d62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d59906126d5565b60405180910390fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610dbd9190612704565b602060405180830381865afa158015610dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfe9190612734565b81600454610e0c919061262f565b1115610e4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e44906127d3565b60405180910390fd5b80600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610e9c919061262f565b925050819055508060046000828254610eb5919061262f565b925050819055508173ffffffffffffffffffffffffffffffffffffffff167f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f623383604051610f049291906127f3565b60405180910390a25050565b610f1a8282610668565b610fec57600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610f91610ff0565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b6110028282610668565b156110d557600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061107a610ff0565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6110e1611682565b80600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b815260040161113d9190612704565b602060405180830381865afa15801561115a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117e9190612734565b10156111bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b69061288e565b60405180910390fd5b80600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e85306040518363ffffffff1660e01b815260040161121d9291906128ae565b602060405180830381865afa15801561123a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125e9190612734565b101561129f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129690612949565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379cc679084836040518363ffffffff1660e01b81526004016112fc9291906127f3565b600060405180830381600087803b15801561131657600080fd5b505af115801561132a573d6000803e3d6000fd5b505050506113388282610cb0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f81aaa18332363199c2673bf9efd29fedf28c9cf21a0d14b986854c436993c06f836040516113959190611e7b565b60405180910390a36113a56116d1565b505050565b600080600090505b6005805490508160ff161080156113f057508260058260ff16815481106113dc576113db61234a565b5b906000526020600020906002020160000154105b1561140857808061140090612976565b9150506113b2565b60008160ff161161141a57600061145e565b6005600182611429919061299f565b60ff168154811061143d5761143c61234a565b5b906000526020600020906002020160010160009054906101000a900461ffff165b915050919050565b60008060008019858709858702925082811083820303915050600081036114a157838281611497576114966129d4565b5b0492505050611570565b8084116114e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114da90612a4f565b60405180910390fd5b60008486880990508281118203915080830392506000600186190186169050808604955080840493506001818260000304019050808302841793506000600287600302189050808702600203810290508087026002038102905080870260020381029050808702600203810290508087026002038102905080870260020381029050808502955050505050505b9392505050565b6115f88363a9059cbb60e01b84846040516024016115969291906127f3565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116db565b505050565b6116078282610668565b61167e57611614816117a3565b6116228360001c60206117d0565b604051602001611633929190612b78565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116759190612bfc565b60405180910390fd5b5050565b6002600754036116c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116be90612c6a565b60405180910390fd5b6002600781905550565b6001600781905550565b600061173d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611a0c9092919063ffffffff16565b905060008151148061175f57508080602001905181019061175e9190612cb6565b5b61179e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179590612d55565b60405180910390fd5b505050565b60606117c98273ffffffffffffffffffffffffffffffffffffffff16601460ff166117d0565b9050919050565b6060600060028360026117e39190612d75565b6117ed919061262f565b67ffffffffffffffff81111561180657611805612db7565b5b6040519080825280601f01601f1916602001820160405280156118385781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106118705761186f61234a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106118d4576118d361234a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026119149190612d75565b61191e919061262f565b90505b60018111156119be577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106119605761195f61234a565b5b1a60f81b8282815181106119775761197661234a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806119b790612de6565b9050611921565b5060008414611a02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f990612e5b565b60405180910390fd5b8091505092915050565b6060611a1b8484600085611a24565b90509392505050565b606082471015611a69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a6090612eed565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611a929190612f54565b60006040518083038185875af1925050503d8060008114611acf576040519150601f19603f3d011682016040523d82523d6000602084013e611ad4565b606091505b5091509150611ae587838387611af1565b92505050949350505050565b60608315611b53576000835103611b4b57611b0b85611b66565b611b4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4190612fb7565b60405180910390fd5b5b829050611b5e565b611b5d8383611b89565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115611b9c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd09190612bfc565b60405180910390fd5b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611c1881611be3565b8114611c2357600080fd5b50565b600081359050611c3581611c0f565b92915050565b600060208284031215611c5157611c50611bd9565b5b6000611c5f84828501611c26565b91505092915050565b60008115159050919050565b611c7d81611c68565b82525050565b6000602082019050611c986000830184611c74565b92915050565b6000819050919050565b611cb181611c9e565b82525050565b6000602082019050611ccc6000830184611ca8565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611cfd82611cd2565b9050919050565b611d0d81611cf2565b8114611d1857600080fd5b50565b600081359050611d2a81611d04565b92915050565b6000819050919050565b611d4381611d30565b8114611d4e57600080fd5b50565b600081359050611d6081611d3a565b92915050565b60008060408385031215611d7d57611d7c611bd9565b5b6000611d8b85828601611d1b565b9250506020611d9c85828601611d51565b9150509250929050565b611daf81611c9e565b8114611dba57600080fd5b50565b600081359050611dcc81611da6565b92915050565b600060208284031215611de857611de7611bd9565b5b6000611df684828501611dbd565b91505092915050565b60008060408385031215611e1657611e15611bd9565b5b6000611e2485828601611dbd565b9250506020611e3585828601611d1b565b9150509250929050565b600060208284031215611e5557611e54611bd9565b5b6000611e6384828501611d1b565b91505092915050565b611e7581611d30565b82525050565b6000602082019050611e906000830184611e6c565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611ebb57611eba611e96565b5b8235905067ffffffffffffffff811115611ed857611ed7611e9b565b5b602083019150836020820283011115611ef457611ef3611ea0565b5b9250929050565b60008083601f840112611f1157611f10611e96565b5b8235905067ffffffffffffffff811115611f2e57611f2d611e9b565b5b602083019150836020820283011115611f4a57611f49611ea0565b5b9250929050565b60008060008060408587031215611f6b57611f6a611bd9565b5b600085013567ffffffffffffffff811115611f8957611f88611bde565b5b611f9587828801611ea5565b9450945050602085013567ffffffffffffffff811115611fb857611fb7611bde565b5b611fc487828801611efb565b925092505092959194509250565b6000819050919050565b6000611ff7611ff2611fed84611cd2565b611fd2565b611cd2565b9050919050565b600061200982611fdc565b9050919050565b600061201b82611ffe565b9050919050565b61202b81612010565b82525050565b60006020820190506120466000830184612022565b92915050565b600082825260208201905092915050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b60006120b9602f8361204c565b91506120c48261205d565b604082019050919050565b600060208201905081810360008301526120e8816120ac565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061212982611d30565b915061213483611d30565b925082820390508181111561214c5761214b6120ef565b5b92915050565b7f5363686564756c6564546f6b656e53616c653a2053616c6520616c726561647960008201527f206c61756e636865640000000000000000000000000000000000000000000000602082015250565b60006121ae60298361204c565b91506121b982612152565b604082019050919050565b600060208201905081810360008301526121dd816121a1565b9050919050565b7f53656564546f6b656e53616c653a204e756d626572206f66207265636970696560008201527f6e74732073686f756c64206d61746368206e756d626572206f6620616d6f756e60208201527f7473000000000000000000000000000000000000000000000000000000000000604082015250565b600061226660428361204c565b9150612271826121e4565b606082019050919050565b6000602082019050818103600083015261229581612259565b9050919050565b7f53656564546f6b656e53616c653a204e6f20726563697069656e747300000000600082015250565b60006122d2601c8361204c565b91506122dd8261229c565b602082019050919050565b60006020820190508181036000830152612301816122c5565b9050919050565b60008151905061231781611d04565b92915050565b60006020828403121561233357612332611bd9565b5b600061234184828501612308565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061238482611d30565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036123b6576123b56120ef565b5b600182019050919050565b7f5363686564756c6564546f6b656e53616c653a20526563697069656e7420616460008201527f64726573732063616e6e6f74206265206e756c6c000000000000000000000000602082015250565b600061241d60348361204c565b9150612428826123c1565b604082019050919050565b6000602082019050818103600083015261244c81612410565b9050919050565b7f5363686564756c6564546f6b656e53616c653a20576974686472617720616d6f60008201527f756e74206d7573742062652067726561746572207468616e207a65726f000000602082015250565b60006124af603d8361204c565b91506124ba82612453565b604082019050919050565b600060208201905081810360008301526124de816124a2565b9050919050565b7f5363686564756c6564546f6b656e53616c653a20556e6c6f636b20736368656460008201527f756c65206e6f7420737461727465642079657400000000000000000000000000602082015250565b600061254160338361204c565b915061254c826124e5565b604082019050919050565b6000602082019050818103600083015261257081612534565b9050919050565b7f5363686564756c6564546f6b656e53616c653a20416d6f756e7420746f20776960008201527f7468647261772069732067726561746572207468616e20756e6c6f636b65642060208201527f616d6f756e740000000000000000000000000000000000000000000000000000604082015250565b60006125f960468361204c565b915061260482612577565b606082019050919050565b60006020820190508181036000830152612628816125ec565b9050919050565b600061263a82611d30565b915061264583611d30565b925082820190508082111561265d5761265c6120ef565b5b92915050565b7f5363686564756c6564546f6b656e53616c653a2042616c616e636520616d6f7560008201527f6e74206d7573742062652067726561746572207468616e207a65726f00000000602082015250565b60006126bf603c8361204c565b91506126ca82612663565b604082019050919050565b600060208201905081810360008301526126ee816126b2565b9050919050565b6126fe81611cf2565b82525050565b600060208201905061271960008301846126f5565b92915050565b60008151905061272e81611d3a565b92915050565b60006020828403121561274a57612749611bd9565b5b60006127588482850161271f565b91505092915050565b7f5363686564756c6564546f6b656e53616c653a20546f74616c2062616c616e6360008201527f65206578636565647320617661696c61626c652062616c616e63650000000000602082015250565b60006127bd603b8361204c565b91506127c882612761565b604082019050919050565b600060208201905081810360008301526127ec816127b0565b9050919050565b600060408201905061280860008301856126f5565b6128156020830184611e6c565b9392505050565b7f53656564546f6b656e53616c653a20496e73756666696369656e74204c65676160008201527f6379546f6b656e2062616c616e63650000000000000000000000000000000000602082015250565b6000612878602f8361204c565b91506128838261281c565b604082019050919050565b600060208201905081810360008301526128a78161286b565b9050919050565b60006040820190506128c360008301856126f5565b6128d060208301846126f5565b9392505050565b7f53656564546f6b656e53616c653a204e6f7420656e6f756768204c656761637960008201527f546f6b656e20616c6c6f77616e63650000000000000000000000000000000000602082015250565b6000612933602f8361204c565b915061293e826128d7565b604082019050919050565b6000602082019050818103600083015261296281612926565b9050919050565b600060ff82169050919050565b600061298182612969565b915060ff8203612994576129936120ef565b5b600182019050919050565b60006129aa82612969565b91506129b583612969565b9250828203905060ff8111156129ce576129cd6120ef565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4d6174683a206d756c446976206f766572666c6f770000000000000000000000600082015250565b6000612a3960158361204c565b9150612a4482612a03565b602082019050919050565b60006020820190508181036000830152612a6881612a2c565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000612ab0601783612a6f565b9150612abb82612a7a565b601782019050919050565b600081519050919050565b60005b83811015612aef578082015181840152602081019050612ad4565b60008484015250505050565b6000612b0682612ac6565b612b108185612a6f565b9350612b20818560208601612ad1565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000612b62601183612a6f565b9150612b6d82612b2c565b601182019050919050565b6000612b8382612aa3565b9150612b8f8285612afb565b9150612b9a82612b55565b9150612ba68284612afb565b91508190509392505050565b6000601f19601f8301169050919050565b6000612bce82612ac6565b612bd8818561204c565b9350612be8818560208601612ad1565b612bf181612bb2565b840191505092915050565b60006020820190508181036000830152612c168184612bc3565b905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612c54601f8361204c565b9150612c5f82612c1e565b602082019050919050565b60006020820190508181036000830152612c8381612c47565b9050919050565b612c9381611c68565b8114612c9e57600080fd5b50565b600081519050612cb081612c8a565b92915050565b600060208284031215612ccc57612ccb611bd9565b5b6000612cda84828501612ca1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000612d3f602a8361204c565b9150612d4a82612ce3565b604082019050919050565b60006020820190508181036000830152612d6e81612d32565b9050919050565b6000612d8082611d30565b9150612d8b83611d30565b9250828202612d9981611d30565b91508282048414831517612db057612daf6120ef565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000612df182611d30565b915060008203612e0457612e036120ef565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000612e4560208361204c565b9150612e5082612e0f565b602082019050919050565b60006020820190508181036000830152612e7481612e38565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000612ed760268361204c565b9150612ee282612e7b565b604082019050919050565b60006020820190508181036000830152612f0681612eca565b9050919050565b600081519050919050565b600081905092915050565b6000612f2e82612f0d565b612f388185612f18565b9350612f48818560208601612ad1565b80840191505092915050565b6000612f608284612f23565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000612fa1601d8361204c565b9150612fac82612f6b565b602082019050919050565b60006020820190508181036000830152612fd081612f94565b905091905056fea2646970667358221220f25ae3e563f3e35ab2ae646394340bb58b040bd53db1e16e7275c1f6c241040164736f6c63430008110033000000000000000000000000c8bf8bc34874e07f6a0d4abc8be22ba9e372631b00000000000000000000000085e5cc7bb799b5abe00fd8ebb3edd4ff095789b9
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101165760003560e01c806391d14854116100a2578063d547741f11610071578063d547741f146102f3578063dc4ff41a1461030f578063f313372d1461033f578063f3fef3a31461035d578063fc0c546a1461038d57610116565b806391d1485414610257578063a217fddf14610287578063ad7a672f146102a5578063caad546e146102c357610116565b80632f2ff15d116100e95780632f2ff15d146101b557806336568abe146101d157806367c6e39c146101ed57806370a082311461021d5780637f7376e81461024d57610116565b806301ffc9a71461011b578063092c5b3b1461014b57806321e5383a14610169578063248a9ca314610185575b600080fd5b61013560048036038101906101309190611c3b565b6103ab565b6040516101429190611c83565b60405180910390f35b610153610425565b6040516101609190611cb7565b60405180910390f35b610183600480360381019061017e9190611d66565b610449565b005b61019f600480360381019061019a9190611dd2565b610482565b6040516101ac9190611cb7565b60405180910390f35b6101cf60048036038101906101ca9190611dff565b6104a1565b005b6101eb60048036038101906101e69190611dff565b6104c2565b005b61020760048036038101906102029190611d66565b610545565b6040516102149190611c83565b60405180910390f35b61023760048036038101906102329190611e3f565b61055c565b6040516102449190611e7b565b60405180910390f35b6102556105ef565b005b610271600480360381019061026c9190611dff565b610668565b60405161027e9190611c83565b60405180910390f35b61028f6106d2565b60405161029c9190611cb7565b60405180910390f35b6102ad6106d9565b6040516102ba9190611e7b565b60405180910390f35b6102dd60048036038101906102d89190611e3f565b6106df565b6040516102ea9190611e7b565b60405180910390f35b61030d60048036038101906103089190611dff565b610805565b005b61032960048036038101906103249190611f51565b610826565b6040516103369190611c83565b60405180910390f35b6103476109f0565b6040516103549190611e7b565b60405180910390f35b61037760048036038101906103729190611d66565b6109f6565b6040516103849190611c83565b60405180910390f35b610395610c0c565b6040516103a29190612031565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061041e575061041d82610c32565b5b9050919050565b7f7b765e0e932d348852a6f810bfa1ab891e259123f02db8cdcde614c57022335781565b7f7b765e0e932d348852a6f810bfa1ab891e259123f02db8cdcde614c57022335761047381610c9c565b61047d8383610cb0565b505050565b6000806000838152602001908152602001600020600101549050919050565b6104aa82610482565b6104b381610c9c565b6104bd8383610f10565b505050565b6104ca610ff0565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052e906120cf565b60405180910390fd5b6105418282610ff8565b5050565b60006105523384846110d9565b6001905092915050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546105e8919061211e565b9050919050565b7f7b765e0e932d348852a6f810bfa1ab891e259123f02db8cdcde614c57022335761061981610c9c565b60006001541461065e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610655906121c4565b60405180910390fd5b4260018190555050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000801b81565b60045481565b60008060015411156107fb576000610756600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461074660015442610741919061211e565b6113aa565b61ffff1661271061ffff16611466565b9050600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481116107a8576000915050610800565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054816107f3919061211e565b915050610800565b600090505b919050565b61080e82610482565b61081781610c9c565b6108218383610ff8565b505050565b60007f7b765e0e932d348852a6f810bfa1ab891e259123f02db8cdcde614c57022335761085281610c9c565b83839050868690501461089a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108919061227c565b60405180910390fd5b600086869050116108e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d7906122e8565b60405180910390fd5b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561094f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610973919061231d565b905060005b878790508110156109e1576109ce8289898481811061099a5761099961234a565b5b90506020020160208101906109af9190611e3f565b8888858181106109c2576109c161234a565b5b905060200201356110d9565b80806109d990612379565b915050610978565b50600192505050949350505050565b60015481565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5d90612433565b60405180910390fd5b60008211610aa9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa0906124c5565b60405180910390fd5b6000600154118015610abc575042600154105b610afb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af290612557565b60405180910390fd5b81610b05336106df565b1015610b46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3d9061260f565b60405180910390fd5b81600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610b95919061262f565b925050819055508160046000828254610bae919061211e565b92505081905550610c028383600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166115779092919063ffffffff16565b6001905092915050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610cad81610ca8610ff0565b6115fd565b50565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1690612433565b60405180910390fd5b60008111610d62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d59906126d5565b60405180910390fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610dbd9190612704565b602060405180830381865afa158015610dda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfe9190612734565b81600454610e0c919061262f565b1115610e4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e44906127d3565b60405180910390fd5b80600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610e9c919061262f565b925050819055508060046000828254610eb5919061262f565b925050819055508173ffffffffffffffffffffffffffffffffffffffff167f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f623383604051610f049291906127f3565b60405180910390a25050565b610f1a8282610668565b610fec57600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550610f91610ff0565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600033905090565b6110028282610668565b156110d557600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061107a610ff0565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6110e1611682565b80600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231856040518263ffffffff1660e01b815260040161113d9190612704565b602060405180830381865afa15801561115a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117e9190612734565b10156111bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111b69061288e565b60405180910390fd5b80600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e85306040518363ffffffff1660e01b815260040161121d9291906128ae565b602060405180830381865afa15801561123a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125e9190612734565b101561129f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129690612949565b60405180910390fd5b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166379cc679084836040518363ffffffff1660e01b81526004016112fc9291906127f3565b600060405180830381600087803b15801561131657600080fd5b505af115801561132a573d6000803e3d6000fd5b505050506113388282610cb0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f81aaa18332363199c2673bf9efd29fedf28c9cf21a0d14b986854c436993c06f836040516113959190611e7b565b60405180910390a36113a56116d1565b505050565b600080600090505b6005805490508160ff161080156113f057508260058260ff16815481106113dc576113db61234a565b5b906000526020600020906002020160000154105b1561140857808061140090612976565b9150506113b2565b60008160ff161161141a57600061145e565b6005600182611429919061299f565b60ff168154811061143d5761143c61234a565b5b906000526020600020906002020160010160009054906101000a900461ffff165b915050919050565b60008060008019858709858702925082811083820303915050600081036114a157838281611497576114966129d4565b5b0492505050611570565b8084116114e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114da90612a4f565b60405180910390fd5b60008486880990508281118203915080830392506000600186190186169050808604955080840493506001818260000304019050808302841793506000600287600302189050808702600203810290508087026002038102905080870260020381029050808702600203810290508087026002038102905080870260020381029050808502955050505050505b9392505050565b6115f88363a9059cbb60e01b84846040516024016115969291906127f3565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506116db565b505050565b6116078282610668565b61167e57611614816117a3565b6116228360001c60206117d0565b604051602001611633929190612b78565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116759190612bfc565b60405180910390fd5b5050565b6002600754036116c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116be90612c6a565b60405180910390fd5b6002600781905550565b6001600781905550565b600061173d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16611a0c9092919063ffffffff16565b905060008151148061175f57508080602001905181019061175e9190612cb6565b5b61179e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179590612d55565b60405180910390fd5b505050565b60606117c98273ffffffffffffffffffffffffffffffffffffffff16601460ff166117d0565b9050919050565b6060600060028360026117e39190612d75565b6117ed919061262f565b67ffffffffffffffff81111561180657611805612db7565b5b6040519080825280601f01601f1916602001820160405280156118385781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106118705761186f61234a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106118d4576118d361234a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026119149190612d75565b61191e919061262f565b90505b60018111156119be577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106119605761195f61234a565b5b1a60f81b8282815181106119775761197661234a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806119b790612de6565b9050611921565b5060008414611a02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f990612e5b565b60405180910390fd5b8091505092915050565b6060611a1b8484600085611a24565b90509392505050565b606082471015611a69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a6090612eed565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051611a929190612f54565b60006040518083038185875af1925050503d8060008114611acf576040519150601f19603f3d011682016040523d82523d6000602084013e611ad4565b606091505b5091509150611ae587838387611af1565b92505050949350505050565b60608315611b53576000835103611b4b57611b0b85611b66565b611b4a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4190612fb7565b60405180910390fd5b5b829050611b5e565b611b5d8383611b89565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600082511115611b9c5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd09190612bfc565b60405180910390fd5b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611c1881611be3565b8114611c2357600080fd5b50565b600081359050611c3581611c0f565b92915050565b600060208284031215611c5157611c50611bd9565b5b6000611c5f84828501611c26565b91505092915050565b60008115159050919050565b611c7d81611c68565b82525050565b6000602082019050611c986000830184611c74565b92915050565b6000819050919050565b611cb181611c9e565b82525050565b6000602082019050611ccc6000830184611ca8565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611cfd82611cd2565b9050919050565b611d0d81611cf2565b8114611d1857600080fd5b50565b600081359050611d2a81611d04565b92915050565b6000819050919050565b611d4381611d30565b8114611d4e57600080fd5b50565b600081359050611d6081611d3a565b92915050565b60008060408385031215611d7d57611d7c611bd9565b5b6000611d8b85828601611d1b565b9250506020611d9c85828601611d51565b9150509250929050565b611daf81611c9e565b8114611dba57600080fd5b50565b600081359050611dcc81611da6565b92915050565b600060208284031215611de857611de7611bd9565b5b6000611df684828501611dbd565b91505092915050565b60008060408385031215611e1657611e15611bd9565b5b6000611e2485828601611dbd565b9250506020611e3585828601611d1b565b9150509250929050565b600060208284031215611e5557611e54611bd9565b5b6000611e6384828501611d1b565b91505092915050565b611e7581611d30565b82525050565b6000602082019050611e906000830184611e6c565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611ebb57611eba611e96565b5b8235905067ffffffffffffffff811115611ed857611ed7611e9b565b5b602083019150836020820283011115611ef457611ef3611ea0565b5b9250929050565b60008083601f840112611f1157611f10611e96565b5b8235905067ffffffffffffffff811115611f2e57611f2d611e9b565b5b602083019150836020820283011115611f4a57611f49611ea0565b5b9250929050565b60008060008060408587031215611f6b57611f6a611bd9565b5b600085013567ffffffffffffffff811115611f8957611f88611bde565b5b611f9587828801611ea5565b9450945050602085013567ffffffffffffffff811115611fb857611fb7611bde565b5b611fc487828801611efb565b925092505092959194509250565b6000819050919050565b6000611ff7611ff2611fed84611cd2565b611fd2565b611cd2565b9050919050565b600061200982611fdc565b9050919050565b600061201b82611ffe565b9050919050565b61202b81612010565b82525050565b60006020820190506120466000830184612022565b92915050565b600082825260208201905092915050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b60006120b9602f8361204c565b91506120c48261205d565b604082019050919050565b600060208201905081810360008301526120e8816120ac565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061212982611d30565b915061213483611d30565b925082820390508181111561214c5761214b6120ef565b5b92915050565b7f5363686564756c6564546f6b656e53616c653a2053616c6520616c726561647960008201527f206c61756e636865640000000000000000000000000000000000000000000000602082015250565b60006121ae60298361204c565b91506121b982612152565b604082019050919050565b600060208201905081810360008301526121dd816121a1565b9050919050565b7f53656564546f6b656e53616c653a204e756d626572206f66207265636970696560008201527f6e74732073686f756c64206d61746368206e756d626572206f6620616d6f756e60208201527f7473000000000000000000000000000000000000000000000000000000000000604082015250565b600061226660428361204c565b9150612271826121e4565b606082019050919050565b6000602082019050818103600083015261229581612259565b9050919050565b7f53656564546f6b656e53616c653a204e6f20726563697069656e747300000000600082015250565b60006122d2601c8361204c565b91506122dd8261229c565b602082019050919050565b60006020820190508181036000830152612301816122c5565b9050919050565b60008151905061231781611d04565b92915050565b60006020828403121561233357612332611bd9565b5b600061234184828501612308565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061238482611d30565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036123b6576123b56120ef565b5b600182019050919050565b7f5363686564756c6564546f6b656e53616c653a20526563697069656e7420616460008201527f64726573732063616e6e6f74206265206e756c6c000000000000000000000000602082015250565b600061241d60348361204c565b9150612428826123c1565b604082019050919050565b6000602082019050818103600083015261244c81612410565b9050919050565b7f5363686564756c6564546f6b656e53616c653a20576974686472617720616d6f60008201527f756e74206d7573742062652067726561746572207468616e207a65726f000000602082015250565b60006124af603d8361204c565b91506124ba82612453565b604082019050919050565b600060208201905081810360008301526124de816124a2565b9050919050565b7f5363686564756c6564546f6b656e53616c653a20556e6c6f636b20736368656460008201527f756c65206e6f7420737461727465642079657400000000000000000000000000602082015250565b600061254160338361204c565b915061254c826124e5565b604082019050919050565b6000602082019050818103600083015261257081612534565b9050919050565b7f5363686564756c6564546f6b656e53616c653a20416d6f756e7420746f20776960008201527f7468647261772069732067726561746572207468616e20756e6c6f636b65642060208201527f616d6f756e740000000000000000000000000000000000000000000000000000604082015250565b60006125f960468361204c565b915061260482612577565b606082019050919050565b60006020820190508181036000830152612628816125ec565b9050919050565b600061263a82611d30565b915061264583611d30565b925082820190508082111561265d5761265c6120ef565b5b92915050565b7f5363686564756c6564546f6b656e53616c653a2042616c616e636520616d6f7560008201527f6e74206d7573742062652067726561746572207468616e207a65726f00000000602082015250565b60006126bf603c8361204c565b91506126ca82612663565b604082019050919050565b600060208201905081810360008301526126ee816126b2565b9050919050565b6126fe81611cf2565b82525050565b600060208201905061271960008301846126f5565b92915050565b60008151905061272e81611d3a565b92915050565b60006020828403121561274a57612749611bd9565b5b60006127588482850161271f565b91505092915050565b7f5363686564756c6564546f6b656e53616c653a20546f74616c2062616c616e6360008201527f65206578636565647320617661696c61626c652062616c616e63650000000000602082015250565b60006127bd603b8361204c565b91506127c882612761565b604082019050919050565b600060208201905081810360008301526127ec816127b0565b9050919050565b600060408201905061280860008301856126f5565b6128156020830184611e6c565b9392505050565b7f53656564546f6b656e53616c653a20496e73756666696369656e74204c65676160008201527f6379546f6b656e2062616c616e63650000000000000000000000000000000000602082015250565b6000612878602f8361204c565b91506128838261281c565b604082019050919050565b600060208201905081810360008301526128a78161286b565b9050919050565b60006040820190506128c360008301856126f5565b6128d060208301846126f5565b9392505050565b7f53656564546f6b656e53616c653a204e6f7420656e6f756768204c656761637960008201527f546f6b656e20616c6c6f77616e63650000000000000000000000000000000000602082015250565b6000612933602f8361204c565b915061293e826128d7565b604082019050919050565b6000602082019050818103600083015261296281612926565b9050919050565b600060ff82169050919050565b600061298182612969565b915060ff8203612994576129936120ef565b5b600182019050919050565b60006129aa82612969565b91506129b583612969565b9250828203905060ff8111156129ce576129cd6120ef565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4d6174683a206d756c446976206f766572666c6f770000000000000000000000600082015250565b6000612a3960158361204c565b9150612a4482612a03565b602082019050919050565b60006020820190508181036000830152612a6881612a2c565b9050919050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b6000612ab0601783612a6f565b9150612abb82612a7a565b601782019050919050565b600081519050919050565b60005b83811015612aef578082015181840152602081019050612ad4565b60008484015250505050565b6000612b0682612ac6565b612b108185612a6f565b9350612b20818560208601612ad1565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b6000612b62601183612a6f565b9150612b6d82612b2c565b601182019050919050565b6000612b8382612aa3565b9150612b8f8285612afb565b9150612b9a82612b55565b9150612ba68284612afb565b91508190509392505050565b6000601f19601f8301169050919050565b6000612bce82612ac6565b612bd8818561204c565b9350612be8818560208601612ad1565b612bf181612bb2565b840191505092915050565b60006020820190508181036000830152612c168184612bc3565b905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612c54601f8361204c565b9150612c5f82612c1e565b602082019050919050565b60006020820190508181036000830152612c8381612c47565b9050919050565b612c9381611c68565b8114612c9e57600080fd5b50565b600081519050612cb081612c8a565b92915050565b600060208284031215612ccc57612ccb611bd9565b5b6000612cda84828501612ca1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000612d3f602a8361204c565b9150612d4a82612ce3565b604082019050919050565b60006020820190508181036000830152612d6e81612d32565b9050919050565b6000612d8082611d30565b9150612d8b83611d30565b9250828202612d9981611d30565b91508282048414831517612db057612daf6120ef565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000612df182611d30565b915060008203612e0457612e036120ef565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000612e4560208361204c565b9150612e5082612e0f565b602082019050919050565b60006020820190508181036000830152612e7481612e38565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000612ed760268361204c565b9150612ee282612e7b565b604082019050919050565b60006020820190508181036000830152612f0681612eca565b9050919050565b600081519050919050565b600081905092915050565b6000612f2e82612f0d565b612f388185612f18565b9350612f48818560208601612ad1565b80840191505092915050565b6000612f608284612f23565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000612fa1601d8361204c565b9150612fac82612f6b565b602082019050919050565b60006020820190508181036000830152612fd081612f94565b905091905056fea2646970667358221220f25ae3e563f3e35ab2ae646394340bb58b040bd53db1e16e7275c1f6c241040164736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c8bf8bc34874e07f6a0d4abc8be22ba9e372631b00000000000000000000000085e5cc7bb799b5abe00fd8ebb3edd4ff095789b9
-----Decoded View---------------
Arg [0] : token (address): 0xc8bf8bC34874E07f6A0d4aBc8be22ba9E372631b
Arg [1] : tokenOld_ (address): 0x85E5cC7BB799B5aBE00Fd8eBb3EdD4FF095789b9
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c8bf8bc34874e07f6a0d4abc8be22ba9e372631b
Arg [1] : 00000000000000000000000085e5cc7bb799b5abe00fd8ebb3edd4ff095789b9
Deployed Bytecode Sourcemap
80384:2465:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31991:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57183:70;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58383:158;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;33814:131;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34255:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35399:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80866:175;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59431:142;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58112:263;;;:::i;:::-;;32287:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31392:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57486:27;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59581:586;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34695:149;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81049:571;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57321:41;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58549:874;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57691:19;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31991:204;32076:4;32115:32;32100:47;;;:11;:47;;;;:87;;;;32151:36;32175:11;32151:23;:36::i;:::-;32100:87;32093:94;;31991:204;;;:::o;57183:70::-;57225:28;57183:70;:::o;58383:158::-;57225:28;31883:16;31894:4;31883:10;:16::i;:::-;58510:23:::1;58522:2;58526:6;58510:11;:23::i;:::-;58383:158:::0;;;:::o;33814:131::-;33888:7;33915:6;:12;33922:4;33915:12;;;;;;;;;;;:22;;;33908:29;;33814:131;;;:::o;34255:147::-;34338:18;34351:4;34338:12;:18::i;:::-;31883:16;31894:4;31883:10;:16::i;:::-;34369:25:::1;34380:4;34386:7;34369:10;:25::i;:::-;34255:147:::0;;;:::o;35399:218::-;35506:12;:10;:12::i;:::-;35495:23;;:7;:23;;;35487:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;35583:26;35595:4;35601:7;35583:11;:26::i;:::-;35399:218;;:::o;80866:175::-;80962:4;80979:32;80988:10;81000:2;81004:6;80979:8;:32::i;:::-;81029:4;81022:11;;80866:175;;;;:::o;59431:142::-;59490:7;59538:18;:27;59557:7;59538:27;;;;;;;;;;;;;;;;59517:9;:18;59527:7;59517:18;;;;;;;;;;;;;;;;:48;;;;:::i;:::-;59510:55;;59431:142;;;:::o;58112:263::-;57225:28;31883:16;31894:4;31883:10;:16::i;:::-;58214:1:::1;58188:22;;:27;58180:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;58352:15;58327:22;:40;;;;58112:263:::0;:::o;32287:147::-;32373:4;32397:6;:12;32404:4;32397:12;;;;;;;;;;;:20;;:29;32418:7;32397:29;;;;;;;;;;;;;;;;;;;;;;;;;32390:36;;32287:147;;;;:::o;31392:49::-;31437:4;31392:49;;;:::o;57486:27::-;;;;:::o;59581:586::-;59639:7;59688:1;59663:22;;:26;59659:480;;;59706:21;59730:221;59760:9;:18;59770:7;59760:18;;;;;;;;;;;;;;;;59797:60;59834:22;;59816:15;:40;;;;:::i;:::-;59797:18;:60::i;:::-;59730:221;;57306:6;59730:221;;:11;:221::i;:::-;59706:245;;59989:18;:27;60008:7;59989:27;;;;;;;;;;;;;;;;59972:13;:44;59968:93;;60044:1;60037:8;;;;;59968:93;60100:18;:27;60119:7;60100:27;;;;;;;;;;;;;;;;60084:13;:43;;;;:::i;:::-;60077:50;;;;;59659:480;60158:1;60151:8;;59581:586;;;;:::o;34695:149::-;34779:18;34792:4;34779:12;:18::i;:::-;31883:16;31894:4;31883:10;:16::i;:::-;34810:26:::1;34822:4;34828:7;34810:11;:26::i;:::-;34695:149:::0;;;:::o;81049:571::-;81193:4;57225:28;31883:16;31894:4;31883:10;:16::i;:::-;81245:6:::1;;:13;;81232:2;;:9;;:26;81210:142;;;;;;;;;;;;:::i;:::-;;;;;;;;;81383:1;81371:2;;:9;;:13;81363:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;81430:21;81454:8;;;;;;;;;;;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81430:40;;81486:9;81481:108;81505:2;;:9;;81501:1;:13;81481:108;;;81536:41;81545:13;81560:2;;81563:1;81560:5;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;81567:6;;81574:1;81567:9;;;;;;;:::i;:::-;;;;;;;;81536:8;:41::i;:::-;81516:3;;;;;:::i;:::-;;;;81481:108;;;;81608:4;81601:11;;;81049:571:::0;;;;;;;:::o;57321:41::-;;;;:::o;58549:874::-;58613:4;58666:1;58652:16;;:2;:16;;;58630:118;;;;;;;;;;;;:::i;:::-;;;;;;;;;58790:1;58781:6;:10;58759:121;;;;;;;;;;;;:::i;:::-;;;;;;;;;58938:1;58913:22;;:26;:70;;;;;58968:15;58943:22;;:40;58913:70;58891:212;;;;;;;;;;;;:::i;:::-;;;;;;;;;59162:6;59136:22;59147:10;59136;:22::i;:::-;:32;;59114:152;;;;;;;;;;;;:::i;:::-;;;;;;;;;59313:6;59279:18;:30;59298:10;59279:30;;;;;;;;;;;;;;;;:40;;;;;;;:::i;:::-;;;;;;;;59346:6;59330:12;;:22;;;;;;;:::i;:::-;;;;;;;;59363:30;59382:2;59386:6;59363:5;;;;;;;;;;;:18;;;;:30;;;;;:::i;:::-;59411:4;59404:11;;58549:874;;;;:::o;57691:19::-;;;;;;;;;;;;;:::o;29123:157::-;29208:4;29247:25;29232:40;;;:11;:40;;;;29225:47;;29123:157;;;:::o;32738:105::-;32805:30;32816:4;32822:12;:10;:12::i;:::-;32805:10;:30::i;:::-;32738:105;:::o;60515:619::-;60620:1;60606:16;;:2;:16;;;60584:118;;;;;;;;;;;;:::i;:::-;;;;;;;;;60744:1;60735:6;:10;60713:120;;;;;;;;;;;;:::i;:::-;;;;;;;;;60891:5;;;;;;;;;;;:15;;;60915:4;60891:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60881:6;60866:12;;:21;;;;:::i;:::-;:55;;60844:164;;;;;;;;;;;;:::i;:::-;;;;;;;;;61038:6;61021:9;:13;61031:2;61021:13;;;;;;;;;;;;;;;;:23;;;;;;;:::i;:::-;;;;;;;;61071:6;61055:12;;:22;;;;;;;:::i;:::-;;;;;;;;61115:2;61095:31;;;61103:10;61119:6;61095:31;;;;;;;:::i;:::-;;;;;;;;60515:619;;:::o;36996:238::-;37080:22;37088:4;37094:7;37080;:22::i;:::-;37075:152;;37151:4;37119:6;:12;37126:4;37119:12;;;;;;;;;;;:20;;:29;37140:7;37119:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;37202:12;:10;:12::i;:::-;37175:40;;37193:7;37175:40;;37187:4;37175:40;;;;;;;;;;37075:152;36996:238;;:::o;9805:98::-;9858:7;9885:10;9878:17;;9805:98;:::o;37414:239::-;37498:22;37506:4;37512:7;37498;:22::i;:::-;37494:152;;;37569:5;37537:6;:12;37544:4;37537:12;;;;;;;;;;;:20;;:29;37558:7;37537:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;37621:12;:10;:12::i;:::-;37594:40;;37612:7;37594:40;;37606:4;37594:40;;;;;;;;;;37494:152;37414:239;;:::o;81628:559::-;2345:21;:19;:21::i;:::-;81813:6:::1;81785:8;;;;;;;;;;;:18;;;81804:4;81785:24;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:34;;81763:131;;;;;;;;;;;;:::i;:::-;;;;;;;;;81970:6;81927:8;;;;;;;;;;;:18;;;81946:4;81960;81927:39;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:49;;81905:146;;;;;;;;;;;;:::i;:::-;;;;;;;;;82064:8;;;;;;;;;;;:17;;;82082:4;82088:6;82064:31;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;82106:23;82118:2;82122:6;82106:11;:23::i;:::-;82168:2;82147:32;;82162:4;82147:32;;;82172:6;82147:32;;;;;;:::i;:::-;;;;;;;;2389:20:::0;:18;:20::i;:::-;81628:559;;;:::o;60175:332::-;60265:6;60284:11;60298:1;60284:15;;60310:105;60324:14;:21;;;;60316:5;:29;;;:85;;;;;60388:13;60349:14;60364:5;60349:21;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;:52;60316:85;60310:105;;;60405:7;;;;;:::i;:::-;;;;60310:105;;;60442:1;60434:5;:9;;;:65;;60498:1;60434:65;;;60446:14;60469:1;60461:5;:9;;;;:::i;:::-;60446:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;:49;;;;;;;;;;;;60434:65;60427:72;;;60175:332;;;:::o;11765:4292::-;11847:14;12199:13;12272;12399:1;12395:6;12392:1;12389;12382:20;12436:1;12433;12429:9;12420:18;;12492:5;12488:2;12485:13;12477:5;12473:2;12469:14;12465:34;12456:43;;12353:161;12607:1;12598:5;:10;12594:373;;12940:11;12932:5;:19;;;;;:::i;:::-;;;12925:26;;;;;;12594:373;13094:5;13080:11;:19;13072:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;13388:17;13526:11;13523:1;13520;13513:25;13500:38;;13657:5;13646:9;13643:20;13636:5;13632:32;13623:41;;13702:9;13695:5;13691:21;13682:30;;14040:12;14085:1;14071:11;14070:12;:16;14055:11;:32;14040:47;;14210:4;14197:11;14193:22;14178:37;;14305:4;14298:5;14294:16;14285:25;;14465:1;14458:4;14451;14448:1;14444:12;14440:23;14436:31;14428:39;;14568:4;14560:5;:12;14551:21;;;;14895:15;14933:1;14918:11;14914:1;:15;14913:21;14895:39;;15184:7;15170:11;:21;15166:1;:25;15155:36;;;;15254:7;15240:11;:21;15236:1;:25;15225:36;;;;15325:7;15311:11;:21;15307:1;:25;15296:36;;;;15396:7;15382:11;:21;15378:1;:25;15367:36;;;;15467:7;15453:11;:21;15449:1;:25;15438:36;;;;15539:7;15525:11;:21;15521:1;:25;15510:36;;;;16003:7;15995:5;:15;15986:24;;16025:13;;;;;11765:4292;;;;;;:::o;50563:177::-;50646:86;50666:5;50696:23;;;50721:2;50725:5;50673:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50646:19;:86::i;:::-;50563:177;;;:::o;33133:492::-;33222:22;33230:4;33236:7;33222;:22::i;:::-;33217:401;;33410:28;33430:7;33410:19;:28::i;:::-;33511:38;33539:4;33531:13;;33546:2;33511:19;:38::i;:::-;33315:257;;;;;;;;;:::i;:::-;;;;;;;;;;;;;33261:345;;;;;;;;;;;:::i;:::-;;;;;;;;33217:401;33133:492;;:::o;2425:293::-;1827:1;2559:7;;:19;2551:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1827:1;2692:7;:18;;;;2425:293::o;2726:213::-;1783:1;2909:7;:22;;;;2726:213::o;54886:649::-;55310:23;55336:69;55364:4;55336:69;;;;;;;;;;;;;;;;;55344:5;55336:27;;;;:69;;;;;:::i;:::-;55310:95;;55445:1;55424:10;:17;:22;:56;;;;55461:10;55450:30;;;;;;;;;;;;:::i;:::-;55424:56;55416:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;54956:579;54886:649;;:::o;26955:151::-;27013:13;27046:52;27074:4;27058:22;;24830:2;27046:52;;:11;:52::i;:::-;27039:59;;26955:151;;;:::o;26351:447::-;26426:13;26452:19;26497:1;26488:6;26484:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;26474:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26452:47;;26510:15;:6;26517:1;26510:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;26536;:6;26543:1;26536:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;26567:9;26592:1;26583:6;26579:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;26567:26;;26562:131;26599:1;26595;:5;26562:131;;;26634:8;26651:3;26643:5;:11;26634:21;;;;;;;:::i;:::-;;;;;26622:6;26629:1;26622:9;;;;;;;;:::i;:::-;;;;;:33;;;;;;;;;;;26680:1;26670:11;;;;;26602:3;;;;:::i;:::-;;;26562:131;;;;26720:1;26711:5;:10;26703:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;26783:6;26769:21;;;26351:447;;;;:::o;44257:229::-;44394:12;44426:52;44448:6;44456:4;44462:1;44465:12;44426:21;:52::i;:::-;44419:59;;44257:229;;;;;:::o;45343:455::-;45513:12;45571:5;45546:21;:30;;45538:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;45631:12;45645:23;45672:6;:11;;45691:5;45698:4;45672:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45630:73;;;;45721:69;45748:6;45756:7;45765:10;45777:12;45721:26;:69::i;:::-;45714:76;;;;45343:455;;;;;;:::o;47916:644::-;48101:12;48130:7;48126:427;;;48179:1;48158:10;:17;:22;48154:290;;48376:18;48387:6;48376:10;:18::i;:::-;48368:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;48154:290;48465:10;48458:17;;;;48126:427;48508:33;48516:10;48528:12;48508:7;:33::i;:::-;47916:644;;;;;;;:::o;41502:326::-;41562:4;41819:1;41797:7;:19;;;:23;41790:30;;41502:326;;;:::o;49102:552::-;49283:1;49263:10;:17;:21;49259:388;;;49495:10;49489:17;49552:15;49539:10;49535:2;49531:19;49524:44;49259:388;49622:12;49615:20;;;;;;;;;;;:::i;:::-;;;;;;;;88:117:1;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:77::-;1555:7;1584:5;1573:16;;1518:77;;;:::o;1601:118::-;1688:24;1706:5;1688:24;:::i;:::-;1683:3;1676:37;1601:118;;:::o;1725:222::-;1818:4;1856:2;1845:9;1841:18;1833:26;;1869:71;1937:1;1926:9;1922:17;1913:6;1869:71;:::i;:::-;1725:222;;;;:::o;1953:126::-;1990:7;2030:42;2023:5;2019:54;2008:65;;1953:126;;;:::o;2085:96::-;2122:7;2151:24;2169:5;2151:24;:::i;:::-;2140:35;;2085:96;;;:::o;2187:122::-;2260:24;2278:5;2260:24;:::i;:::-;2253:5;2250:35;2240:63;;2299:1;2296;2289:12;2240:63;2187:122;:::o;2315:139::-;2361:5;2399:6;2386:20;2377:29;;2415:33;2442:5;2415:33;:::i;:::-;2315:139;;;;:::o;2460:77::-;2497:7;2526:5;2515:16;;2460:77;;;:::o;2543:122::-;2616:24;2634:5;2616:24;:::i;:::-;2609:5;2606:35;2596:63;;2655:1;2652;2645:12;2596:63;2543:122;:::o;2671:139::-;2717:5;2755:6;2742:20;2733:29;;2771:33;2798:5;2771:33;:::i;:::-;2671:139;;;;:::o;2816:474::-;2884:6;2892;2941:2;2929:9;2920:7;2916:23;2912:32;2909:119;;;2947:79;;:::i;:::-;2909:119;3067:1;3092:53;3137:7;3128:6;3117:9;3113:22;3092:53;:::i;:::-;3082:63;;3038:117;3194:2;3220:53;3265:7;3256:6;3245:9;3241:22;3220:53;:::i;:::-;3210:63;;3165:118;2816:474;;;;;:::o;3296:122::-;3369:24;3387:5;3369:24;:::i;:::-;3362:5;3359:35;3349:63;;3408:1;3405;3398:12;3349:63;3296:122;:::o;3424:139::-;3470:5;3508:6;3495:20;3486:29;;3524:33;3551:5;3524:33;:::i;:::-;3424:139;;;;:::o;3569:329::-;3628:6;3677:2;3665:9;3656:7;3652:23;3648:32;3645:119;;;3683:79;;:::i;:::-;3645:119;3803:1;3828:53;3873:7;3864:6;3853:9;3849:22;3828:53;:::i;:::-;3818:63;;3774:117;3569:329;;;;:::o;3904:474::-;3972:6;3980;4029:2;4017:9;4008:7;4004:23;4000:32;3997:119;;;4035:79;;:::i;:::-;3997:119;4155:1;4180:53;4225:7;4216:6;4205:9;4201:22;4180:53;:::i;:::-;4170:63;;4126:117;4282:2;4308:53;4353:7;4344:6;4333:9;4329:22;4308:53;:::i;:::-;4298:63;;4253:118;3904:474;;;;;:::o;4384:329::-;4443:6;4492:2;4480:9;4471:7;4467:23;4463:32;4460:119;;;4498:79;;:::i;:::-;4460:119;4618:1;4643:53;4688:7;4679:6;4668:9;4664:22;4643:53;:::i;:::-;4633:63;;4589:117;4384:329;;;;:::o;4719:118::-;4806:24;4824:5;4806:24;:::i;:::-;4801:3;4794:37;4719:118;;:::o;4843:222::-;4936:4;4974:2;4963:9;4959:18;4951:26;;4987:71;5055:1;5044:9;5040:17;5031:6;4987:71;:::i;:::-;4843:222;;;;:::o;5071:117::-;5180:1;5177;5170:12;5194:117;5303:1;5300;5293:12;5317:117;5426:1;5423;5416:12;5457:568;5530:8;5540:6;5590:3;5583:4;5575:6;5571:17;5567:27;5557:122;;5598:79;;:::i;:::-;5557:122;5711:6;5698:20;5688:30;;5741:18;5733:6;5730:30;5727:117;;;5763:79;;:::i;:::-;5727:117;5877:4;5869:6;5865:17;5853:29;;5931:3;5923:4;5915:6;5911:17;5901:8;5897:32;5894:41;5891:128;;;5938:79;;:::i;:::-;5891:128;5457:568;;;;;:::o;6048:::-;6121:8;6131:6;6181:3;6174:4;6166:6;6162:17;6158:27;6148:122;;6189:79;;:::i;:::-;6148:122;6302:6;6289:20;6279:30;;6332:18;6324:6;6321:30;6318:117;;;6354:79;;:::i;:::-;6318:117;6468:4;6460:6;6456:17;6444:29;;6522:3;6514:4;6506:6;6502:17;6492:8;6488:32;6485:41;6482:128;;;6529:79;;:::i;:::-;6482:128;6048:568;;;;;:::o;6622:934::-;6744:6;6752;6760;6768;6817:2;6805:9;6796:7;6792:23;6788:32;6785:119;;;6823:79;;:::i;:::-;6785:119;6971:1;6960:9;6956:17;6943:31;7001:18;6993:6;6990:30;6987:117;;;7023:79;;:::i;:::-;6987:117;7136:80;7208:7;7199:6;7188:9;7184:22;7136:80;:::i;:::-;7118:98;;;;6914:312;7293:2;7282:9;7278:18;7265:32;7324:18;7316:6;7313:30;7310:117;;;7346:79;;:::i;:::-;7310:117;7459:80;7531:7;7522:6;7511:9;7507:22;7459:80;:::i;:::-;7441:98;;;;7236:313;6622:934;;;;;;;:::o;7562:60::-;7590:3;7611:5;7604:12;;7562:60;;;:::o;7628:142::-;7678:9;7711:53;7729:34;7738:24;7756:5;7738:24;:::i;:::-;7729:34;:::i;:::-;7711:53;:::i;:::-;7698:66;;7628:142;;;:::o;7776:126::-;7826:9;7859:37;7890:5;7859:37;:::i;:::-;7846:50;;7776:126;;;:::o;7908:140::-;7972:9;8005:37;8036:5;8005:37;:::i;:::-;7992:50;;7908:140;;;:::o;8054:159::-;8155:51;8200:5;8155:51;:::i;:::-;8150:3;8143:64;8054:159;;:::o;8219:250::-;8326:4;8364:2;8353:9;8349:18;8341:26;;8377:85;8459:1;8448:9;8444:17;8435:6;8377:85;:::i;:::-;8219:250;;;;:::o;8475:169::-;8559:11;8593:6;8588:3;8581:19;8633:4;8628:3;8624:14;8609:29;;8475:169;;;;:::o;8650:234::-;8790:34;8786:1;8778:6;8774:14;8767:58;8859:17;8854:2;8846:6;8842:15;8835:42;8650:234;:::o;8890:366::-;9032:3;9053:67;9117:2;9112:3;9053:67;:::i;:::-;9046:74;;9129:93;9218:3;9129:93;:::i;:::-;9247:2;9242:3;9238:12;9231:19;;8890:366;;;:::o;9262:419::-;9428:4;9466:2;9455:9;9451:18;9443:26;;9515:9;9509:4;9505:20;9501:1;9490:9;9486:17;9479:47;9543:131;9669:4;9543:131;:::i;:::-;9535:139;;9262:419;;;:::o;9687:180::-;9735:77;9732:1;9725:88;9832:4;9829:1;9822:15;9856:4;9853:1;9846:15;9873:194;9913:4;9933:20;9951:1;9933:20;:::i;:::-;9928:25;;9967:20;9985:1;9967:20;:::i;:::-;9962:25;;10011:1;10008;10004:9;9996:17;;10035:1;10029:4;10026:11;10023:37;;;10040:18;;:::i;:::-;10023:37;9873:194;;;;:::o;10073:228::-;10213:34;10209:1;10201:6;10197:14;10190:58;10282:11;10277:2;10269:6;10265:15;10258:36;10073:228;:::o;10307:366::-;10449:3;10470:67;10534:2;10529:3;10470:67;:::i;:::-;10463:74;;10546:93;10635:3;10546:93;:::i;:::-;10664:2;10659:3;10655:12;10648:19;;10307:366;;;:::o;10679:419::-;10845:4;10883:2;10872:9;10868:18;10860:26;;10932:9;10926:4;10922:20;10918:1;10907:9;10903:17;10896:47;10960:131;11086:4;10960:131;:::i;:::-;10952:139;;10679:419;;;:::o;11104:290::-;11244:34;11240:1;11232:6;11228:14;11221:58;11313:34;11308:2;11300:6;11296:15;11289:59;11382:4;11377:2;11369:6;11365:15;11358:29;11104:290;:::o;11400:366::-;11542:3;11563:67;11627:2;11622:3;11563:67;:::i;:::-;11556:74;;11639:93;11728:3;11639:93;:::i;:::-;11757:2;11752:3;11748:12;11741:19;;11400:366;;;:::o;11772:419::-;11938:4;11976:2;11965:9;11961:18;11953:26;;12025:9;12019:4;12015:20;12011:1;12000:9;11996:17;11989:47;12053:131;12179:4;12053:131;:::i;:::-;12045:139;;11772:419;;;:::o;12197:178::-;12337:30;12333:1;12325:6;12321:14;12314:54;12197:178;:::o;12381:366::-;12523:3;12544:67;12608:2;12603:3;12544:67;:::i;:::-;12537:74;;12620:93;12709:3;12620:93;:::i;:::-;12738:2;12733:3;12729:12;12722:19;;12381:366;;;:::o;12753:419::-;12919:4;12957:2;12946:9;12942:18;12934:26;;13006:9;13000:4;12996:20;12992:1;12981:9;12977:17;12970:47;13034:131;13160:4;13034:131;:::i;:::-;13026:139;;12753:419;;;:::o;13178:143::-;13235:5;13266:6;13260:13;13251:22;;13282:33;13309:5;13282:33;:::i;:::-;13178:143;;;;:::o;13327:351::-;13397:6;13446:2;13434:9;13425:7;13421:23;13417:32;13414:119;;;13452:79;;:::i;:::-;13414:119;13572:1;13597:64;13653:7;13644:6;13633:9;13629:22;13597:64;:::i;:::-;13587:74;;13543:128;13327:351;;;;:::o;13684:180::-;13732:77;13729:1;13722:88;13829:4;13826:1;13819:15;13853:4;13850:1;13843:15;13870:233;13909:3;13932:24;13950:5;13932:24;:::i;:::-;13923:33;;13978:66;13971:5;13968:77;13965:103;;14048:18;;:::i;:::-;13965:103;14095:1;14088:5;14084:13;14077:20;;13870:233;;;:::o;14109:239::-;14249:34;14245:1;14237:6;14233:14;14226:58;14318:22;14313:2;14305:6;14301:15;14294:47;14109:239;:::o;14354:366::-;14496:3;14517:67;14581:2;14576:3;14517:67;:::i;:::-;14510:74;;14593:93;14682:3;14593:93;:::i;:::-;14711:2;14706:3;14702:12;14695:19;;14354:366;;;:::o;14726:419::-;14892:4;14930:2;14919:9;14915:18;14907:26;;14979:9;14973:4;14969:20;14965:1;14954:9;14950:17;14943:47;15007:131;15133:4;15007:131;:::i;:::-;14999:139;;14726:419;;;:::o;15151:248::-;15291:34;15287:1;15279:6;15275:14;15268:58;15360:31;15355:2;15347:6;15343:15;15336:56;15151:248;:::o;15405:366::-;15547:3;15568:67;15632:2;15627:3;15568:67;:::i;:::-;15561:74;;15644:93;15733:3;15644:93;:::i;:::-;15762:2;15757:3;15753:12;15746:19;;15405:366;;;:::o;15777:419::-;15943:4;15981:2;15970:9;15966:18;15958:26;;16030:9;16024:4;16020:20;16016:1;16005:9;16001:17;15994:47;16058:131;16184:4;16058:131;:::i;:::-;16050:139;;15777:419;;;:::o;16202:238::-;16342:34;16338:1;16330:6;16326:14;16319:58;16411:21;16406:2;16398:6;16394:15;16387:46;16202:238;:::o;16446:366::-;16588:3;16609:67;16673:2;16668:3;16609:67;:::i;:::-;16602:74;;16685:93;16774:3;16685:93;:::i;:::-;16803:2;16798:3;16794:12;16787:19;;16446:366;;;:::o;16818:419::-;16984:4;17022:2;17011:9;17007:18;16999:26;;17071:9;17065:4;17061:20;17057:1;17046:9;17042:17;17035:47;17099:131;17225:4;17099:131;:::i;:::-;17091:139;;16818:419;;;:::o;17243:294::-;17383:34;17379:1;17371:6;17367:14;17360:58;17452:34;17447:2;17439:6;17435:15;17428:59;17521:8;17516:2;17508:6;17504:15;17497:33;17243:294;:::o;17543:366::-;17685:3;17706:67;17770:2;17765:3;17706:67;:::i;:::-;17699:74;;17782:93;17871:3;17782:93;:::i;:::-;17900:2;17895:3;17891:12;17884:19;;17543:366;;;:::o;17915:419::-;18081:4;18119:2;18108:9;18104:18;18096:26;;18168:9;18162:4;18158:20;18154:1;18143:9;18139:17;18132:47;18196:131;18322:4;18196:131;:::i;:::-;18188:139;;17915:419;;;:::o;18340:191::-;18380:3;18399:20;18417:1;18399:20;:::i;:::-;18394:25;;18433:20;18451:1;18433:20;:::i;:::-;18428:25;;18476:1;18473;18469:9;18462:16;;18497:3;18494:1;18491:10;18488:36;;;18504:18;;:::i;:::-;18488:36;18340:191;;;;:::o;18537:247::-;18677:34;18673:1;18665:6;18661:14;18654:58;18746:30;18741:2;18733:6;18729:15;18722:55;18537:247;:::o;18790:366::-;18932:3;18953:67;19017:2;19012:3;18953:67;:::i;:::-;18946:74;;19029:93;19118:3;19029:93;:::i;:::-;19147:2;19142:3;19138:12;19131:19;;18790:366;;;:::o;19162:419::-;19328:4;19366:2;19355:9;19351:18;19343:26;;19415:9;19409:4;19405:20;19401:1;19390:9;19386:17;19379:47;19443:131;19569:4;19443:131;:::i;:::-;19435:139;;19162:419;;;:::o;19587:118::-;19674:24;19692:5;19674:24;:::i;:::-;19669:3;19662:37;19587:118;;:::o;19711:222::-;19804:4;19842:2;19831:9;19827:18;19819:26;;19855:71;19923:1;19912:9;19908:17;19899:6;19855:71;:::i;:::-;19711:222;;;;:::o;19939:143::-;19996:5;20027:6;20021:13;20012:22;;20043:33;20070:5;20043:33;:::i;:::-;19939:143;;;;:::o;20088:351::-;20158:6;20207:2;20195:9;20186:7;20182:23;20178:32;20175:119;;;20213:79;;:::i;:::-;20175:119;20333:1;20358:64;20414:7;20405:6;20394:9;20390:22;20358:64;:::i;:::-;20348:74;;20304:128;20088:351;;;;:::o;20445:246::-;20585:34;20581:1;20573:6;20569:14;20562:58;20654:29;20649:2;20641:6;20637:15;20630:54;20445:246;:::o;20697:366::-;20839:3;20860:67;20924:2;20919:3;20860:67;:::i;:::-;20853:74;;20936:93;21025:3;20936:93;:::i;:::-;21054:2;21049:3;21045:12;21038:19;;20697:366;;;:::o;21069:419::-;21235:4;21273:2;21262:9;21258:18;21250:26;;21322:9;21316:4;21312:20;21308:1;21297:9;21293:17;21286:47;21350:131;21476:4;21350:131;:::i;:::-;21342:139;;21069:419;;;:::o;21494:332::-;21615:4;21653:2;21642:9;21638:18;21630:26;;21666:71;21734:1;21723:9;21719:17;21710:6;21666:71;:::i;:::-;21747:72;21815:2;21804:9;21800:18;21791:6;21747:72;:::i;:::-;21494:332;;;;;:::o;21832:234::-;21972:34;21968:1;21960:6;21956:14;21949:58;22041:17;22036:2;22028:6;22024:15;22017:42;21832:234;:::o;22072:366::-;22214:3;22235:67;22299:2;22294:3;22235:67;:::i;:::-;22228:74;;22311:93;22400:3;22311:93;:::i;:::-;22429:2;22424:3;22420:12;22413:19;;22072:366;;;:::o;22444:419::-;22610:4;22648:2;22637:9;22633:18;22625:26;;22697:9;22691:4;22687:20;22683:1;22672:9;22668:17;22661:47;22725:131;22851:4;22725:131;:::i;:::-;22717:139;;22444:419;;;:::o;22869:332::-;22990:4;23028:2;23017:9;23013:18;23005:26;;23041:71;23109:1;23098:9;23094:17;23085:6;23041:71;:::i;:::-;23122:72;23190:2;23179:9;23175:18;23166:6;23122:72;:::i;:::-;22869:332;;;;;:::o;23207:234::-;23347:34;23343:1;23335:6;23331:14;23324:58;23416:17;23411:2;23403:6;23399:15;23392:42;23207:234;:::o;23447:366::-;23589:3;23610:67;23674:2;23669:3;23610:67;:::i;:::-;23603:74;;23686:93;23775:3;23686:93;:::i;:::-;23804:2;23799:3;23795:12;23788:19;;23447:366;;;:::o;23819:419::-;23985:4;24023:2;24012:9;24008:18;24000:26;;24072:9;24066:4;24062:20;24058:1;24047:9;24043:17;24036:47;24100:131;24226:4;24100:131;:::i;:::-;24092:139;;23819:419;;;:::o;24244:86::-;24279:7;24319:4;24312:5;24308:16;24297:27;;24244:86;;;:::o;24336:167::-;24373:3;24396:22;24412:5;24396:22;:::i;:::-;24387:31;;24440:4;24433:5;24430:15;24427:41;;24448:18;;:::i;:::-;24427:41;24495:1;24488:5;24484:13;24477:20;;24336:167;;;:::o;24509:191::-;24547:4;24567:18;24583:1;24567:18;:::i;:::-;24562:23;;24599:18;24615:1;24599:18;:::i;:::-;24594:23;;24641:1;24638;24634:9;24626:17;;24665:4;24659;24656:14;24653:40;;;24673:18;;:::i;:::-;24653:40;24509:191;;;;:::o;24706:180::-;24754:77;24751:1;24744:88;24851:4;24848:1;24841:15;24875:4;24872:1;24865:15;24892:171;25032:23;25028:1;25020:6;25016:14;25009:47;24892:171;:::o;25069:366::-;25211:3;25232:67;25296:2;25291:3;25232:67;:::i;:::-;25225:74;;25308:93;25397:3;25308:93;:::i;:::-;25426:2;25421:3;25417:12;25410:19;;25069:366;;;:::o;25441:419::-;25607:4;25645:2;25634:9;25630:18;25622:26;;25694:9;25688:4;25684:20;25680:1;25669:9;25665:17;25658:47;25722:131;25848:4;25722:131;:::i;:::-;25714:139;;25441:419;;;:::o;25866:148::-;25968:11;26005:3;25990:18;;25866:148;;;;:::o;26020:173::-;26160:25;26156:1;26148:6;26144:14;26137:49;26020:173;:::o;26199:402::-;26359:3;26380:85;26462:2;26457:3;26380:85;:::i;:::-;26373:92;;26474:93;26563:3;26474:93;:::i;:::-;26592:2;26587:3;26583:12;26576:19;;26199:402;;;:::o;26607:99::-;26659:6;26693:5;26687:12;26677:22;;26607:99;;;:::o;26712:246::-;26793:1;26803:113;26817:6;26814:1;26811:13;26803:113;;;26902:1;26897:3;26893:11;26887:18;26883:1;26878:3;26874:11;26867:39;26839:2;26836:1;26832:10;26827:15;;26803:113;;;26950:1;26941:6;26936:3;26932:16;26925:27;26774:184;26712:246;;;:::o;26964:390::-;27070:3;27098:39;27131:5;27098:39;:::i;:::-;27153:89;27235:6;27230:3;27153:89;:::i;:::-;27146:96;;27251:65;27309:6;27304:3;27297:4;27290:5;27286:16;27251:65;:::i;:::-;27341:6;27336:3;27332:16;27325:23;;27074:280;26964:390;;;;:::o;27360:167::-;27500:19;27496:1;27488:6;27484:14;27477:43;27360:167;:::o;27533:402::-;27693:3;27714:85;27796:2;27791:3;27714:85;:::i;:::-;27707:92;;27808:93;27897:3;27808:93;:::i;:::-;27926:2;27921:3;27917:12;27910:19;;27533:402;;;:::o;27941:967::-;28323:3;28345:148;28489:3;28345:148;:::i;:::-;28338:155;;28510:95;28601:3;28592:6;28510:95;:::i;:::-;28503:102;;28622:148;28766:3;28622:148;:::i;:::-;28615:155;;28787:95;28878:3;28869:6;28787:95;:::i;:::-;28780:102;;28899:3;28892:10;;27941:967;;;;;:::o;28914:102::-;28955:6;29006:2;29002:7;28997:2;28990:5;28986:14;28982:28;28972:38;;28914:102;;;:::o;29022:377::-;29110:3;29138:39;29171:5;29138:39;:::i;:::-;29193:71;29257:6;29252:3;29193:71;:::i;:::-;29186:78;;29273:65;29331:6;29326:3;29319:4;29312:5;29308:16;29273:65;:::i;:::-;29363:29;29385:6;29363:29;:::i;:::-;29358:3;29354:39;29347:46;;29114:285;29022:377;;;;:::o;29405:313::-;29518:4;29556:2;29545:9;29541:18;29533:26;;29605:9;29599:4;29595:20;29591:1;29580:9;29576:17;29569:47;29633:78;29706:4;29697:6;29633:78;:::i;:::-;29625:86;;29405:313;;;;:::o;29724:181::-;29864:33;29860:1;29852:6;29848:14;29841:57;29724:181;:::o;29911:366::-;30053:3;30074:67;30138:2;30133:3;30074:67;:::i;:::-;30067:74;;30150:93;30239:3;30150:93;:::i;:::-;30268:2;30263:3;30259:12;30252:19;;29911:366;;;:::o;30283:419::-;30449:4;30487:2;30476:9;30472:18;30464:26;;30536:9;30530:4;30526:20;30522:1;30511:9;30507:17;30500:47;30564:131;30690:4;30564:131;:::i;:::-;30556:139;;30283:419;;;:::o;30708:116::-;30778:21;30793:5;30778:21;:::i;:::-;30771:5;30768:32;30758:60;;30814:1;30811;30804:12;30758:60;30708:116;:::o;30830:137::-;30884:5;30915:6;30909:13;30900:22;;30931:30;30955:5;30931:30;:::i;:::-;30830:137;;;;:::o;30973:345::-;31040:6;31089:2;31077:9;31068:7;31064:23;31060:32;31057:119;;;31095:79;;:::i;:::-;31057:119;31215:1;31240:61;31293:7;31284:6;31273:9;31269:22;31240:61;:::i;:::-;31230:71;;31186:125;30973:345;;;;:::o;31324:229::-;31464:34;31460:1;31452:6;31448:14;31441:58;31533:12;31528:2;31520:6;31516:15;31509:37;31324:229;:::o;31559:366::-;31701:3;31722:67;31786:2;31781:3;31722:67;:::i;:::-;31715:74;;31798:93;31887:3;31798:93;:::i;:::-;31916:2;31911:3;31907:12;31900:19;;31559:366;;;:::o;31931:419::-;32097:4;32135:2;32124:9;32120:18;32112:26;;32184:9;32178:4;32174:20;32170:1;32159:9;32155:17;32148:47;32212:131;32338:4;32212:131;:::i;:::-;32204:139;;31931:419;;;:::o;32356:410::-;32396:7;32419:20;32437:1;32419:20;:::i;:::-;32414:25;;32453:20;32471:1;32453:20;:::i;:::-;32448:25;;32508:1;32505;32501:9;32530:30;32548:11;32530:30;:::i;:::-;32519:41;;32709:1;32700:7;32696:15;32693:1;32690:22;32670:1;32663:9;32643:83;32620:139;;32739:18;;:::i;:::-;32620:139;32404:362;32356:410;;;;:::o;32772:180::-;32820:77;32817:1;32810:88;32917:4;32914:1;32907:15;32941:4;32938:1;32931:15;32958:171;32997:3;33020:24;33038:5;33020:24;:::i;:::-;33011:33;;33066:4;33059:5;33056:15;33053:41;;33074:18;;:::i;:::-;33053:41;33121:1;33114:5;33110:13;33103:20;;32958:171;;;:::o;33135:182::-;33275:34;33271:1;33263:6;33259:14;33252:58;33135:182;:::o;33323:366::-;33465:3;33486:67;33550:2;33545:3;33486:67;:::i;:::-;33479:74;;33562:93;33651:3;33562:93;:::i;:::-;33680:2;33675:3;33671:12;33664:19;;33323:366;;;:::o;33695:419::-;33861:4;33899:2;33888:9;33884:18;33876:26;;33948:9;33942:4;33938:20;33934:1;33923:9;33919:17;33912:47;33976:131;34102:4;33976:131;:::i;:::-;33968:139;;33695:419;;;:::o;34120:225::-;34260:34;34256:1;34248:6;34244:14;34237:58;34329:8;34324:2;34316:6;34312:15;34305:33;34120:225;:::o;34351:366::-;34493:3;34514:67;34578:2;34573:3;34514:67;:::i;:::-;34507:74;;34590:93;34679:3;34590:93;:::i;:::-;34708:2;34703:3;34699:12;34692:19;;34351:366;;;:::o;34723:419::-;34889:4;34927:2;34916:9;34912:18;34904:26;;34976:9;34970:4;34966:20;34962:1;34951:9;34947:17;34940:47;35004:131;35130:4;35004:131;:::i;:::-;34996:139;;34723:419;;;:::o;35148:98::-;35199:6;35233:5;35227:12;35217:22;;35148:98;;;:::o;35252:147::-;35353:11;35390:3;35375:18;;35252:147;;;;:::o;35405:386::-;35509:3;35537:38;35569:5;35537:38;:::i;:::-;35591:88;35672:6;35667:3;35591:88;:::i;:::-;35584:95;;35688:65;35746:6;35741:3;35734:4;35727:5;35723:16;35688:65;:::i;:::-;35778:6;35773:3;35769:16;35762:23;;35513:278;35405:386;;;;:::o;35797:271::-;35927:3;35949:93;36038:3;36029:6;35949:93;:::i;:::-;35942:100;;36059:3;36052:10;;35797:271;;;;:::o;36074:179::-;36214:31;36210:1;36202:6;36198:14;36191:55;36074:179;:::o;36259:366::-;36401:3;36422:67;36486:2;36481:3;36422:67;:::i;:::-;36415:74;;36498:93;36587:3;36498:93;:::i;:::-;36616:2;36611:3;36607:12;36600:19;;36259:366;;;:::o;36631:419::-;36797:4;36835:2;36824:9;36820:18;36812:26;;36884:9;36878:4;36874:20;36870:1;36859:9;36855:17;36848:47;36912:131;37038:4;36912:131;:::i;:::-;36904:139;;36631:419;;;:::o
Swarm Source
ipfs://f25ae3e563f3e35ab2ae646394340bb58b040bd53db1e16e7275c1f6c2410401
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.16839 | 19,546,986.1378 | $3,291,517 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.