Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 945 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Buy With Eth | 18669202 | 411 days ago | IN | 0.048311 ETH | 0.0028935 | ||||
Buy With Eth | 18669196 | 411 days ago | IN | 0.03 ETH | 0.00215485 | ||||
Buy With Usdt | 18669177 | 411 days ago | IN | 0 ETH | 0.0030816 | ||||
Buy With Eth | 18669175 | 411 days ago | IN | 0.034 ETH | 0.00314173 | ||||
Buy With Usdt | 18669175 | 411 days ago | IN | 0 ETH | 0.00308088 | ||||
Buy With Eth | 18669175 | 411 days ago | IN | 3.1888 ETH | 0.00313394 | ||||
Buy With Eth | 18669166 | 411 days ago | IN | 0.12 ETH | 0.00216031 | ||||
Buy With Eth | 18669159 | 411 days ago | IN | 0.048 ETH | 0.00233423 | ||||
Buy With Eth | 18669151 | 411 days ago | IN | 0.68 ETH | 0.003148 | ||||
Buy With Eth | 18669114 | 411 days ago | IN | 0.22 ETH | 0.00295965 | ||||
Buy With Eth | 18669110 | 411 days ago | IN | 0.025665 ETH | 0.00305728 | ||||
Buy With Eth | 18669108 | 411 days ago | IN | 0.043 ETH | 0.00319811 | ||||
Buy With Eth | 18669102 | 411 days ago | IN | 0.035 ETH | 0.00241157 | ||||
Buy With Usdt | 18669095 | 411 days ago | IN | 0 ETH | 0.00316625 | ||||
Buy With Eth | 18669076 | 411 days ago | IN | 1.33 ETH | 0.00330986 | ||||
Buy With Eth | 18669037 | 411 days ago | IN | 0.0905 ETH | 0.00317396 | ||||
Buy With Eth | 18669033 | 411 days ago | IN | 0.7 ETH | 0.00237404 | ||||
Buy With Eth | 18669025 | 411 days ago | IN | 0.03 ETH | 0.00341576 | ||||
Buy With Eth | 18669005 | 411 days ago | IN | 0.47 ETH | 0.00298747 | ||||
Buy With Usdt | 18668994 | 411 days ago | IN | 0 ETH | 0.00335707 | ||||
Buy With Eth | 18668976 | 411 days ago | IN | 1.5 ETH | 0.00322684 | ||||
Buy With Usdt | 18668968 | 411 days ago | IN | 0 ETH | 0.00302458 | ||||
Buy With Eth | 18668967 | 411 days ago | IN | 1.2 ETH | 0.00213733 | ||||
Buy With Eth | 18668949 | 411 days ago | IN | 1 ETH | 0.00231742 | ||||
Buy With Usdt | 18668934 | 411 days ago | IN | 0 ETH | 0.00307073 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18669202 | 411 days ago | 0.04783258 ETH | ||||
18669202 | 411 days ago | 0.00047841 ETH | ||||
18669196 | 411 days ago | 0.02968609 ETH | ||||
18669196 | 411 days ago | 0.0003139 ETH | ||||
18669175 | 411 days ago | 0.03366218 ETH | ||||
18669175 | 411 days ago | 0.00033781 ETH | ||||
18669175 | 411 days ago | 3.15721375 ETH | ||||
18669175 | 411 days ago | 0.03158624 ETH | ||||
18669166 | 411 days ago | 0.11880418 ETH | ||||
18669166 | 411 days ago | 0.00119581 ETH | ||||
18669159 | 411 days ago | 0.04750373 ETH | ||||
18669159 | 411 days ago | 0.00049626 ETH | ||||
18669151 | 411 days ago | 0.67325829 ETH | ||||
18669151 | 411 days ago | 0.0067417 ETH | ||||
18669114 | 411 days ago | 0.21781763 ETH | ||||
18669114 | 411 days ago | 0.00218236 ETH | ||||
18669110 | 411 days ago | 0.02541106 ETH | ||||
18669110 | 411 days ago | 0.00025393 ETH | ||||
18669108 | 411 days ago | 0.042571 ETH | ||||
18669108 | 411 days ago | 0.00042899 ETH | ||||
18669102 | 411 days ago | 0.03464872 ETH | ||||
18669102 | 411 days ago | 0.00035127 ETH | ||||
18669076 | 411 days ago | 1.32218983 ETH | ||||
18669076 | 411 days ago | 0.00781016 ETH | ||||
18669037 | 411 days ago | 0.0895903 ETH |
Loading...
Loading
Contract Name:
CatchTokenPresale
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2023-11-12 */ // File: @chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); } // File: @openzeppelin/[email protected]/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/[email protected]/interfaces/IERC5267.sol // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.0; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); } // File: @openzeppelin/[email protected]/utils/StorageSlot.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } } // File: @openzeppelin/[email protected]/utils/ShortStrings.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol) pragma solidity ^0.8.8; // | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | // | length | 0x BB | type ShortString is bytes32; /** * @dev This library provides functions to convert short memory strings * into a `ShortString` type that can be used as an immutable variable. * * Strings of arbitrary length can be optimized using this library if * they are short enough (up to 31 bytes) by packing them with their * length (1 byte) in a single EVM word (32 bytes). Additionally, a * fallback mechanism can be used for every other case. * * Usage example: * * ```solidity * contract Named { * using ShortStrings for *; * * ShortString private immutable _name; * string private _nameFallback; * * constructor(string memory contractName) { * _name = contractName.toShortStringWithFallback(_nameFallback); * } * * function name() external view returns (string memory) { * return _name.toStringWithFallback(_nameFallback); * } * } * ``` */ library ShortStrings { // Used as an identifier for strings longer than 31 bytes. bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; error StringTooLong(string str); error InvalidShortString(); /** * @dev Encode a string of at most 31 chars into a `ShortString`. * * This will trigger a `StringTooLong` error is the input string is too long. */ function toShortString(string memory str) internal pure returns (ShortString) { bytes memory bstr = bytes(str); if (bstr.length > 31) { revert StringTooLong(str); } return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); } /** * @dev Decode a `ShortString` back to a "normal" string. */ function toString(ShortString sstr) internal pure returns (string memory) { uint256 len = byteLength(sstr); // using `new string(len)` would work locally but is not memory safe. string memory str = new string(32); /// @solidity memory-safe-assembly assembly { mstore(str, len) mstore(add(str, 0x20), sstr) } return str; } /** * @dev Return the length of a `ShortString`. */ function byteLength(ShortString sstr) internal pure returns (uint256) { uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; if (result > 31) { revert InvalidShortString(); } return result; } /** * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. */ function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { if (bytes(value).length < 32) { return toShortString(value); } else { StorageSlot.getStringSlot(store).value = value; return ShortString.wrap(_FALLBACK_SENTINEL); } } /** * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. */ function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return toString(value); } else { return store; } } /** * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}. * * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. */ function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { return byteLength(value); } else { return bytes(store).length; } } } // File: @openzeppelin/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } } // File: @openzeppelin/[email protected]/utils/cryptography/EIP712.sol // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment */ abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. * * _Available since v4.9._ */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _name.toStringWithFallback(_nameFallback), _version.toStringWithFallback(_versionFallback), block.chainid, address(this), bytes32(0), new uint256[](0) ); } } // File: @openzeppelin/[email protected]/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/[email protected]/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/[email protected]/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: CatchTokenPresale.sol pragma solidity 0.8.19; contract CatchTokenPresale is AccessControl, EIP712 { bytes32 public constant SIGNER_ROLE = keccak256("SIGNER_ROLE"); event Bought(address user, uint256 tokenAmount); event PhaseChanged(Phase phase); event ClaimedTGE(address user, uint256 tokenAmount); event ClaimedVesting(address user, uint256 tokenAmount); enum Phase { INIT, BUY, CLAIM } address payable immutable public buyRecipient; IERC20 immutable public catchToken; AggregatorV3Interface immutable public priceFeed; IERC20 immutable public usdt; /// @notice 8 decimals; e.g. value `100000000` represents $1.00 for 1 full CATCH token uint256 immutable public tokenPriceUsd; /// @notice 8 decimals; e.g. value `5000000000` represents $50.00 minimal USDT amount uint256 immutable public minUsdAmount; /// @notice 0 decimals, e.g. value `10` represents 10% discount uint8 immutable public nftHolderDiscountPercent; uint256 immutable public presaleSupply; /// @notice 0 decimals, e.g. value `10` represents 10% unlock at TGE uint8 immutable public unlockPercentAtTGE; uint8 immutable public cliffMonths; uint8 immutable public linearVestingMonths; Phase public currentPhase; mapping(bytes32 => bool) public usedNonces; uint256 public vestingStartDate; uint256 public vestingEndDate; mapping(address user => uint256 tokens) public totalTGETokensByUser; mapping(address user => uint256 tokens) public totalVestingTokensByUser; mapping(address user => uint256 tokens) public claimedTGETokensByUser; mapping(address user => uint256 tokens) public claimedVestingTokensByUser; uint256 public totalTokensBought; uint256[4] private volumeThresholds = [50000000000, 150100000000, 300100000000, 500100000000]; uint8[4] private volumeBonuses = [3, 5, 7, 12]; modifier onlyCurrentPhase(Phase _phase) { require(currentPhase == _phase, "CatchTokenPresale: Unexpected current phase"); _; } struct PresaleParams { address payable _buyRecipient; uint256 _tokenPriceUsd; uint256 _minUsdAmount; uint8 _nftHolderDiscountPercent; uint256 _presaleSupply; uint8 _unlockPercentAtTGE; uint8 _cliffMonths; uint8 _linearVestingMonths; } constructor( address[] memory admins, address[] memory signers, IERC20 _catchToken, AggregatorV3Interface _priceFeed, IERC20 _usdt, PresaleParams memory presaleParams ) EIP712("CatchTokenPresale", "1") { for (uint i; i < admins.length; i++) { _grantRole(DEFAULT_ADMIN_ROLE, admins[i]); } for (uint i; i < admins.length; i++) { _grantRole(SIGNER_ROLE, signers[i]); } catchToken = _catchToken; priceFeed = _priceFeed; usdt = _usdt; buyRecipient = presaleParams._buyRecipient; tokenPriceUsd = presaleParams._tokenPriceUsd; minUsdAmount = presaleParams._minUsdAmount; nftHolderDiscountPercent = presaleParams._nftHolderDiscountPercent; presaleSupply = presaleParams._presaleSupply; unlockPercentAtTGE = presaleParams._unlockPercentAtTGE; cliffMonths = presaleParams._cliffMonths; linearVestingMonths = presaleParams._linearVestingMonths; } function buyWithEth(uint256 tokenAmount) external payable onlyCurrentPhase(Phase.BUY) { require(this.getUsdAmount(tokenAmount) >= minUsdAmount, "CatchTokenPresale: Below min amount"); _buyWithEth(tokenAmount, false); } function buyWithUsdt(uint256 tokenAmount) external onlyCurrentPhase(Phase.BUY) { require(this.getUsdAmount(tokenAmount) >= minUsdAmount, "CatchTokenPresale: Below min amount"); _buyWithUsdt(tokenAmount, false); } function buyWithEthNftHolder(uint256 tokenAmount, bytes32 nonce, bytes memory signature) external payable onlyCurrentPhase(Phase.BUY) { require(this.getUsdAmount(tokenAmount) >= minUsdAmount, "CatchTokenPresale: Below min amount"); bytes32 digest = _hashTypedDataV4( keccak256(abi.encode(keccak256("BuyWithEthNftHolder(bytes32 nonce)"), nonce)) ); address recoveredSigner = ECDSA.recover(digest, signature); require(hasRole(SIGNER_ROLE, recoveredSigner), "CatchTokenPresale: Invalid signature"); require(!usedNonces[nonce], "CatchTokenPresale: Nonce already used"); usedNonces[nonce] = true; _buyWithEth(tokenAmount, true); } function buyWithUsdtNftHolder(uint256 tokenAmount, bytes32 nonce, bytes memory signature) external onlyCurrentPhase(Phase.BUY) { require(this.getUsdAmount(tokenAmount) >= minUsdAmount, "CatchTokenPresale: Below min amount"); bytes32 digest = _hashTypedDataV4( keccak256(abi.encode(keccak256("BuyWithUsdtNftHolder(bytes32 nonce)"), nonce)) ); address recoveredSigner = ECDSA.recover(digest, signature); require(hasRole(SIGNER_ROLE, recoveredSigner), "CatchTokenPresale: Invalid signature"); require(!usedNonces[nonce], "CatchTokenPresale: Nonce already used"); usedNonces[nonce] = true; _buyWithUsdt(tokenAmount, true); } function availableTGETokensToClaim(address user) public view returns (uint256) { if (currentPhase != Phase.CLAIM) { return 0; } return totalTGETokensByUser[user] - claimedTGETokensByUser[user]; } function availableVestingTokensToClaim(address user) public view returns (uint256) { if (currentPhase != Phase.CLAIM) { return 0; } uint256 vestingDays = (vestingEndDate - vestingStartDate) / 1 days; uint256 tokensPerDay = totalVestingTokensByUser[user] / vestingDays; uint256 daysSinceVestingStart = block.timestamp > vestingStartDate ? (block.timestamp - vestingStartDate) / 1 days : 0; return (daysSinceVestingStart * tokensPerDay) - claimedVestingTokensByUser[user]; } function claimTGETokens() external { uint256 tokenAmount = availableTGETokensToClaim(msg.sender); claimedTGETokensByUser[msg.sender] = tokenAmount; catchToken.transfer(msg.sender, tokenAmount); emit ClaimedTGE(msg.sender, tokenAmount); } function claimVestingTokens() external { uint256 tokenAmount = availableVestingTokensToClaim(msg.sender); claimedVestingTokensByUser[msg.sender] += tokenAmount; catchToken.transfer(msg.sender, tokenAmount); emit ClaimedVesting(msg.sender, tokenAmount); } function calculateEthAmountRequired(uint256 tokenAmount, bool isNftHolder) external view returns (uint256) { uint256 usdAmount = this.tokenAmountToUsdAmount(tokenAmount, isNftHolder); (,int256 ethUsdPrice,,,) = priceFeed.latestRoundData(); uint256 ethAmount = (usdAmount * 1e18) / uint256(ethUsdPrice); return ethAmount; } function calculateUsdtAmountRequired(uint256 tokenAmount, bool isNftHolder) external view returns (uint256) { uint256 usdAmount = this.tokenAmountToUsdAmount(tokenAmount, isNftHolder); uint256 usdtAmount = usdAmount / 1e2; return usdtAmount; } function calculateTokenAmountByEth(uint256 ethAmount, bool isNftHolder) public view returns (uint256) { (,int256 ethUsdPrice,,,) = priceFeed.latestRoundData(); uint256 usdAmount = (ethAmount * uint256(ethUsdPrice)) / 1e18; uint256 tokenAmount = this.usdAmountToTokenAmount(usdAmount, isNftHolder); return tokenAmount; } function calculateTokenAmountByUsdt(uint256 usdtAmount, bool isNftHolder) public view returns (uint256) { uint256 usdAmount = usdtAmount * 1e2; uint256 tokenAmount = this.usdAmountToTokenAmount(usdAmount, isNftHolder); return tokenAmount; } function usdAmountToTokenAmount(uint256 usdAmount, bool isNftHolder) external view returns (uint256) { uint256 volumeDiscount = getVolumeDiscount(usdAmount); uint256 discountedTokenPriceUsd = (tokenPriceUsd * (100 - volumeDiscount)) / 100; if (isNftHolder) { discountedTokenPriceUsd = (discountedTokenPriceUsd * (100 - nftHolderDiscountPercent)) / 100; } uint256 tokenAmount = (usdAmount * 1e18) / discountedTokenPriceUsd; return tokenAmount; } function tokenAmountToUsdAmount(uint256 tokenAmount, bool isNftHolder) external view returns (uint256) { uint256 usdAmountBeforeDiscount = (tokenAmount * tokenPriceUsd) / 1e18; uint256 volumeDiscount = getVolumeDiscount(usdAmountBeforeDiscount); uint256 discountedUsdAmount = (usdAmountBeforeDiscount * (100 - volumeDiscount)) / 100; if (isNftHolder) { discountedUsdAmount = (discountedUsdAmount * (100 - nftHolderDiscountPercent)) / 100; } return discountedUsdAmount; } function startBuyPhase() external onlyCurrentPhase(Phase.INIT) onlyRole(DEFAULT_ADMIN_ROLE) { require(catchToken.balanceOf(address(this)) >= presaleSupply, "CatchTokenPresale: Not enough supply. Send first."); _changeCurrentPhase(Phase.BUY); } function startClaimPhase() external onlyCurrentPhase(Phase.BUY) onlyRole(DEFAULT_ADMIN_ROLE) { _changeCurrentPhase(Phase.CLAIM); vestingStartDate = block.timestamp + (uint256(cliffMonths) * (30 days)); vestingEndDate = vestingStartDate + (uint256(linearVestingMonths) * (30 days)); } function _buyWithEth(uint256 tokenAmount, bool isNftHolder) internal { uint256 currentBalance = catchToken.balanceOf(address(this)); if (tokenAmount >= currentBalance) { tokenAmount = currentBalance; } uint256 ethAmountRequired = this.calculateEthAmountRequired(tokenAmount, isNftHolder); require(msg.value >= ethAmountRequired, "CatchTokenPresale: Insufficient value"); totalTokensBought += tokenAmount; uint256 TGEAmount = (tokenAmount / 100) * unlockPercentAtTGE; totalTGETokensByUser[msg.sender] += TGEAmount; totalVestingTokensByUser[msg.sender] += tokenAmount - TGEAmount; emit Bought(msg.sender, tokenAmount); if (msg.value > ethAmountRequired) { // return overpaid ETH back to the sender uint256 overpaid = msg.value - ethAmountRequired; payable(msg.sender).transfer(overpaid); } buyRecipient.transfer(ethAmountRequired); } function _buyWithUsdt(uint256 tokenAmount, bool isNftHolder) internal { uint256 currentBalance = catchToken.balanceOf(address(this)); if (tokenAmount >= currentBalance) { tokenAmount = currentBalance; } totalTokensBought += tokenAmount; uint256 usdtAmountRequired = this.calculateUsdtAmountRequired(tokenAmount, isNftHolder); (bool success, ) = address(usdt).call( abi.encodeWithSignature( "transferFrom(address,address,uint256)", msg.sender, buyRecipient, usdtAmountRequired ) ); require(success, "CatchTokenPresale: Could not transfer usdt"); uint256 TGEAmount = (tokenAmount / 100) * unlockPercentAtTGE; totalTGETokensByUser[msg.sender] += TGEAmount; totalVestingTokensByUser[msg.sender] += tokenAmount - TGEAmount; emit Bought(msg.sender, tokenAmount); } function getUsdAmount(uint256 tokenAmount) external view returns (uint256) { return (tokenAmount * tokenPriceUsd) / 1e18; } function getVolumeDiscount(uint256 amountInUsd) internal pure returns (uint256) { if (amountInUsd >= 5001 * 1e8) { return 12; } else if (amountInUsd >= 3001 * 1e8) { return 7; } else if (amountInUsd >= 1501 * 1e8) { return 5; } else if (amountInUsd >= 500 * 1e8) { return 3; } return 0; } function _changeCurrentPhase(Phase _phase) internal { currentPhase = _phase; emit PhaseChanged(_phase); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address[]","name":"admins","type":"address[]"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"contract IERC20","name":"_catchToken","type":"address"},{"internalType":"contract AggregatorV3Interface","name":"_priceFeed","type":"address"},{"internalType":"contract IERC20","name":"_usdt","type":"address"},{"components":[{"internalType":"address payable","name":"_buyRecipient","type":"address"},{"internalType":"uint256","name":"_tokenPriceUsd","type":"uint256"},{"internalType":"uint256","name":"_minUsdAmount","type":"uint256"},{"internalType":"uint8","name":"_nftHolderDiscountPercent","type":"uint8"},{"internalType":"uint256","name":"_presaleSupply","type":"uint256"},{"internalType":"uint8","name":"_unlockPercentAtTGE","type":"uint8"},{"internalType":"uint8","name":"_cliffMonths","type":"uint8"},{"internalType":"uint8","name":"_linearVestingMonths","type":"uint8"}],"internalType":"struct CatchTokenPresale.PresaleParams","name":"presaleParams","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"Bought","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"ClaimedTGE","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"ClaimedVesting","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum CatchTokenPresale.Phase","name":"phase","type":"uint8"}],"name":"PhaseChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"availableTGETokensToClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"availableVestingTokensToClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyRecipient","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"buyWithEth","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"buyWithEthNftHolder","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"buyWithUsdt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"buyWithUsdtNftHolder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"bool","name":"isNftHolder","type":"bool"}],"name":"calculateEthAmountRequired","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"bool","name":"isNftHolder","type":"bool"}],"name":"calculateTokenAmountByEth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdtAmount","type":"uint256"},{"internalType":"bool","name":"isNftHolder","type":"bool"}],"name":"calculateTokenAmountByUsdt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"bool","name":"isNftHolder","type":"bool"}],"name":"calculateUsdtAmountRequired","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"catchToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimTGETokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimVestingTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"claimedTGETokensByUser","outputs":[{"internalType":"uint256","name":"tokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"claimedVestingTokensByUser","outputs":[{"internalType":"uint256","name":"tokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cliffMonths","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPhase","outputs":[{"internalType":"enum CatchTokenPresale.Phase","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"getUsdAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"linearVestingMonths","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minUsdAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftHolderDiscountPercent","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceFeed","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBuyPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startClaimPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"bool","name":"isNftHolder","type":"bool"}],"name":"tokenAmountToUsdAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPriceUsd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"totalTGETokensByUser","outputs":[{"internalType":"uint256","name":"tokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTokensBought","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"totalVestingTokensByUser","outputs":[{"internalType":"uint256","name":"tokens","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unlockPercentAtTGE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdAmount","type":"uint256"},{"internalType":"bool","name":"isNftHolder","type":"bool"}],"name":"usdAmountToTokenAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdt","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"usedNonces","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestingEndDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestingStartDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
610340604052640ba43b74006102c09081526422f2a83d006102e0526445df5a990061030052647470486900610320526200003f90600c906004620003f7565b50604080516080810182526003815260056020820152600791810191909152600c60608201526200007590601090600462000443565b503480156200008357600080fd5b5060405162003ab938038062003ab9833981016040819052620000a6916200060b565b604051806040016040528060118152602001704361746368546f6b656e50726573616c6560781b815250604051806040016040528060018152602001603160f81b81525062000100600183620002d160201b90919060201c565b6101205262000111816002620002d1565b61014052815160208084019190912060e052815190820120610100524660a0526200019f60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c05260005b8651811015620001fb57620001e66000801b888381518110620001d257620001d26200075d565b60200260200101516200030a60201b60201c565b80620001f28162000773565b915050620001ab565b5060005b86518110156200025857620002437fe2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f70878381518110620001d257620001d26200075d565b806200024f8162000773565b915050620001ff565b506001600160a01b03938416610180529183166101a05282166101c05280519091166101605260208101516101e052604081015161020052606081015160ff9081166102205260808201516102405260a082015181166102605260c082015181166102805260e090910151166102a052506200096b9050565b6000602083511015620002f157620002e983620003ab565b905062000304565b81620002fe84826200082a565b5060ff90505b92915050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16620003a7576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620003663390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600080829050601f81511115620003e2578260405163305a27a960e01b8152600401620003d99190620008f6565b60405180910390fd5b8051620003ef8262000946565b179392505050565b826004810192821562000431579160200282015b8281111562000431578251829064ffffffffff169055916020019190600101906200040b565b506200043f929150620004d3565b5090565b600183019183908215620004315791602002820160005b838211156200049a57835183826101000a81548160ff021916908360ff16021790555092602001926001016020816000010492830192600103026200045a565b8015620004c95782816101000a81549060ff02191690556001016020816000010492830192600103026200049a565b50506200043f9291505b5b808211156200043f5760008155600101620004d4565b634e487b7160e01b600052604160045260246000fd5b60405161010081016001600160401b0381118282101715620005265762000526620004ea565b60405290565b6001600160a01b03811681146200054257600080fd5b50565b600082601f8301126200055757600080fd5b815160206001600160401b0380831115620005765762000576620004ea565b8260051b604051601f19603f830116810181811084821117156200059e576200059e620004ea565b604052938452858101830193838101925087851115620005bd57600080fd5b83870191505b84821015620005e9578151620005d9816200052c565b83529183019190830190620005c3565b979650505050505050565b805160ff811681146200060657600080fd5b919050565b6000806000806000808688036101a08112156200062757600080fd5b87516001600160401b03808211156200063f57600080fd5b6200064d8b838c0162000545565b985060208a01519150808211156200066457600080fd5b50620006738a828b0162000545565b965050604088015162000686816200052c565b606089015190955062000699816200052c565b6080890151909450620006ac816200052c565b9250610100609f198201811315620006c357600080fd5b620006cd62000500565b915060a0890151620006df816200052c565b825260c0890151602083015260e0890151604083015262000702818a01620005f4565b6060830152506101208801516080820152620007226101408901620005f4565b60a0820152620007366101608901620005f4565b60c08201526200074a6101808901620005f4565b60e0820152809150509295509295509295565b634e487b7160e01b600052603260045260246000fd5b6000600182016200079457634e487b7160e01b600052601160045260246000fd5b5060010190565b600181811c90821680620007b057607f821691505b602082108103620007d157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200082557600081815260208120601f850160051c81016020861015620008005750805b601f850160051c820191505b8181101562000821578281556001016200080c565b5050505b505050565b81516001600160401b03811115620008465762000846620004ea565b6200085e816200085784546200079b565b84620007d7565b602080601f8311600181146200089657600084156200087d5750858301515b600019600386901b1c1916600185901b17855562000821565b600085815260208120601f198616915b82811015620008c757888601518255948401946001909101908401620008a6565b5085821015620008e65787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208083528351808285015260005b81811015620009255785810183015185820160400152820162000907565b506000604082860101526040601f19601f8301168501019250505092915050565b80516020808301519190811015620007d15760001960209190910360031b1b16919050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a051612fd262000ae7600039600081816108640152611a3e0152600081816108ed0152611a0101526000818161045e01528181611dcc01526121640152600081816107450152610eb10152600081816104c4015281816109f401526110910152600081816107f001528181610ac901528181611132015281816114d701526117d80152600081816104f801528181610985015281816110540152611a8b0152600081816103dc0152611cc70152600081816105f101528181611238015261167601526000818161078f01528181610ed3015281816113ae015281816118b301528181611b7d0152611ffb01526000818161071101528181611c92015261227e0152600061130e015260006112e30152600061244c015260006124240152600061237f015260006123a9015260006123d30152612fd26000f3fe60806040526004361061027c5760003560e01c806380d975bf1161014f578063c4b31a42116100c1578063d95b977f1161007a578063d95b977f146108a6578063dfde347f146108bb578063e3b9b22d146108db578063eddd21431461090f578063facce97614610924578063feb617241461094457600080fd5b8063c4b31a42146107b1578063ce8e4830146107de578063d547741f14610812578063d5f0e64514610832578063d60035bc14610852578063d707dfd11461088657600080fd5b8063a1ebf35d11610113578063a1ebf35d146106b6578063a217fddf146106ea578063a32683d4146106ff578063b3a196e914610733578063baa9e53114610767578063c4a693481461077d57600080fd5b806380d975bf1461062657806384b0196e14610646578063890bb0e01461066e57806391d14854146106835780639b0986e2146106a357600080fd5b80634610fe7c116101f357806365be4aa5116101ac57806365be4aa51461055d57806369cebcf2146105725780636f7adf67146105925780636fbaea1b146105bf578063741bef1a146105df5780637649b9571461061357600080fd5b80634610fe7c1461044c5780635138ecd3146104925780635176e323146104b25780635249be25146104e6578063579acacc1461051a5780635a7dfc9b1461053057600080fd5b806320ba282d1161024557806320ba282d1461035a578063248a9ca31461037a5780632f2ff15d146103aa5780632f48ab7d146103ca57806336568abe146104165780633db5a5241461043657600080fd5b806217dcc51461028157806301ffc9a7146102b4578063055ad42e146102e45780631885d3121461030b5780631c696f3914610338575b600080fd5b34801561028d57600080fd5b506102a161029c366004612978565b610974565b6040519081526020015b60405180910390f35b3480156102c057600080fd5b506102d46102cf3660046129a8565b610a3e565b60405190151581526020016102ab565b3480156102f057600080fd5b506003546102fe9060ff1681565b6040516102ab91906129e8565b34801561031757600080fd5b506102a1610326366004612a2c565b600a6020526000908152604090205481565b34801561034457600080fd5b50610358610353366004612a5d565b610a73565b005b34801561036657600080fd5b506102a1610375366004612978565b610c5d565b34801561038657600080fd5b506102a1610395366004612b21565b60009081526020819052604090206001015490565b3480156103b657600080fd5b506103586103c5366004612b3a565b610cd9565b3480156103d657600080fd5b506103fe7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102ab565b34801561042257600080fd5b50610358610431366004612b3a565b610d03565b34801561044257600080fd5b506102a160065481565b34801561045857600080fd5b506104807f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016102ab565b34801561049e57600080fd5b506102a16104ad366004612a2c565b610d81565b3480156104be57600080fd5b506104807f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f257600080fd5b506102a17f000000000000000000000000000000000000000000000000000000000000000081565b34801561052657600080fd5b506102a160055481565b34801561053c57600080fd5b506102a161054b366004612a2c565b60096020526000908152604090205481565b34801561056957600080fd5b50610358610e5a565b34801561057e57600080fd5b506102a161058d366004612978565b610fb8565b34801561059e57600080fd5b506102a16105ad366004612a2c565b60076020526000908152604090205481565b3480156105cb57600080fd5b506102a16105da366004612978565b611032565b3480156105eb57600080fd5b506103fe7f000000000000000000000000000000000000000000000000000000000000000081565b610358610621366004612b21565b6110e5565b34801561063257600080fd5b506102a1610641366004612978565b6111c7565b34801561065257600080fd5b5061065b6112d5565b6040516102ab9796959493929190612bb6565b34801561067a57600080fd5b5061035861135e565b34801561068f57600080fd5b506102d461069e366004612b3a565b611461565b6103586106b1366004612a5d565b61148a565b3480156106c257600080fd5b506102a17fe2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f7081565b3480156106f657600080fd5b506102a1600081565b34801561070b57600080fd5b506103fe7f000000000000000000000000000000000000000000000000000000000000000081565b34801561073f57600080fd5b506102a17f000000000000000000000000000000000000000000000000000000000000000081565b34801561077357600080fd5b506102a1600b5481565b34801561078957600080fd5b506103fe7f000000000000000000000000000000000000000000000000000000000000000081565b3480156107bd57600080fd5b506102a16107cc366004612a2c565b60086020526000908152604090205481565b3480156107ea57600080fd5b506102a17f000000000000000000000000000000000000000000000000000000000000000081565b34801561081e57600080fd5b5061035861082d366004612b3a565b61164c565b34801561083e57600080fd5b506102a161084d366004612978565b611671565b34801561085e57600080fd5b506104807f000000000000000000000000000000000000000000000000000000000000000081565b34801561089257600080fd5b506103586108a1366004612b21565b61178b565b3480156108b257600080fd5b5061035861186d565b3480156108c757600080fd5b506102a16108d6366004612a2c565b611957565b3480156108e757600080fd5b506104807f000000000000000000000000000000000000000000000000000000000000000081565b34801561091b57600080fd5b506103586119ae565b34801561093057600080fd5b506102a161093f366004612b21565b611a7b565b34801561095057600080fd5b506102d461095f366004612b21565b60046020526000908152604090205460ff1681565b600080670de0b6b3a76400006109aa7f000000000000000000000000000000000000000000000000000000000000000086612c62565b6109b49190612c79565b905060006109c182611aba565b9050600060646109d18382612c9b565b6109db9085612c62565b6109e59190612c79565b90508415610a33576064610a197f000000000000000000000000000000000000000000000000000000000000000082612cae565b610a269060ff1683612c62565b610a309190612c79565b90505b925050505b92915050565b60006001600160e01b03198216637965db0b60e01b1480610a3857506301ffc9a760e01b6001600160e01b0319831614610a38565b60018060035460ff166002811115610a8d57610a8d6129d2565b14610ab35760405162461bcd60e51b8152600401610aaa90612cc7565b60405180910390fd5b604051637d6674bb60e11b8152600481018590527f000000000000000000000000000000000000000000000000000000000000000090309063facce97690602401602060405180830381865afa158015610b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b359190612d12565b1015610b535760405162461bcd60e51b8152600401610aaa90612d2b565b604080517fc39426da28b92313088f1a2a66c3ece8e42469247f971fd1139b79c0885bf95d6020820152908101849052600090610ba9906060015b60405160208183030381529060405280519060200120611b14565b90506000610bb78285611b41565b9050610be37fe2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f7082611461565b610bff5760405162461bcd60e51b8152600401610aaa90612d6e565b60008581526004602052604090205460ff1615610c2e5760405162461bcd60e51b8152600401610aaa90612db2565b6000858152600460205260409020805460ff19166001908117909155610c55908790611b65565b505050505050565b600080610c6b846064612c62565b604051636fbaea1b60e01b81526004810182905284151560248201529091506000903090636fbaea1b90604401602060405180830381865afa158015610cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a339190612d12565b600082815260208190526040902060010154610cf481611e9a565b610cfe8383611ea7565b505050565b6001600160a01b0381163314610d735760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610aaa565b610d7d8282611f2b565b5050565b6000600260035460ff166002811115610d9c57610d9c6129d2565b14610da957506000919050565b600062015180600554600654610dbf9190612c9b565b610dc99190612c79565b6001600160a01b03841660009081526008602052604081205491925090610df1908390612c79565b905060006005544211610e05576000610e21565b6201518060055442610e179190612c9b565b610e219190612c79565b6001600160a01b0386166000908152600a6020526040902054909150610e478383612c62565b610e519190612c9b565b95945050505050565b60008060035460ff166002811115610e7457610e746129d2565b14610e915760405162461bcd60e51b8152600401610aaa90612cc7565b6000610e9c81611e9a565b6040516370a0823160e01b81523060048201527f0000000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f469190612d12565b1015610fae5760405162461bcd60e51b815260206004820152603160248201527f4361746368546f6b656e50726573616c653a204e6f7420656e6f7567682073756044820152703838363c971029b2b732103334b939ba1760791b6064820152608401610aaa565b610d7d6001611f90565b6040516217dcc560e01b8152600481018390528115156024820152600090819030906217dcc590604401602060405180830381865afa158015610fff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110239190612d12565b90506000610a33606483612c79565b60008061103e84611aba565b90506000606461104e8382612c9b565b611078907f0000000000000000000000000000000000000000000000000000000000000000612c62565b6110829190612c79565b905083156110d05760646110b67f000000000000000000000000000000000000000000000000000000000000000082612cae565b6110c39060ff1683612c62565b6110cd9190612c79565b90505b600081610a2687670de0b6b3a7640000612c62565b60018060035460ff1660028111156110ff576110ff6129d2565b1461111c5760405162461bcd60e51b8152600401610aaa90612cc7565b604051637d6674bb60e11b8152600481018390527f000000000000000000000000000000000000000000000000000000000000000090309063facce97690602401602060405180830381865afa15801561117a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119e9190612d12565b10156111bc5760405162461bcd60e51b8152600401610aaa90612d2b565b610d7d826000611fe3565b6040516217dcc560e01b8152600481018390528115156024820152600090819030906217dcc590604401602060405180830381865afa15801561120e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112329190612d12565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611294573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b89190612e11565b50505091505060008183670de0b6b3a7640000610a269190612c62565b6000606080828080836113097f000000000000000000000000000000000000000000000000000000000000000060016122c7565b6113347f000000000000000000000000000000000000000000000000000000000000000060026122c7565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b600061136933610d81565b336000908152600a602052604081208054929350839290919061138d908490612e61565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af11580156113ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114239190612e74565b5060408051338152602081018390527fb2d84ea6f935b15fed127c4844c9ef741d12c97e8924002d93ca92d0c044bbfc91015b60405180910390a150565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60018060035460ff1660028111156114a4576114a46129d2565b146114c15760405162461bcd60e51b8152600401610aaa90612cc7565b604051637d6674bb60e11b8152600481018590527f000000000000000000000000000000000000000000000000000000000000000090309063facce97690602401602060405180830381865afa15801561151f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115439190612d12565b10156115615760405162461bcd60e51b8152600401610aaa90612d2b565b604080517f9a206d4546afa0aa00085c8bfd09faad9350c09515019b5555ea500aef88054b60208201529081018490526000906115a090606001610b8e565b905060006115ae8285611b41565b90506115da7fe2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f7082611461565b6115f65760405162461bcd60e51b8152600401610aaa90612d6e565b60008581526004602052604090205460ff16156116255760405162461bcd60e51b8152600401610aaa90612db2565b6000858152600460205260409020805460ff19166001908117909155610c55908790611fe3565b60008281526020819052604090206001015461166781611e9a565b610cfe8383611f2b565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156116d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f69190612e11565b5050509150506000670de0b6b3a764000082866117139190612c62565b61171d9190612c79565b604051636fbaea1b60e01b81526004810182905285151560248201529091506000903090636fbaea1b90604401602060405180830381865afa158015611767573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a309190612d12565b60018060035460ff1660028111156117a5576117a56129d2565b146117c25760405162461bcd60e51b8152600401610aaa90612cc7565b604051637d6674bb60e11b8152600481018390527f000000000000000000000000000000000000000000000000000000000000000090309063facce97690602401602060405180830381865afa158015611820573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118449190612d12565b10156118625760405162461bcd60e51b8152600401610aaa90612d2b565b610d7d826000611b65565b600061187833611957565b33600081815260096020526040908190208390555163a9059cbb60e01b81526004810191909152602481018290529091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af11580156118fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119209190612e74565b5060408051338152602081018390527ffa5eb272d14a1abca6db7cfa4ebb3aa755a76da51f81b9563105354f5a7d07089101611456565b6000600260035460ff166002811115611972576119726129d2565b1461197f57506000919050565b6001600160a01b038216600090815260096020908152604080832054600790925290912054610a389190612c9b565b60018060035460ff1660028111156119c8576119c86129d2565b146119e55760405162461bcd60e51b8152600401610aaa90612cc7565b60006119f081611e9a565b6119fa6002611f90565b611a2a60ff7f00000000000000000000000000000000000000000000000000000000000000001662278d00612c62565b611a349042612e61565b600555611a6760ff7f00000000000000000000000000000000000000000000000000000000000000001662278d00612c62565b600554611a749190612e61565b6006555050565b6000670de0b6b3a7640000611ab07f000000000000000000000000000000000000000000000000000000000000000084612c62565b610a389190612c79565b60006474704869008210611ad05750600c919050565b6445df5a99008210611ae457506007919050565b6422f2a83d008210611af857506005919050565b640ba43b74008210611b0c57506003919050565b506000919050565b6000610a38611b21612372565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000611b5085856124a2565b91509150611b5d816124e7565b509392505050565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf09190612d12565b9050808310611bfd578092505b82600b6000828254611c0f9190612e61565b90915550506040516334e75e7960e11b815260048101849052821515602482015260009030906369cebcf290604401602060405180830381865afa158015611c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7f9190612d12565b6040513360248201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166044830152606482018390529192506000917f0000000000000000000000000000000000000000000000000000000000000000169060840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b17905251611d209190612e91565b6000604051808303816000865af19150503d8060008114611d5d576040519150601f19603f3d011682016040523d82523d6000602084013e611d62565b606091505b5050905080611dc65760405162461bcd60e51b815260206004820152602a60248201527f4361746368546f6b656e50726573616c653a20436f756c64206e6f74207472616044820152691b9cd9995c881d5cd91d60b21b6064820152608401610aaa565b600060ff7f000000000000000000000000000000000000000000000000000000000000000016611df7606488612c79565b611e019190612c62565b33600090815260076020526040812080549293508392909190611e25908490612e61565b90915550611e3590508187612c9b565b3360009081526008602052604081208054909190611e54908490612e61565b909155505060408051338152602081018890527fc55650ccda1011e1cdc769b1fbf546ebb8c97800b6072b49e06cd560305b1d67910160405180910390a1505050505050565b611ea48133612631565b50565b611eb18282611461565b610d7d576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055611ee73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b611f358282611461565b15610d7d576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6003805482919060ff19166001836002811115611faf57611faf6129d2565b02179055507fa6dcc92f45df25789d5639b7a0c97ba1edf3bb1c0b5dd3376fd96a0db87c46428160405161145691906129e8565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561204a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206e9190612d12565b905080831061207b578092505b6040516380d975bf60e01b815260048101849052821515602482015260009030906380d975bf90604401602060405180830381865afa1580156120c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e69190612d12565b9050803410156121465760405162461bcd60e51b815260206004820152602560248201527f4361746368546f6b656e50726573616c653a20496e73756666696369656e742060448201526476616c756560d81b6064820152608401610aaa565b83600b60008282546121589190612e61565b909155506000905060ff7f00000000000000000000000000000000000000000000000000000000000000001661218f606487612c79565b6121999190612c62565b336000908152600760205260408120805492935083929091906121bd908490612e61565b909155506121cd90508186612c9b565b33600090815260086020526040812080549091906121ec908490612e61565b909155505060408051338152602081018790527fc55650ccda1011e1cdc769b1fbf546ebb8c97800b6072b49e06cd560305b1d67910160405180910390a18134111561227157600061223e8334612c9b565b604051909150339082156108fc029083906000818181858888f1935050505015801561226e573d6000803e3d6000fd5b50505b6040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169083156108fc029084906000818181858888f19350505050158015610c55573d6000803e3d6000fd5b606060ff83146122e1576122da8361268a565b9050610a38565b8180546122ed90612ead565b80601f016020809104026020016040519081016040528092919081815260200182805461231990612ead565b80156123665780601f1061233b57610100808354040283529160200191612366565b820191906000526020600020905b81548152906001019060200180831161234957829003601f168201915b50505050509050610a38565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156123cb57507f000000000000000000000000000000000000000000000000000000000000000046145b156123f557507f000000000000000000000000000000000000000000000000000000000000000090565b61249d604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b905090565b60008082516041036124d85760208301516040840151606085015160001a6124cc878285856126c9565b945094505050506124e0565b506000905060025b9250929050565b60008160048111156124fb576124fb6129d2565b036125035750565b6001816004811115612517576125176129d2565b036125645760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610aaa565b6002816004811115612578576125786129d2565b036125c55760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610aaa565b60038160048111156125d9576125d96129d2565b03611ea45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610aaa565b61263b8282611461565b610d7d576126488161278d565b61265383602061279f565b604051602001612664929190612ee7565b60408051601f198184030181529082905262461bcd60e51b8252610aaa91600401612f5c565b6060600061269783612942565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156127005750600090506003612784565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612754573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661277d57600060019250925050612784565b9150600090505b94509492505050565b6060610a386001600160a01b03831660145b606060006127ae836002612c62565b6127b9906002612e61565b67ffffffffffffffff8111156127d1576127d1612a47565b6040519080825280601f01601f1916602001820160405280156127fb576020820181803683370190505b509050600360fc1b8160008151811061281657612816612f6f565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061284557612845612f6f565b60200101906001600160f81b031916908160001a9053506000612869846002612c62565b612874906001612e61565b90505b60018111156128ec576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106128a8576128a8612f6f565b1a60f81b8282815181106128be576128be612f6f565b60200101906001600160f81b031916908160001a90535060049490941c936128e581612f85565b9050612877565b50831561293b5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610aaa565b9392505050565b600060ff8216601f811115610a3857604051632cd44ac360e21b815260040160405180910390fd5b8015158114611ea457600080fd5b6000806040838503121561298b57600080fd5b82359150602083013561299d8161296a565b809150509250929050565b6000602082840312156129ba57600080fd5b81356001600160e01b03198116811461293b57600080fd5b634e487b7160e01b600052602160045260246000fd5b6020810160038310612a0a57634e487b7160e01b600052602160045260246000fd5b91905290565b80356001600160a01b0381168114612a2757600080fd5b919050565b600060208284031215612a3e57600080fd5b61293b82612a10565b634e487b7160e01b600052604160045260246000fd5b600080600060608486031215612a7257600080fd5b8335925060208401359150604084013567ffffffffffffffff80821115612a9857600080fd5b818601915086601f830112612aac57600080fd5b813581811115612abe57612abe612a47565b604051601f8201601f19908116603f01168101908382118183101715612ae657612ae6612a47565b81604052828152896020848701011115612aff57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b600060208284031215612b3357600080fd5b5035919050565b60008060408385031215612b4d57600080fd5b82359150612b5d60208401612a10565b90509250929050565b60005b83811015612b81578181015183820152602001612b69565b50506000910152565b60008151808452612ba2816020860160208601612b66565b601f01601f19169290920160200192915050565b60ff60f81b881681526000602060e081840152612bd660e084018a612b8a565b8381036040850152612be8818a612b8a565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015612c3a57835183529284019291840191600101612c1e565b50909c9b505050505050505050505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a3857610a38612c4c565b600082612c9657634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610a3857610a38612c4c565b60ff8281168282160390811115610a3857610a38612c4c565b6020808252602b908201527f4361746368546f6b656e50726573616c653a20556e657870656374656420637560408201526a7272656e7420706861736560a81b606082015260800190565b600060208284031215612d2457600080fd5b5051919050565b60208082526023908201527f4361746368546f6b656e50726573616c653a2042656c6f77206d696e20616d6f6040820152621d5b9d60ea1b606082015260800190565b60208082526024908201527f4361746368546f6b656e50726573616c653a20496e76616c6964207369676e616040820152637475726560e01b606082015260800190565b60208082526025908201527f4361746368546f6b656e50726573616c653a204e6f6e636520616c7265616479604082015264081d5cd95960da1b606082015260800190565b805169ffffffffffffffffffff81168114612a2757600080fd5b600080600080600060a08688031215612e2957600080fd5b612e3286612df7565b9450602086015193506040860151925060608601519150612e5560808701612df7565b90509295509295909350565b80820180821115610a3857610a38612c4c565b600060208284031215612e8657600080fd5b815161293b8161296a565b60008251612ea3818460208701612b66565b9190910192915050565b600181811c90821680612ec157607f821691505b602082108103612ee157634e487b7160e01b600052602260045260246000fd5b50919050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612f1f816017850160208801612b66565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612f50816028840160208801612b66565b01602801949350505050565b60208152600061293b6020830184612b8a565b634e487b7160e01b600052603260045260246000fd5b600081612f9457612f94612c4c565b50600019019056fea26469706673582212206d1e2ccc3840a2da54a7bc51bcb9037b0d87803b46108816e1840a9b463b11f064736f6c6343000813003300000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000007b708ac2c20200ac4b241d5523c76691b96ca01f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000308a31a6acc3b3b36d39c6f87703e00ea06a52e200000000000000000000000000000000000000000000000000000000005b8d80000000000000000000000000000000000000000000000000000000011e1a30000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000010000000000000000000000009158dbc0dedef18f075db08bd34a3400473874b900000000000000000000000000000000000000000000000000000000000000020000000000000000000000009158dbc0dedef18f075db08bd34a3400473874b9000000000000000000000000528f5cf460acf61fcf3dce0fc59f8b2fcd9740b2
Deployed Bytecode
0x60806040526004361061027c5760003560e01c806380d975bf1161014f578063c4b31a42116100c1578063d95b977f1161007a578063d95b977f146108a6578063dfde347f146108bb578063e3b9b22d146108db578063eddd21431461090f578063facce97614610924578063feb617241461094457600080fd5b8063c4b31a42146107b1578063ce8e4830146107de578063d547741f14610812578063d5f0e64514610832578063d60035bc14610852578063d707dfd11461088657600080fd5b8063a1ebf35d11610113578063a1ebf35d146106b6578063a217fddf146106ea578063a32683d4146106ff578063b3a196e914610733578063baa9e53114610767578063c4a693481461077d57600080fd5b806380d975bf1461062657806384b0196e14610646578063890bb0e01461066e57806391d14854146106835780639b0986e2146106a357600080fd5b80634610fe7c116101f357806365be4aa5116101ac57806365be4aa51461055d57806369cebcf2146105725780636f7adf67146105925780636fbaea1b146105bf578063741bef1a146105df5780637649b9571461061357600080fd5b80634610fe7c1461044c5780635138ecd3146104925780635176e323146104b25780635249be25146104e6578063579acacc1461051a5780635a7dfc9b1461053057600080fd5b806320ba282d1161024557806320ba282d1461035a578063248a9ca31461037a5780632f2ff15d146103aa5780632f48ab7d146103ca57806336568abe146104165780633db5a5241461043657600080fd5b806217dcc51461028157806301ffc9a7146102b4578063055ad42e146102e45780631885d3121461030b5780631c696f3914610338575b600080fd5b34801561028d57600080fd5b506102a161029c366004612978565b610974565b6040519081526020015b60405180910390f35b3480156102c057600080fd5b506102d46102cf3660046129a8565b610a3e565b60405190151581526020016102ab565b3480156102f057600080fd5b506003546102fe9060ff1681565b6040516102ab91906129e8565b34801561031757600080fd5b506102a1610326366004612a2c565b600a6020526000908152604090205481565b34801561034457600080fd5b50610358610353366004612a5d565b610a73565b005b34801561036657600080fd5b506102a1610375366004612978565b610c5d565b34801561038657600080fd5b506102a1610395366004612b21565b60009081526020819052604090206001015490565b3480156103b657600080fd5b506103586103c5366004612b3a565b610cd9565b3480156103d657600080fd5b506103fe7f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec781565b6040516001600160a01b0390911681526020016102ab565b34801561042257600080fd5b50610358610431366004612b3a565b610d03565b34801561044257600080fd5b506102a160065481565b34801561045857600080fd5b506104807f000000000000000000000000000000000000000000000000000000000000000581565b60405160ff90911681526020016102ab565b34801561049e57600080fd5b506102a16104ad366004612a2c565b610d81565b3480156104be57600080fd5b506104807f000000000000000000000000000000000000000000000000000000000000000581565b3480156104f257600080fd5b506102a17f00000000000000000000000000000000000000000000000000000000005b8d8081565b34801561052657600080fd5b506102a160055481565b34801561053c57600080fd5b506102a161054b366004612a2c565b60096020526000908152604090205481565b34801561056957600080fd5b50610358610e5a565b34801561057e57600080fd5b506102a161058d366004612978565b610fb8565b34801561059e57600080fd5b506102a16105ad366004612a2c565b60076020526000908152604090205481565b3480156105cb57600080fd5b506102a16105da366004612978565b611032565b3480156105eb57600080fd5b506103fe7f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b841981565b610358610621366004612b21565b6110e5565b34801561063257600080fd5b506102a1610641366004612978565b6111c7565b34801561065257600080fd5b5061065b6112d5565b6040516102ab9796959493929190612bb6565b34801561067a57600080fd5b5061035861135e565b34801561068f57600080fd5b506102d461069e366004612b3a565b611461565b6103586106b1366004612a5d565b61148a565b3480156106c257600080fd5b506102a17fe2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f7081565b3480156106f657600080fd5b506102a1600081565b34801561070b57600080fd5b506103fe7f000000000000000000000000308a31a6acc3b3b36d39c6f87703e00ea06a52e281565b34801561073f57600080fd5b506102a17f000000000000000000000000000000000000000000084595161401484a00000081565b34801561077357600080fd5b506102a1600b5481565b34801561078957600080fd5b506103fe7f0000000000000000000000007b708ac2c20200ac4b241d5523c76691b96ca01f81565b3480156107bd57600080fd5b506102a16107cc366004612a2c565b60086020526000908152604090205481565b3480156107ea57600080fd5b506102a17f000000000000000000000000000000000000000000000000000000011e1a300081565b34801561081e57600080fd5b5061035861082d366004612b3a565b61164c565b34801561083e57600080fd5b506102a161084d366004612978565b611671565b34801561085e57600080fd5b506104807f000000000000000000000000000000000000000000000000000000000000001481565b34801561089257600080fd5b506103586108a1366004612b21565b61178b565b3480156108b257600080fd5b5061035861186d565b3480156108c757600080fd5b506102a16108d6366004612a2c565b611957565b3480156108e757600080fd5b506104807f000000000000000000000000000000000000000000000000000000000000000381565b34801561091b57600080fd5b506103586119ae565b34801561093057600080fd5b506102a161093f366004612b21565b611a7b565b34801561095057600080fd5b506102d461095f366004612b21565b60046020526000908152604090205460ff1681565b600080670de0b6b3a76400006109aa7f00000000000000000000000000000000000000000000000000000000005b8d8086612c62565b6109b49190612c79565b905060006109c182611aba565b9050600060646109d18382612c9b565b6109db9085612c62565b6109e59190612c79565b90508415610a33576064610a197f000000000000000000000000000000000000000000000000000000000000000582612cae565b610a269060ff1683612c62565b610a309190612c79565b90505b925050505b92915050565b60006001600160e01b03198216637965db0b60e01b1480610a3857506301ffc9a760e01b6001600160e01b0319831614610a38565b60018060035460ff166002811115610a8d57610a8d6129d2565b14610ab35760405162461bcd60e51b8152600401610aaa90612cc7565b60405180910390fd5b604051637d6674bb60e11b8152600481018590527f000000000000000000000000000000000000000000000000000000011e1a300090309063facce97690602401602060405180830381865afa158015610b11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b359190612d12565b1015610b535760405162461bcd60e51b8152600401610aaa90612d2b565b604080517fc39426da28b92313088f1a2a66c3ece8e42469247f971fd1139b79c0885bf95d6020820152908101849052600090610ba9906060015b60405160208183030381529060405280519060200120611b14565b90506000610bb78285611b41565b9050610be37fe2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f7082611461565b610bff5760405162461bcd60e51b8152600401610aaa90612d6e565b60008581526004602052604090205460ff1615610c2e5760405162461bcd60e51b8152600401610aaa90612db2565b6000858152600460205260409020805460ff19166001908117909155610c55908790611b65565b505050505050565b600080610c6b846064612c62565b604051636fbaea1b60e01b81526004810182905284151560248201529091506000903090636fbaea1b90604401602060405180830381865afa158015610cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a339190612d12565b600082815260208190526040902060010154610cf481611e9a565b610cfe8383611ea7565b505050565b6001600160a01b0381163314610d735760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610aaa565b610d7d8282611f2b565b5050565b6000600260035460ff166002811115610d9c57610d9c6129d2565b14610da957506000919050565b600062015180600554600654610dbf9190612c9b565b610dc99190612c79565b6001600160a01b03841660009081526008602052604081205491925090610df1908390612c79565b905060006005544211610e05576000610e21565b6201518060055442610e179190612c9b565b610e219190612c79565b6001600160a01b0386166000908152600a6020526040902054909150610e478383612c62565b610e519190612c9b565b95945050505050565b60008060035460ff166002811115610e7457610e746129d2565b14610e915760405162461bcd60e51b8152600401610aaa90612cc7565b6000610e9c81611e9a565b6040516370a0823160e01b81523060048201527f000000000000000000000000000000000000000000084595161401484a000000907f0000000000000000000000007b708ac2c20200ac4b241d5523c76691b96ca01f6001600160a01b0316906370a0823190602401602060405180830381865afa158015610f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f469190612d12565b1015610fae5760405162461bcd60e51b815260206004820152603160248201527f4361746368546f6b656e50726573616c653a204e6f7420656e6f7567682073756044820152703838363c971029b2b732103334b939ba1760791b6064820152608401610aaa565b610d7d6001611f90565b6040516217dcc560e01b8152600481018390528115156024820152600090819030906217dcc590604401602060405180830381865afa158015610fff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110239190612d12565b90506000610a33606483612c79565b60008061103e84611aba565b90506000606461104e8382612c9b565b611078907f00000000000000000000000000000000000000000000000000000000005b8d80612c62565b6110829190612c79565b905083156110d05760646110b67f000000000000000000000000000000000000000000000000000000000000000582612cae565b6110c39060ff1683612c62565b6110cd9190612c79565b90505b600081610a2687670de0b6b3a7640000612c62565b60018060035460ff1660028111156110ff576110ff6129d2565b1461111c5760405162461bcd60e51b8152600401610aaa90612cc7565b604051637d6674bb60e11b8152600481018390527f000000000000000000000000000000000000000000000000000000011e1a300090309063facce97690602401602060405180830381865afa15801561117a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061119e9190612d12565b10156111bc5760405162461bcd60e51b8152600401610aaa90612d2b565b610d7d826000611fe3565b6040516217dcc560e01b8152600481018390528115156024820152600090819030906217dcc590604401602060405180830381865afa15801561120e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112329190612d12565b905060007f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84196001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611294573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112b89190612e11565b50505091505060008183670de0b6b3a7640000610a269190612c62565b6000606080828080836113097f4361746368546f6b656e50726573616c6500000000000000000000000000001160016122c7565b6113347f310000000000000000000000000000000000000000000000000000000000000160026122c7565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b600061136933610d81565b336000908152600a602052604081208054929350839290919061138d908490612e61565b909155505060405163a9059cbb60e01b8152336004820152602481018290527f0000000000000000000000007b708ac2c20200ac4b241d5523c76691b96ca01f6001600160a01b03169063a9059cbb906044016020604051808303816000875af11580156113ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114239190612e74565b5060408051338152602081018390527fb2d84ea6f935b15fed127c4844c9ef741d12c97e8924002d93ca92d0c044bbfc91015b60405180910390a150565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60018060035460ff1660028111156114a4576114a46129d2565b146114c15760405162461bcd60e51b8152600401610aaa90612cc7565b604051637d6674bb60e11b8152600481018590527f000000000000000000000000000000000000000000000000000000011e1a300090309063facce97690602401602060405180830381865afa15801561151f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115439190612d12565b10156115615760405162461bcd60e51b8152600401610aaa90612d2b565b604080517f9a206d4546afa0aa00085c8bfd09faad9350c09515019b5555ea500aef88054b60208201529081018490526000906115a090606001610b8e565b905060006115ae8285611b41565b90506115da7fe2f4eaae4a9751e85a3e4a7b9587827a877f29914755229b07a7b2da98285f7082611461565b6115f65760405162461bcd60e51b8152600401610aaa90612d6e565b60008581526004602052604090205460ff16156116255760405162461bcd60e51b8152600401610aaa90612db2565b6000858152600460205260409020805460ff19166001908117909155610c55908790611fe3565b60008281526020819052604090206001015461166781611e9a565b610cfe8383611f2b565b6000807f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b84196001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156116d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f69190612e11565b5050509150506000670de0b6b3a764000082866117139190612c62565b61171d9190612c79565b604051636fbaea1b60e01b81526004810182905285151560248201529091506000903090636fbaea1b90604401602060405180830381865afa158015611767573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a309190612d12565b60018060035460ff1660028111156117a5576117a56129d2565b146117c25760405162461bcd60e51b8152600401610aaa90612cc7565b604051637d6674bb60e11b8152600481018390527f000000000000000000000000000000000000000000000000000000011e1a300090309063facce97690602401602060405180830381865afa158015611820573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118449190612d12565b10156118625760405162461bcd60e51b8152600401610aaa90612d2b565b610d7d826000611b65565b600061187833611957565b33600081815260096020526040908190208390555163a9059cbb60e01b81526004810191909152602481018290529091506001600160a01b037f0000000000000000000000007b708ac2c20200ac4b241d5523c76691b96ca01f169063a9059cbb906044016020604051808303816000875af11580156118fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119209190612e74565b5060408051338152602081018390527ffa5eb272d14a1abca6db7cfa4ebb3aa755a76da51f81b9563105354f5a7d07089101611456565b6000600260035460ff166002811115611972576119726129d2565b1461197f57506000919050565b6001600160a01b038216600090815260096020908152604080832054600790925290912054610a389190612c9b565b60018060035460ff1660028111156119c8576119c86129d2565b146119e55760405162461bcd60e51b8152600401610aaa90612cc7565b60006119f081611e9a565b6119fa6002611f90565b611a2a60ff7f00000000000000000000000000000000000000000000000000000000000000031662278d00612c62565b611a349042612e61565b600555611a6760ff7f00000000000000000000000000000000000000000000000000000000000000141662278d00612c62565b600554611a749190612e61565b6006555050565b6000670de0b6b3a7640000611ab07f00000000000000000000000000000000000000000000000000000000005b8d8084612c62565b610a389190612c79565b60006474704869008210611ad05750600c919050565b6445df5a99008210611ae457506007919050565b6422f2a83d008210611af857506005919050565b640ba43b74008210611b0c57506003919050565b506000919050565b6000610a38611b21612372565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000611b5085856124a2565b91509150611b5d816124e7565b509392505050565b6040516370a0823160e01b81523060048201526000907f0000000000000000000000007b708ac2c20200ac4b241d5523c76691b96ca01f6001600160a01b0316906370a0823190602401602060405180830381865afa158015611bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf09190612d12565b9050808310611bfd578092505b82600b6000828254611c0f9190612e61565b90915550506040516334e75e7960e11b815260048101849052821515602482015260009030906369cebcf290604401602060405180830381865afa158015611c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7f9190612d12565b6040513360248201526001600160a01b037f000000000000000000000000308a31a6acc3b3b36d39c6f87703e00ea06a52e281166044830152606482018390529192506000917f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7169060840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b17905251611d209190612e91565b6000604051808303816000865af19150503d8060008114611d5d576040519150601f19603f3d011682016040523d82523d6000602084013e611d62565b606091505b5050905080611dc65760405162461bcd60e51b815260206004820152602a60248201527f4361746368546f6b656e50726573616c653a20436f756c64206e6f74207472616044820152691b9cd9995c881d5cd91d60b21b6064820152608401610aaa565b600060ff7f000000000000000000000000000000000000000000000000000000000000000516611df7606488612c79565b611e019190612c62565b33600090815260076020526040812080549293508392909190611e25908490612e61565b90915550611e3590508187612c9b565b3360009081526008602052604081208054909190611e54908490612e61565b909155505060408051338152602081018890527fc55650ccda1011e1cdc769b1fbf546ebb8c97800b6072b49e06cd560305b1d67910160405180910390a1505050505050565b611ea48133612631565b50565b611eb18282611461565b610d7d576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055611ee73390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b611f358282611461565b15610d7d576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6003805482919060ff19166001836002811115611faf57611faf6129d2565b02179055507fa6dcc92f45df25789d5639b7a0c97ba1edf3bb1c0b5dd3376fd96a0db87c46428160405161145691906129e8565b6040516370a0823160e01b81523060048201526000907f0000000000000000000000007b708ac2c20200ac4b241d5523c76691b96ca01f6001600160a01b0316906370a0823190602401602060405180830381865afa15801561204a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061206e9190612d12565b905080831061207b578092505b6040516380d975bf60e01b815260048101849052821515602482015260009030906380d975bf90604401602060405180830381865afa1580156120c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e69190612d12565b9050803410156121465760405162461bcd60e51b815260206004820152602560248201527f4361746368546f6b656e50726573616c653a20496e73756666696369656e742060448201526476616c756560d81b6064820152608401610aaa565b83600b60008282546121589190612e61565b909155506000905060ff7f00000000000000000000000000000000000000000000000000000000000000051661218f606487612c79565b6121999190612c62565b336000908152600760205260408120805492935083929091906121bd908490612e61565b909155506121cd90508186612c9b565b33600090815260086020526040812080549091906121ec908490612e61565b909155505060408051338152602081018790527fc55650ccda1011e1cdc769b1fbf546ebb8c97800b6072b49e06cd560305b1d67910160405180910390a18134111561227157600061223e8334612c9b565b604051909150339082156108fc029083906000818181858888f1935050505015801561226e573d6000803e3d6000fd5b50505b6040516001600160a01b037f000000000000000000000000308a31a6acc3b3b36d39c6f87703e00ea06a52e2169083156108fc029084906000818181858888f19350505050158015610c55573d6000803e3d6000fd5b606060ff83146122e1576122da8361268a565b9050610a38565b8180546122ed90612ead565b80601f016020809104026020016040519081016040528092919081815260200182805461231990612ead565b80156123665780601f1061233b57610100808354040283529160200191612366565b820191906000526020600020905b81548152906001019060200180831161234957829003601f168201915b50505050509050610a38565b6000306001600160a01b037f0000000000000000000000003381b62d4ec5ef9bd99630cb10aab770b0c38922161480156123cb57507f000000000000000000000000000000000000000000000000000000000000000146145b156123f557507f7e560ca37e8c53ca4762f12f801841b21443c81e8cee16aeadb45621814774c990565b61249d604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f8a489a429de6ef3ea00b00cbc70836bb7b13497a6ceba00d5e813eada3e21663918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b905090565b60008082516041036124d85760208301516040840151606085015160001a6124cc878285856126c9565b945094505050506124e0565b506000905060025b9250929050565b60008160048111156124fb576124fb6129d2565b036125035750565b6001816004811115612517576125176129d2565b036125645760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610aaa565b6002816004811115612578576125786129d2565b036125c55760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610aaa565b60038160048111156125d9576125d96129d2565b03611ea45760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610aaa565b61263b8282611461565b610d7d576126488161278d565b61265383602061279f565b604051602001612664929190612ee7565b60408051601f198184030181529082905262461bcd60e51b8252610aaa91600401612f5c565b6060600061269783612942565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156127005750600090506003612784565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612754573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661277d57600060019250925050612784565b9150600090505b94509492505050565b6060610a386001600160a01b03831660145b606060006127ae836002612c62565b6127b9906002612e61565b67ffffffffffffffff8111156127d1576127d1612a47565b6040519080825280601f01601f1916602001820160405280156127fb576020820181803683370190505b509050600360fc1b8160008151811061281657612816612f6f565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061284557612845612f6f565b60200101906001600160f81b031916908160001a9053506000612869846002612c62565b612874906001612e61565b90505b60018111156128ec576f181899199a1a9b1b9c1cb0b131b232b360811b85600f16601081106128a8576128a8612f6f565b1a60f81b8282815181106128be576128be612f6f565b60200101906001600160f81b031916908160001a90535060049490941c936128e581612f85565b9050612877565b50831561293b5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610aaa565b9392505050565b600060ff8216601f811115610a3857604051632cd44ac360e21b815260040160405180910390fd5b8015158114611ea457600080fd5b6000806040838503121561298b57600080fd5b82359150602083013561299d8161296a565b809150509250929050565b6000602082840312156129ba57600080fd5b81356001600160e01b03198116811461293b57600080fd5b634e487b7160e01b600052602160045260246000fd5b6020810160038310612a0a57634e487b7160e01b600052602160045260246000fd5b91905290565b80356001600160a01b0381168114612a2757600080fd5b919050565b600060208284031215612a3e57600080fd5b61293b82612a10565b634e487b7160e01b600052604160045260246000fd5b600080600060608486031215612a7257600080fd5b8335925060208401359150604084013567ffffffffffffffff80821115612a9857600080fd5b818601915086601f830112612aac57600080fd5b813581811115612abe57612abe612a47565b604051601f8201601f19908116603f01168101908382118183101715612ae657612ae6612a47565b81604052828152896020848701011115612aff57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b600060208284031215612b3357600080fd5b5035919050565b60008060408385031215612b4d57600080fd5b82359150612b5d60208401612a10565b90509250929050565b60005b83811015612b81578181015183820152602001612b69565b50506000910152565b60008151808452612ba2816020860160208601612b66565b601f01601f19169290920160200192915050565b60ff60f81b881681526000602060e081840152612bd660e084018a612b8a565b8381036040850152612be8818a612b8a565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015612c3a57835183529284019291840191600101612c1e565b50909c9b505050505050505050505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a3857610a38612c4c565b600082612c9657634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610a3857610a38612c4c565b60ff8281168282160390811115610a3857610a38612c4c565b6020808252602b908201527f4361746368546f6b656e50726573616c653a20556e657870656374656420637560408201526a7272656e7420706861736560a81b606082015260800190565b600060208284031215612d2457600080fd5b5051919050565b60208082526023908201527f4361746368546f6b656e50726573616c653a2042656c6f77206d696e20616d6f6040820152621d5b9d60ea1b606082015260800190565b60208082526024908201527f4361746368546f6b656e50726573616c653a20496e76616c6964207369676e616040820152637475726560e01b606082015260800190565b60208082526025908201527f4361746368546f6b656e50726573616c653a204e6f6e636520616c7265616479604082015264081d5cd95960da1b606082015260800190565b805169ffffffffffffffffffff81168114612a2757600080fd5b600080600080600060a08688031215612e2957600080fd5b612e3286612df7565b9450602086015193506040860151925060608601519150612e5560808701612df7565b90509295509295909350565b80820180821115610a3857610a38612c4c565b600060208284031215612e8657600080fd5b815161293b8161296a565b60008251612ea3818460208701612b66565b9190910192915050565b600181811c90821680612ec157607f821691505b602082108103612ee157634e487b7160e01b600052602260045260246000fd5b50919050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612f1f816017850160208801612b66565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612f50816028840160208801612b66565b01602801949350505050565b60208152600061293b6020830184612b8a565b634e487b7160e01b600052603260045260246000fd5b600081612f9457612f94612c4c565b50600019019056fea26469706673582212206d1e2ccc3840a2da54a7bc51bcb9037b0d87803b46108816e1840a9b463b11f064736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000007b708ac2c20200ac4b241d5523c76691b96ca01f0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000308a31a6acc3b3b36d39c6f87703e00ea06a52e200000000000000000000000000000000000000000000000000000000005b8d80000000000000000000000000000000000000000000000000000000011e1a30000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000010000000000000000000000009158dbc0dedef18f075db08bd34a3400473874b900000000000000000000000000000000000000000000000000000000000000020000000000000000000000009158dbc0dedef18f075db08bd34a3400473874b9000000000000000000000000528f5cf460acf61fcf3dce0fc59f8b2fcd9740b2
-----Decoded View---------------
Arg [0] : admins (address[]): 0x9158DbC0DEdEf18f075db08bd34a3400473874b9
Arg [1] : signers (address[]): 0x9158DbC0DEdEf18f075db08bd34a3400473874b9,0x528F5Cf460AcF61fCf3DCE0fc59f8b2fCd9740B2
Arg [2] : _catchToken (address): 0x7B708Ac2c20200Ac4b241d5523C76691B96cA01f
Arg [3] : _priceFeed (address): 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
Arg [4] : _usdt (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [5] : presaleParams (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
18 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000001e0
Arg [2] : 0000000000000000000000007b708ac2c20200ac4b241d5523c76691b96ca01f
Arg [3] : 0000000000000000000000005f4ec3df9cbd43714fe2740f5e3616155c5b8419
Arg [4] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [5] : 000000000000000000000000308a31a6acc3b3b36d39c6f87703e00ea06a52e2
Arg [6] : 00000000000000000000000000000000000000000000000000000000005b8d80
Arg [7] : 000000000000000000000000000000000000000000000000000000011e1a3000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [9] : 000000000000000000000000000000000000000000084595161401484a000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [14] : 0000000000000000000000009158dbc0dedef18f075db08bd34a3400473874b9
Arg [15] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [16] : 0000000000000000000000009158dbc0dedef18f075db08bd34a3400473874b9
Arg [17] : 000000000000000000000000528f5cf460acf61fcf3dce0fc59f8b2fcd9740b2
Deployed Bytecode Sourcemap
60121:11211:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67952:498;;;;;;;;;;-1:-1:-1;67952:498:0;;;;;:::i;:::-;;:::i;:::-;;;597:25:1;;;585:2;570:18;67952:498:0;;;;;;;;54381:204;;;;;;;;;;-1:-1:-1;54381:204:0;;;;;:::i;:::-;;:::i;:::-;;;1089:14:1;;1082:22;1064:41;;1052:2;1037:18;54381:204:0;924:187:1;61296:25:0;;;;;;;;;;-1:-1:-1;61296:25:0;;;;;;;;;;;;;;;:::i;61664:73::-;;;;;;;;;;-1:-1:-1;61664:73:0;;;;;:::i;:::-;;;;;;;;;;;;;;64369:650;;;;;;;;;;-1:-1:-1;64369:650:0;;;;;:::i;:::-;;:::i;:::-;;67219:251;;;;;;;;;;-1:-1:-1;67219:251:0;;;;;:::i;:::-;;:::i;56204:131::-;;;;;;;;;;-1:-1:-1;56204:131:0;;;;;:::i;:::-;56278:7;56305:12;;;;;;;;;;:22;;;;56204:131;56645:147;;;;;;;;;;-1:-1:-1;56645:147:0;;;;;:::i;:::-;;:::i;60633:28::-;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3958:32:1;;;3940:51;;3928:2;3913:18;60633:28:0;3780:217:1;57789:218:0;;;;;;;;;;-1:-1:-1;57789:218:0;;;;;:::i;:::-;;:::i;61410:29::-;;;;;;;;;;;;;;;;61165:41;;;;;;;;;;;;;;;;;;4174:4:1;4162:17;;;4144:36;;4132:2;4117:18;61165:41:0;4002:184:1;65241:506:0;;;;;;;;;;-1:-1:-1;65241:506:0;;;;;:::i;:::-;;:::i;60997:47::-;;;;;;;;;;;;;;;60756:38;;;;;;;;;;;;;;;61375:31;;;;;;;;;;;;;;;;61591:69;;;;;;;;;;-1:-1:-1;61591:69:0;;;;;:::i;:::-;;;;;;;;;;;;;;68455:251;;;;;;;;;;;;;:::i;66622:254::-;;;;;;;;;;-1:-1:-1;66622:254:0;;;;;:::i;:::-;;:::i;61445:67::-;;;;;;;;;;-1:-1:-1;61445:67:0;;;;;:::i;:::-;;;;;;;;;;;;;;67475:472;;;;;;;;;;-1:-1:-1;67475:472:0;;;;;:::i;:::-;;:::i;60581:48::-;;;;;;;;;;;;;;;63253:226;;;;;;:::i;:::-;;:::i;66281:336::-;;;;;;;;;;-1:-1:-1;66281:336:0;;;;;:::i;:::-;;:::i;47061:657::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;66008:268::-;;;;;;;;;;;;;:::i;54677:147::-;;;;;;;;;;-1:-1:-1;54677:147:0;;;;;:::i;:::-;;:::i;63709:655::-;;;;;;:::i;:::-;;:::i;60177:62::-;;;;;;;;;;;;60215:24;60177:62;;53782:49;;;;;;;;;;-1:-1:-1;53782:49:0;53827:4;53782:49;;60494:45;;;;;;;;;;;;;;;61050:38;;;;;;;;;;;;;;;61743:32;;;;;;;;;;;;;;;;60543:34;;;;;;;;;;;;;;;61516:71;;;;;;;;;;-1:-1:-1;61516:71:0;;;;;:::i;:::-;;;;;;;;;;;;;;60888:37;;;;;;;;;;;;;;;57085:149;;;;;;;;;;-1:-1:-1;57085:149:0;;;;;:::i;:::-;;:::i;66881:333::-;;;;;;;;;;-1:-1:-1;66881:333:0;;;;;:::i;:::-;;:::i;61248:42::-;;;;;;;;;;;;;;;63484:220;;;;;;;;;;-1:-1:-1;63484:220:0;;;;;:::i;:::-;;:::i;65752:251::-;;;;;;;;;;;;;:::i;65024:212::-;;;;;;;;;;-1:-1:-1;65024:212:0;;;;;:::i;:::-;;:::i;61210:34::-;;;;;;;;;;;;;;;68711:294;;;;;;;;;;;;;:::i;70752:128::-;;;;;;;;;;-1:-1:-1;70752:128:0;;;;;:::i;:::-;;:::i;61327:42::-;;;;;;;;;;-1:-1:-1;61327:42:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;67952:498;68046:7;;68126:4;68095:27;68109:13;68095:11;:27;:::i;:::-;68094:36;;;;:::i;:::-;68060:70;;68135:22;68160:42;68178:23;68160:17;:42::i;:::-;68135:67;-1:-1:-1;68207:27:0;68290:3;68265:20;68135:67;68290:3;68265:20;:::i;:::-;68238:48;;:23;:48;:::i;:::-;68237:56;;;;:::i;:::-;68207:86;;68304:11;68300:113;;;68404:3;68369:30;68375:24;68404:3;68369:30;:::i;:::-;68346:54;;;;:19;:54;:::i;:::-;68345:62;;;;:::i;:::-;68323:84;;68300:113;68426:19;-1:-1:-1;;;67952:498:0;;;;;:::o;54381:204::-;54466:4;-1:-1:-1;;;;;;54490:47:0;;-1:-1:-1;;;54490:47:0;;:87;;-1:-1:-1;;;;;;;;;;15215:40:0;;;54541:36;15106:157;64369:650;64485:9;;61983:12;;;;:22;;;;;;;;:::i;:::-;;61975:78;;;;-1:-1:-1;;;61975:78:0;;;;;;;:::i;:::-;;;;;;;;;64509:30:::1;::::0;-1:-1:-1;;;64509:30:0;;::::1;::::0;::::1;597:25:1::0;;;64543:12:0::1;::::0;64509:4:::1;::::0;:17:::1;::::0;570:18:1;;64509:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;;64501:94;;;;-1:-1:-1::0;;;64501:94:0::1;;;;;;;:::i;:::-;64649:67;::::0;;64660:48:::1;64649:67;::::0;::::1;8626:25:1::0;8667:18;;;8660:34;;;64600:14:0::1;::::0;64617:105:::1;::::0;8599:18:1;;64649:67:0::1;;;;;;;;;;;;;64639:78;;;;;;64617:16;:105::i;:::-;64600:122;;64727:23;64753:32;64767:6;64775:9;64753:13;:32::i;:::-;64727:58;;64798:37;60215:24;64819:15;64798:7;:37::i;:::-;64790:86;;;;-1:-1:-1::0;;;64790:86:0::1;;;;;;;:::i;:::-;64890:17;::::0;;;:10:::1;:17;::::0;;;;;::::1;;64889:18;64881:68;;;;-1:-1:-1::0;;;64881:68:0::1;;;;;;;:::i;:::-;64954:17;::::0;;;:10:::1;:17;::::0;;;;:24;;-1:-1:-1;;64954:24:0::1;64974:4;64954:24:::0;;::::1;::::0;;;64983:31:::1;::::0;64996:11;;64983:12:::1;:31::i;:::-;64496:523;;64369:650:::0;;;;:::o;67219:251::-;67314:7;;67348:16;:10;67361:3;67348:16;:::i;:::-;67391:51;;-1:-1:-1;;;67391:51:0;;;;;9684:25:1;;;9752:14;;9745:22;9725:18;;;9718:50;67328:36:0;;-1:-1:-1;67369:19:0;;67391:4;;:27;;9657:18:1;;67391:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;56645:147::-;56278:7;56305:12;;;;;;;;;;:22;;;54273:16;54284:4;54273:10;:16::i;:::-;56759:25:::1;56770:4;56776:7;56759:10;:25::i;:::-;56645:147:::0;;;:::o;57789:218::-;-1:-1:-1;;;;;57885:23:0;;48490:10;57885:23;57877:83;;;;-1:-1:-1;;;57877:83:0;;9981:2:1;57877:83:0;;;9963:21:1;10020:2;10000:18;;;9993:30;10059:34;10039:18;;;10032:62;-1:-1:-1;;;10110:18:1;;;10103:45;10165:19;;57877:83:0;9779:411:1;57877:83:0;57973:26;57985:4;57991:7;57973:11;:26::i;:::-;57789:218;;:::o;65241:506::-;65315:7;65349:11;65333:12;;;;:27;;;;;;;;:::i;:::-;;65329:53;;-1:-1:-1;65375:1:0;;65241:506;-1:-1:-1;65241:506:0:o;65329:53::-;65388:19;65448:6;65428:16;;65411:14;;:33;;;;:::i;:::-;65410:44;;;;:::i;:::-;-1:-1:-1;;;;;65482:30:0;;65459:20;65482:30;;;:24;:30;;;;;;65388:66;;-1:-1:-1;65459:20:0;65482:44;;65388:66;;65482:44;:::i;:::-;65459:67;;65531:29;65581:16;;65563:15;:34;:94;;65656:1;65563:94;;;65643:6;65623:16;;65605:15;:34;;;;:::i;:::-;65604:45;;;;:::i;:::-;-1:-1:-1;;;;;65710:32:0;;;;;;:26;:32;;;;;;65531:126;;-1:-1:-1;65670:36:0;65694:12;65531:126;65670:36;:::i;:::-;65669:73;;;;:::i;:::-;65662:80;65241:506;-1:-1:-1;;;;;65241:506:0:o;68455:251::-;68506:10;;61983:12;;;;:22;;;;;;;;:::i;:::-;;61975:78;;;;-1:-1:-1;;;61975:78:0;;;;;;;:::i;:::-;53827:4:::1;54273:16;53827:4:::0;54273:10:::1;:16::i;:::-;68560:35:::2;::::0;-1:-1:-1;;;68560:35:0;;68589:4:::2;68560:35;::::0;::::2;3940:51:1::0;68599:13:0::2;::::0;68560:10:::2;-1:-1:-1::0;;;;;68560:20:0::2;::::0;::::2;::::0;3913:18:1;;68560:35:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;;68552:114;;;::::0;-1:-1:-1;;;68552:114:0;;10605:2:1;68552:114:0::2;::::0;::::2;10587:21:1::0;10644:2;10624:18;;;10617:30;10683:34;10663:18;;;10656:62;-1:-1:-1;;;10734:18:1;;;10727:47;10791:19;;68552:114:0::2;10403:413:1::0;68552:114:0::2;68671:30;68691:9;68671:19;:30::i;66622:254::-:0;66755:53;;-1:-1:-1;;;66755:53:0;;;;;9684:25:1;;;9752:14;;9745:22;9725:18;;;9718:50;66721:7:0;;;;66755:4;;:27;;9657:18:1;;66755:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66735:73;-1:-1:-1;66813:18:0;66834:15;66846:3;66735:73;66834:15;:::i;67475:472::-;67567:7;67581:22;67606:28;67624:9;67606:17;:28::i;:::-;67581:53;-1:-1:-1;67639:31:0;67716:3;67691:20;67581:53;67716:3;67691:20;:::i;:::-;67674:38;;:13;:38;:::i;:::-;67673:46;;;;:::i;:::-;67639:80;;67730:11;67726:121;;;67838:3;67803:30;67809:24;67838:3;67803:30;:::i;:::-;67776:58;;;;:23;:58;:::i;:::-;67775:66;;;;:::i;:::-;67749:92;;67726:121;67853:19;67896:23;67876:16;:9;67888:4;67876:16;:::i;63253:226::-;63328:9;;61983:12;;;;:22;;;;;;;;:::i;:::-;;61975:78;;;;-1:-1:-1;;;61975:78:0;;;;;;;:::i;:::-;63352:30:::1;::::0;-1:-1:-1;;;63352:30:0;;::::1;::::0;::::1;597:25:1::0;;;63386:12:0::1;::::0;63352:4:::1;::::0;:17:::1;::::0;570:18:1;;63352:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;;63344:94;;;;-1:-1:-1::0;;;63344:94:0::1;;;;;;;:::i;:::-;63443:31;63455:11;63468:5;63443:11;:31::i;66281:336::-:0;66413:53;;-1:-1:-1;;;66413:53:0;;;;;9684:25:1;;;9752:14;;9745:22;9725:18;;;9718:50;66379:7:0;;;;66413:4;;:27;;9657:18:1;;66413:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66393:73;;66473:18;66498:9;-1:-1:-1;;;;;66498:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66471:54;;;;;;66530:17;66579:11;66551:9;66563:4;66551:16;;;;:::i;47061:657::-;47182:13;47210:18;;47182:13;;;47210:18;47484:41;:5;47511:13;47484:26;:41::i;:::-;47540:47;:8;47570:16;47540:29;:47::i;:::-;47683:16;;;47666:1;47683:16;;;;;;;;;-1:-1:-1;;;47431:279:0;;;-1:-1:-1;47431:279:0;;-1:-1:-1;47602:13:0;;-1:-1:-1;47638:4:0;;-1:-1:-1;47666:1:0;-1:-1:-1;47683:16:0;-1:-1:-1;47431:279:0;-1:-1:-1;47061:657:0:o;66008:268::-;66052:19;66074:41;66104:10;66074:29;:41::i;:::-;66147:10;66120:38;;;;:26;:38;;;;;:53;;66052:63;;-1:-1:-1;66052:63:0;;66120:38;;;:53;;66052:63;;66120:53;:::i;:::-;;;;-1:-1:-1;;66178:44:0;;-1:-1:-1;;;66178:44:0;;66198:10;66178:44;;;11787:51:1;11854:18;;;11847:34;;;66178:10:0;-1:-1:-1;;;;;66178:19:0;;;;11760:18:1;;66178:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;66232:39:0;;;66247:10;11787:51:1;;11869:2;11854:18;;11847:34;;;66232:39:0;;11760:18:1;66232:39:0;;;;;;;;66047:229;66008:268::o;54677:147::-;54763:4;54787:12;;;;;;;;;;;-1:-1:-1;;;;;54787:29:0;;;;;;;;;;;;;;;54677:147::o;63709:655::-;63832:9;;61983:12;;;;:22;;;;;;;;:::i;:::-;;61975:78;;;;-1:-1:-1;;;61975:78:0;;;;;;;:::i;:::-;63856:30:::1;::::0;-1:-1:-1;;;63856:30:0;;::::1;::::0;::::1;597:25:1::0;;;63890:12:0::1;::::0;63856:4:::1;::::0;:17:::1;::::0;570:18:1;;63856:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;;63848:94;;;;-1:-1:-1::0;;;63848:94:0::1;;;;;;;:::i;:::-;63996:66;::::0;;64007:47:::1;63996:66;::::0;::::1;8626:25:1::0;8667:18;;;8660:34;;;63947:14:0::1;::::0;63964:104:::1;::::0;8599:18:1;;63996:66:0::1;8452:248:1::0;63964:104:0::1;63947:121;;64073:23;64099:32;64113:6;64121:9;64099:13;:32::i;:::-;64073:58;;64144:37;60215:24;64165:15;64144:7;:37::i;:::-;64136:86;;;;-1:-1:-1::0;;;64136:86:0::1;;;;;;;:::i;:::-;64236:17;::::0;;;:10:::1;:17;::::0;;;;;::::1;;64235:18;64227:68;;;;-1:-1:-1::0;;;64227:68:0::1;;;;;;;:::i;:::-;64300:17;::::0;;;:10:::1;:17;::::0;;;;:24;;-1:-1:-1;;64300:24:0::1;64320:4;64300:24:::0;;::::1;::::0;;;64329:30:::1;::::0;64341:11;;64329::::1;:30::i;57085:149::-:0;56278:7;56305:12;;;;;;;;;;:22;;;54273:16;54284:4;54273:10;:16::i;:::-;57200:26:::1;57212:4;57218:7;57200:11;:26::i;66881:333::-:0;66974:7;66990:18;67015:9;-1:-1:-1;;;;;67015:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66988:54;;;;;;67047:17;67104:4;67088:11;67068:9;:32;;;;:::i;:::-;67067:41;;;;:::i;:::-;67135:51;;-1:-1:-1;;;67135:51:0;;;;;9684:25:1;;;9752:14;;9745:22;9725:18;;;9718:50;67047:61:0;;-1:-1:-1;67113:19:0;;67135:4;;:27;;9657:18:1;;67135:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;63484:220::-;63552:9;;61983:12;;;;:22;;;;;;;;:::i;:::-;;61975:78;;;;-1:-1:-1;;;61975:78:0;;;;;;;:::i;:::-;63576:30:::1;::::0;-1:-1:-1;;;63576:30:0;;::::1;::::0;::::1;597:25:1::0;;;63610:12:0::1;::::0;63576:4:::1;::::0;:17:::1;::::0;570:18:1;;63576:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;;63568:94;;;;-1:-1:-1::0;;;63568:94:0::1;;;;;;;:::i;:::-;63667:32;63680:11;63693:5;63667:12;:32::i;65752:251::-:0;65792:19;65814:37;65840:10;65814:25;:37::i;:::-;65879:10;65856:34;;;;:22;:34;;;;;;;:48;;;65909:44;-1:-1:-1;;;65909:44:0;;;;;11787:51:1;;;;11854:18;;;11847:34;;;65856:48:0;;-1:-1:-1;;;;;;65909:10:0;:19;;;;11760:18:1;;65909:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;65963:35:0;;;65974:10;11787:51:1;;11869:2;11854:18;;11847:34;;;65963:35:0;;11760:18:1;65963:35:0;11613:274:1;65024:212:0;65094:7;65128:11;65112:12;;;;:27;;;;;;;;:::i;:::-;;65108:53;;-1:-1:-1;65154:1:0;;65024:212;-1:-1:-1;65024:212:0:o;65108:53::-;-1:-1:-1;;;;;65203:28:0;;;;;;:22;:28;;;;;;;;;65174:20;:26;;;;;;;:57;;65203:28;65174:57;:::i;68711:294::-;68764:9;;61983:12;;;;:22;;;;;;;;:::i;:::-;;61975:78;;;;-1:-1:-1;;;61975:78:0;;;;;;;:::i;:::-;53827:4:::1;54273:16;53827:4:::0;54273:10:::1;:16::i;:::-;68809:32:::2;68829:11;68809:19;:32::i;:::-;68884;:20;68892:11;68884:20;68908:7;68884:32;:::i;:::-;68865:52;::::0;:15:::2;:52;:::i;:::-;68846:16;:71:::0;68959:40:::2;:28;68967:19;68959:28;68991:7;68959:40;:::i;:::-;68939:16;;:61;;;;:::i;:::-;68922:14;:78:::0;-1:-1:-1;;68711:294:0:o;70752:128::-;70818:7;70871:4;70840:27;70854:13;70840:11;:27;:::i;:::-;70839:36;;;;:::i;70885:326::-;70956:7;70989:10;70974:11;:25;70970:222;;-1:-1:-1;71014:2:0;;70885:326;-1:-1:-1;70885:326:0:o;70970:222::-;71047:10;71032:11;:25;71028:164;;-1:-1:-1;71072:1:0;;70885:326;-1:-1:-1;70885:326:0:o;71028:164::-;71104:10;71089:11;:25;71085:107;;-1:-1:-1;71129:1:0;;70885:326;-1:-1:-1;70885:326:0:o;71085:107::-;71161:9;71146:11;:24;71142:50;;-1:-1:-1;71185:1:0;;70885:326;-1:-1:-1;70885:326:0:o;71142:50::-;-1:-1:-1;71205:1:0;;70885:326;-1:-1:-1;70885:326:0:o;46799:167::-;46876:7;46903:55;46925:20;:18;:20::i;:::-;46947:10;41359:4;41353:11;-1:-1:-1;;;41378:23:0;;41431:4;41422:14;;41415:39;;;;41484:4;41475:14;;41468:34;41539:4;41524:20;;;41156:406;36372:231;36450:7;36471:17;36490:18;36512:27;36523:4;36529:9;36512:10;:27::i;:::-;36470:69;;;;36550:18;36562:5;36550:11;:18::i;:::-;-1:-1:-1;36586:9:0;36372:231;-1:-1:-1;;;36372:231:0:o;69913:834::-;70013:35;;-1:-1:-1;;;70013:35:0;;70042:4;70013:35;;;3940:51:1;69988:22:0;;70013:10;-1:-1:-1;;;;;70013:20:0;;;;3913:18:1;;70013:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69988:60;;70072:14;70057:11;:29;70053:75;;70108:14;70094:28;;70053:75;70155:11;70134:17;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;;70200:58:0;;-1:-1:-1;;;70200:58:0;;;;;9684:25:1;;;9752:14;;9745:22;9725:18;;;9718:50;70171:26:0;;70200:4;;:32;;9657:18:1;;70200:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;70308:136;;70384:10;70308:136;;;12398:34:1;-1:-1:-1;;;;;70401:12:0;12468:15:1;;12448:18;;;12441:43;12500:18;;;12493:34;;;;;-1:-1:-1;;;70292:4:0;70284:18;;12333::1;;70308:136:0;;;-1:-1:-1;;70308:136:0;;;;;;;;;;;;;;-1:-1:-1;;;;;70308:136:0;-1:-1:-1;;;70308:136:0;;;70284:165;;;70308:136;70284:165;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70265:184;;;70462:7;70454:62;;;;-1:-1:-1;;;70454:62:0;;13032:2:1;70454:62:0;;;13014:21:1;13071:2;13051:18;;;13044:30;13110:34;13090:18;;;13083:62;-1:-1:-1;;;13161:18:1;;;13154:40;13211:19;;70454:62:0;12830:406:1;70454:62:0;70523:17;70543:40;70565:18;70543:40;70544:17;70558:3;70544:11;:17;:::i;:::-;70543:40;;;;:::i;:::-;70609:10;70588:32;;;;:20;:32;;;;;:45;;70523:60;;-1:-1:-1;70523:60:0;;70588:32;;;:45;;70523:60;;70588:45;:::i;:::-;;;;-1:-1:-1;70678:23:0;;-1:-1:-1;70692:9:0;70678:11;:23;:::i;:::-;70663:10;70638:36;;;;:24;:36;;;;;:63;;:36;;;:63;;;;;:::i;:::-;;;;-1:-1:-1;;70711:31:0;;;70718:10;11787:51:1;;11869:2;11854:18;;11847:34;;;70711:31:0;;11760:18:1;70711:31:0;;;;;;;69983:764;;;;69913:834;;:::o;55128:105::-;55195:30;55206:4;48490:10;55195;:30::i;:::-;55128:105;:::o;59386:238::-;59470:22;59478:4;59484:7;59470;:22::i;:::-;59465:152;;59509:6;:12;;;;;;;;;;;-1:-1:-1;;;;;59509:29:0;;;;;;;;;:36;;-1:-1:-1;;59509:36:0;59541:4;59509:36;;;59592:12;48490:10;;48410:98;59592:12;-1:-1:-1;;;;;59565:40:0;59583:7;-1:-1:-1;;;;;59565:40:0;59577:4;59565:40;;;;;;;;;;59386:238;;:::o;59804:239::-;59888:22;59896:4;59902:7;59888;:22::i;:::-;59884:152;;;59959:5;59927:12;;;;;;;;;;;-1:-1:-1;;;;;59927:29:0;;;;;;;;;;:37;;-1:-1:-1;;59927:37:0;;;59984:40;48490:10;;59927:12;;59984:40;;59959:5;59984:40;59804:239;;:::o;71216:113::-;71273:12;:21;;71288:6;;71273:12;-1:-1:-1;;71273:21:0;;71288:6;71273:21;;;;;;;;:::i;:::-;;;;;;71304:20;71317:6;71304:20;;;;;;:::i;69010:898::-;69109:35;;-1:-1:-1;;;69109:35:0;;69138:4;69109:35;;;3940:51:1;69084:22:0;;69109:10;-1:-1:-1;;;;;69109:20:0;;;;3913:18:1;;69109:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69084:60;;69168:14;69153:11;:29;69149:75;;69204:14;69190:28;;69149:75;69258:57;;-1:-1:-1;;;69258:57:0;;;;;9684:25:1;;;9752:14;;9745:22;9725:18;;;9718:50;69230:25:0;;69258:4;;:31;;9657:18:1;;69258:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69230:85;;69341:17;69328:9;:30;;69320:80;;;;-1:-1:-1;;;69320:80:0;;13443:2:1;69320:80:0;;;13425:21:1;13482:2;13462:18;;;13455:30;13521:34;13501:18;;;13494:62;-1:-1:-1;;;13572:18:1;;;13565:35;13617:19;;69320:80:0;13241:401:1;69320:80:0;69428:11;69407:17;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;69446:17:0;;-1:-1:-1;69466:40:0;69488:18;69466:40;69467:17;69481:3;69467:11;:17;:::i;:::-;69466:40;;;;:::i;:::-;69532:10;69511:32;;;;:20;:32;;;;;:45;;69446:60;;-1:-1:-1;69446:60:0;;69511:32;;;:45;;69446:60;;69511:45;:::i;:::-;;;;-1:-1:-1;69601:23:0;;-1:-1:-1;69615:9:0;69601:11;:23;:::i;:::-;69586:10;69561:36;;;;:24;:36;;;;;:63;;:36;;;:63;;;;;:::i;:::-;;;;-1:-1:-1;;69634:31:0;;;69641:10;11787:51:1;;11869:2;11854:18;;11847:34;;;69634:31:0;;11760:18:1;69634:31:0;;;;;;;69688:17;69676:9;:29;69672:185;;;69759:16;69778:29;69790:17;69778:9;:29;:::i;:::-;69813:38;;69759:48;;-1:-1:-1;69821:10:0;;69813:38;;;;;69759:48;;69813:38;;;;69759:48;69821:10;69813:38;;;;;;;;;;;;;;;;;;;;;69707:150;69672:185;69863:40;;-1:-1:-1;;;;;69863:12:0;:21;;:40;;;;;69885:17;;69863:40;;;;69885:17;69863:21;:40;;;;;;;;;;;;;;;;;;;12369:274;12463:13;10314:66;12493:47;;12489:147;;12564:15;12573:5;12564:8;:15::i;:::-;12557:22;;;;12489:147;12619:5;12612:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45699:268;45752:7;45784:4;-1:-1:-1;;;;;45793:11:0;45776:28;;:63;;;;;45825:14;45808:13;:31;45776:63;45772:188;;;-1:-1:-1;45863:22:0;;45699:268::o;45772:188::-;45925:23;46067:81;;;43891:95;46067:81;;;16449:25:1;46090:11:0;16490:18:1;;;16483:34;;;;46103:14:0;16533:18:1;;;16526:34;46119:13:0;16576:18:1;;;16569:34;46142:4:0;16619:19:1;;;16612:61;46030:7:0;;16421:19:1;;46067:81:0;;;;;;;;;;;;46057:92;;;;;;46050:99;;45975:182;;45925:23;45918:30;;45699:268;:::o;34823:747::-;34904:7;34913:12;34942:9;:16;34962:2;34942:22;34938:625;;35286:4;35271:20;;35265:27;35336:4;35321:20;;35315:27;35394:4;35379:20;;35373:27;34981:9;35365:36;35437:25;35448:4;35365:36;35265:27;35315;35437:10;:25::i;:::-;35430:32;;;;;;;;;34938:625;-1:-1:-1;35511:1:0;;-1:-1:-1;35515:35:0;34938:625;34823:747;;;;;:::o;33216:521::-;33294:20;33285:5;:29;;;;;;;;:::i;:::-;;33281:449;;33216:521;:::o;33281:449::-;33392:29;33383:5;:38;;;;;;;;:::i;:::-;;33379:351;;33438:34;;-1:-1:-1;;;33438:34:0;;14234:2:1;33438:34:0;;;14216:21:1;14273:2;14253:18;;;14246:30;14312:26;14292:18;;;14285:54;14356:18;;33438:34:0;14032:348:1;33379:351:0;33503:35;33494:5;:44;;;;;;;;:::i;:::-;;33490:240;;33555:41;;-1:-1:-1;;;33555:41:0;;14587:2:1;33555:41:0;;;14569:21:1;14626:2;14606:18;;;14599:30;14665:33;14645:18;;;14638:61;14716:18;;33555:41:0;14385:355:1;33490:240:0;33627:30;33618:5;:39;;;;;;;;:::i;:::-;;33614:116;;33674:44;;-1:-1:-1;;;33674:44:0;;14947:2:1;33674:44:0;;;14929:21:1;14986:2;14966:18;;;14959:30;15025:34;15005:18;;;14998:62;-1:-1:-1;;;15076:18:1;;;15069:32;15118:19;;33674:44:0;14745:398:1;55523:492:0;55612:22;55620:4;55626:7;55612;:22::i;:::-;55607:401;;55800:28;55820:7;55800:19;:28::i;:::-;55901:38;55929:4;55936:2;55901:19;:38::i;:::-;55705:257;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;55705:257:0;;;;;;;;;;-1:-1:-1;;;55651:345:0;;;;;;;:::i;11023:415::-;11082:13;11108:11;11122:16;11133:4;11122:10;:16::i;:::-;11248:14;;;11259:2;11248:14;;;;;;;;;11108:30;;-1:-1:-1;11228:17:0;;11248:14;;;;;;;;;-1:-1:-1;;;11341:16:0;;;-1:-1:-1;11387:4:0;11378:14;;11371:28;;;;-1:-1:-1;11341:16:0;11023:415::o;37756:1477::-;37844:7;;38778:66;38765:79;;38761:163;;;-1:-1:-1;38877:1:0;;-1:-1:-1;38881:30:0;38861:51;;38761:163;39038:24;;;39021:14;39038:24;;;;;;;;;16911:25:1;;;16984:4;16972:17;;16952:18;;;16945:45;;;;17006:18;;;16999:34;;;17049:18;;;17042:34;;;39038:24:0;;16883:19:1;;39038:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;39038:24:0;;-1:-1:-1;;39038:24:0;;;-1:-1:-1;;;;;;;39077:20:0;;39073:103;;39130:1;39134:29;39114:50;;;;;;;39073:103;39196:6;-1:-1:-1;39204:20:0;;-1:-1:-1;37756:1477:0;;;;;;;;:::o;32224:151::-;32282:13;32315:52;-1:-1:-1;;;;;32327:22:0;;30099:2;31620:447;31695:13;31721:19;31753:10;31757:6;31753:1;:10;:::i;:::-;:14;;31766:1;31753:14;:::i;:::-;31743:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31743:25:0;;31721:47;;-1:-1:-1;;;31779:6:0;31786:1;31779:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;31779:15:0;;;;;;;;;-1:-1:-1;;;31805:6:0;31812:1;31805:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;31805:15:0;;;;;;;;-1:-1:-1;31836:9:0;31848:10;31852:6;31848:1;:10;:::i;:::-;:14;;31861:1;31848:14;:::i;:::-;31836:26;;31831:131;31868:1;31864;:5;31831:131;;;-1:-1:-1;;;31912:5:0;31920:3;31912:11;31903:21;;;;;;;:::i;:::-;;;;31891:6;31898:1;31891:9;;;;;;;;:::i;:::-;;;;:33;-1:-1:-1;;;;;31891:33:0;;;;;;;;-1:-1:-1;31949:1:0;31939:11;;;;;31871:3;;;:::i;:::-;;;31831:131;;;-1:-1:-1;31980:10:0;;31972:55;;;;-1:-1:-1;;;31972:55:0;;17562:2:1;31972:55:0;;;17544:21:1;;;17581:18;;;17574:30;17640:34;17620:18;;;17613:62;17692:18;;31972:55:0;17360:356:1;31972:55:0;32052:6;31620:447;-1:-1:-1;;;31620:447:0:o;11515:251::-;11576:7;11649:4;11613:40;;11677:2;11668:11;;11664:71;;;11703:20;;-1:-1:-1;;;11703:20:0;;;;;;;;;;;14:118:1;100:5;93:13;86:21;79:5;76:32;66:60;;122:1;119;112:12;137:309;202:6;210;263:2;251:9;242:7;238:23;234:32;231:52;;;279:1;276;269:12;231:52;315:9;302:23;292:33;;375:2;364:9;360:18;347:32;388:28;410:5;388:28;:::i;:::-;435:5;425:15;;;137:309;;;;;:::o;633:286::-;691:6;744:2;732:9;723:7;719:23;715:32;712:52;;;760:1;757;750:12;712:52;786:23;;-1:-1:-1;;;;;;838:32:1;;828:43;;818:71;;885:1;882;875:12;1116:127;1177:10;1172:3;1168:20;1165:1;1158:31;1208:4;1205:1;1198:15;1232:4;1229:1;1222:15;1248:338;1390:2;1375:18;;1423:1;1412:13;;1402:144;;1468:10;1463:3;1459:20;1456:1;1449:31;1503:4;1500:1;1493:15;1531:4;1528:1;1521:15;1402:144;1555:25;;;1248:338;:::o;1591:173::-;1659:20;;-1:-1:-1;;;;;1708:31:1;;1698:42;;1688:70;;1754:1;1751;1744:12;1688:70;1591:173;;;:::o;1769:186::-;1828:6;1881:2;1869:9;1860:7;1856:23;1852:32;1849:52;;;1897:1;1894;1887:12;1849:52;1920:29;1939:9;1920:29;:::i;1960:127::-;2021:10;2016:3;2012:20;2009:1;2002:31;2052:4;2049:1;2042:15;2076:4;2073:1;2066:15;2092:1057;2178:6;2186;2194;2247:2;2235:9;2226:7;2222:23;2218:32;2215:52;;;2263:1;2260;2253:12;2215:52;2299:9;2286:23;2276:33;;2356:2;2345:9;2341:18;2328:32;2318:42;;2411:2;2400:9;2396:18;2383:32;2434:18;2475:2;2467:6;2464:14;2461:34;;;2491:1;2488;2481:12;2461:34;2529:6;2518:9;2514:22;2504:32;;2574:7;2567:4;2563:2;2559:13;2555:27;2545:55;;2596:1;2593;2586:12;2545:55;2632:2;2619:16;2654:2;2650;2647:10;2644:36;;;2660:18;;:::i;:::-;2735:2;2729:9;2703:2;2789:13;;-1:-1:-1;;2785:22:1;;;2809:2;2781:31;2777:40;2765:53;;;2833:18;;;2853:22;;;2830:46;2827:72;;;2879:18;;:::i;:::-;2919:10;2915:2;2908:22;2954:2;2946:6;2939:18;2994:7;2989:2;2984;2980;2976:11;2972:20;2969:33;2966:53;;;3015:1;3012;3005:12;2966:53;3071:2;3066;3062;3058:11;3053:2;3045:6;3041:15;3028:46;3116:1;3111:2;3106;3098:6;3094:15;3090:24;3083:35;3137:6;3127:16;;;;;;;2092:1057;;;;;:::o;3154:180::-;3213:6;3266:2;3254:9;3245:7;3241:23;3237:32;3234:52;;;3282:1;3279;3272:12;3234:52;-1:-1:-1;3305:23:1;;3154:180;-1:-1:-1;3154:180:1:o;3521:254::-;3589:6;3597;3650:2;3638:9;3629:7;3625:23;3621:32;3618:52;;;3666:1;3663;3656:12;3618:52;3702:9;3689:23;3679:33;;3731:38;3765:2;3754:9;3750:18;3731:38;:::i;:::-;3721:48;;3521:254;;;;;:::o;4612:250::-;4697:1;4707:113;4721:6;4718:1;4715:13;4707:113;;;4797:11;;;4791:18;4778:11;;;4771:39;4743:2;4736:10;4707:113;;;-1:-1:-1;;4854:1:1;4836:16;;4829:27;4612:250::o;4867:271::-;4909:3;4947:5;4941:12;4974:6;4969:3;4962:19;4990:76;5059:6;5052:4;5047:3;5043:14;5036:4;5029:5;5025:16;4990:76;:::i;:::-;5120:2;5099:15;-1:-1:-1;;5095:29:1;5086:39;;;;5127:4;5082:50;;4867:271;-1:-1:-1;;4867:271:1:o;5143:1259::-;5549:3;5544;5540:13;5532:6;5528:26;5517:9;5510:45;5491:4;5574:2;5612:3;5607:2;5596:9;5592:18;5585:31;5639:46;5680:3;5669:9;5665:19;5657:6;5639:46;:::i;:::-;5733:9;5725:6;5721:22;5716:2;5705:9;5701:18;5694:50;5767:33;5793:6;5785;5767:33;:::i;:::-;5831:2;5816:18;;5809:34;;;-1:-1:-1;;;;;5880:32:1;;5874:3;5859:19;;5852:61;5900:3;5929:19;;5922:35;;;5994:22;;;5988:3;5973:19;;5966:51;6066:13;;6088:22;;;6164:15;;;;-1:-1:-1;6126:15:1;;;;-1:-1:-1;6207:169:1;6221:6;6218:1;6215:13;6207:169;;;6282:13;;6270:26;;6351:15;;;;6316:12;;;;6243:1;6236:9;6207:169;;;-1:-1:-1;6393:3:1;;5143:1259;-1:-1:-1;;;;;;;;;;;;5143:1259:1:o;6631:127::-;6692:10;6687:3;6683:20;6680:1;6673:31;6723:4;6720:1;6713:15;6747:4;6744:1;6737:15;6763:168;6836:9;;;6867;;6884:15;;;6878:22;;6864:37;6854:71;;6905:18;;:::i;6936:217::-;6976:1;7002;6992:132;;7046:10;7041:3;7037:20;7034:1;7027:31;7081:4;7078:1;7071:15;7109:4;7106:1;7099:15;6992:132;-1:-1:-1;7138:9:1;;6936:217::o;7158:128::-;7225:9;;;7246:11;;;7243:37;;;7260:18;;:::i;7291:151::-;7381:4;7374:12;;;7360;;;7356:31;;7399:14;;7396:40;;;7416:18;;:::i;7447:407::-;7649:2;7631:21;;;7688:2;7668:18;;;7661:30;7727:34;7722:2;7707:18;;7700:62;-1:-1:-1;;;7793:2:1;7778:18;;7771:41;7844:3;7829:19;;7447:407::o;7859:184::-;7929:6;7982:2;7970:9;7961:7;7957:23;7953:32;7950:52;;;7998:1;7995;7988:12;7950:52;-1:-1:-1;8021:16:1;;7859:184;-1:-1:-1;7859:184:1:o;8048:399::-;8250:2;8232:21;;;8289:2;8269:18;;;8262:30;8328:34;8323:2;8308:18;;8301:62;-1:-1:-1;;;8394:2:1;8379:18;;8372:33;8437:3;8422:19;;8048:399::o;8705:400::-;8907:2;8889:21;;;8946:2;8926:18;;;8919:30;8985:34;8980:2;8965:18;;8958:62;-1:-1:-1;;;9051:2:1;9036:18;;9029:34;9095:3;9080:19;;8705:400::o;9110:401::-;9312:2;9294:21;;;9351:2;9331:18;;;9324:30;9390:34;9385:2;9370:18;;9363:62;-1:-1:-1;;;9456:2:1;9441:18;;9434:35;9501:3;9486:19;;9110:401::o;10821:179::-;10899:13;;10952:22;10941:34;;10931:45;;10921:73;;10990:1;10987;10980:12;11005:473;11108:6;11116;11124;11132;11140;11193:3;11181:9;11172:7;11168:23;11164:33;11161:53;;;11210:1;11207;11200:12;11161:53;11233:39;11262:9;11233:39;:::i;:::-;11223:49;;11312:2;11301:9;11297:18;11291:25;11281:35;;11356:2;11345:9;11341:18;11335:25;11325:35;;11400:2;11389:9;11385:18;11379:25;11369:35;;11423:49;11467:3;11456:9;11452:19;11423:49;:::i;:::-;11413:59;;11005:473;;;;;;;;:::o;11483:125::-;11548:9;;;11569:10;;;11566:36;;;11582:18;;:::i;11892:245::-;11959:6;12012:2;12000:9;11991:7;11987:23;11983:32;11980:52;;;12028:1;12025;12018:12;11980:52;12060:9;12054:16;12079:28;12101:5;12079:28;:::i;12538:287::-;12667:3;12705:6;12699:13;12721:66;12780:6;12775:3;12768:4;12760:6;12756:17;12721:66;:::i;:::-;12803:16;;;;;12538:287;-1:-1:-1;;12538:287:1:o;13647:380::-;13726:1;13722:12;;;;13769;;;13790:61;;13844:4;13836:6;13832:17;13822:27;;13790:61;13897:2;13889:6;13886:14;13866:18;13863:38;13860:161;;13943:10;13938:3;13934:20;13931:1;13924:31;13978:4;13975:1;13968:15;14006:4;14003:1;13996:15;13860:161;;13647:380;;;:::o;15148:812::-;15559:25;15554:3;15547:38;15529:3;15614:6;15608:13;15630:75;15698:6;15693:2;15688:3;15684:12;15677:4;15669:6;15665:17;15630:75;:::i;:::-;-1:-1:-1;;;15764:2:1;15724:16;;;15756:11;;;15749:40;15814:13;;15836:76;15814:13;15898:2;15890:11;;15883:4;15871:17;;15836:76;:::i;:::-;15932:17;15951:2;15928:26;;15148:812;-1:-1:-1;;;;15148:812:1:o;15965:220::-;16114:2;16103:9;16096:21;16077:4;16134:45;16175:2;16164:9;16160:18;16152:6;16134:45;:::i;17087:127::-;17148:10;17143:3;17139:20;17136:1;17129:31;17179:4;17176:1;17169:15;17203:4;17200:1;17193:15;17219:136;17258:3;17286:5;17276:39;;17295:18;;:::i;:::-;-1:-1:-1;;;17331:18:1;;17219:136::o
Swarm Source
ipfs://6d1e2ccc3840a2da54a7bc51bcb9037b0d87803b46108816e1840a9b463b11f0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ 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.