ETH Price: $2,810.87 (+0.13%)
 

Overview

Max Total Supply

0.00000000001 TOON

Holders

5

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
ToonCity: Deployer
Balance
0.0000000000000003 TOON

Value
$0.00
0x5dfcb24c3152efbbbd94c76361376c2aed9dd557
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
MyToken

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-04-06
*/

//                   ___           ___           ___                    ___           ___                       ___     
//       ___        /  /\         /  /\         /__/\                  /  /\         /  /\        ___          /__/\    
//      /  /\      /  /::\       /  /::\        \  \:\                /  /:/        /  /::\      /  /\         \  \:\   
//     /  /:/     /  /:/\:\     /  /:/\:\        \  \:\              /  /:/        /  /:/\:\    /  /:/          \  \:\  
//    /  /:/     /  /:/  \:\   /  /:/  \:\   _____\__\:\            /  /:/  ___   /  /:/  \:\  /__/::\      _____\__\:\ 
//   /  /::\    /__/:/ \__\:\ /__/:/ \__\:\ /__/::::::::\          /__/:/  /  /\ /__/:/ \__\:\ \__\/\:\__  /__/::::::::\
//  /__/:/\:\   \  \:\ /  /:/ \  \:\ /  /:/ \  \:\~~\~~\/          \  \:\ /  /:/ \  \:\ /  /:/    \  \:\/\ \  \:\~~\~~\/
//  \__\/  \:\   \  \:\  /:/   \  \:\  /:/   \  \:\  ~~~            \  \:\  /:/   \  \:\  /:/      \__\::/  \  \:\  ~~~ 
//       \  \:\   \  \:\/:/     \  \:\/:/     \  \:\                 \  \:\/:/     \  \:\/:/       /__/:/    \  \:\     
//        \__\/    \  \::/       \  \::/       \  \:\                 \  \::/       \  \::/        \__\/      \  \:\    
//                  \__\/         \__\/         \__\/                  \__\/         \__\/                     \__\/    

// File: @openzeppelin/contracts/utils/Counters.sol


// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.8.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) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 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 10, 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 * 8) < value ? 1 : 0);
        }
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts (last updated v4.8.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 `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);
    }
}

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol


// OpenZeppelin Contracts (last updated v4.8.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) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @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) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

// File: @openzeppelin/contracts/utils/cryptography/EIP712.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/EIP712.sol)

pragma solidity ^0.8.0;


/**
 * @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].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // 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 _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;

    /* solhint-enable var-name-mixedcase */

    /**
     * @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) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, 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);
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _totalSupply -= amount;
        }

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/draft-ERC20Permit.sol)

pragma solidity ^0.8.0;






/**
 * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * _Available since v3.4._
 */
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
    using Counters for Counters.Counter;

    mapping(address => Counters.Counter) private _nonces;

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private constant _PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    /**
     * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.
     * However, to ensure consistency with the upgradeable transpiler, we will continue
     * to reserve a slot.
     * @custom:oz-renamed-from _PERMIT_TYPEHASH
     */
    // solhint-disable-next-line var-name-mixedcase
    bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC20 token name.
     */
    constructor(string memory name) EIP712(name, "1") {}

    /**
     * @dev See {IERC20Permit-permit}.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        require(signer == owner, "ERC20Permit: invalid signature");

        _approve(owner, spender, value);
    }

    /**
     * @dev See {IERC20Permit-nonces}.
     */
    function nonces(address owner) public view virtual override returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev "Consume a nonce": return the current value and increment.
     *
     * _Available since v4.1._
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.0;



/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        _spendAllowance(account, _msgSender(), amount);
        _burn(account, amount);
    }
}

// File: contracts/tooncoin.sol


pragma solidity ^0.8.17;





contract MyToken is ERC20, ERC20Burnable, Ownable, ERC20Permit {
    constructor() ERC20("TOON", "TOON") ERC20Permit("TOON") {}

    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101406040523480156200001257600080fd5b506040518060400160405280600481526020017f544f4f4e00000000000000000000000000000000000000000000000000000000815250806040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f544f4f4e000000000000000000000000000000000000000000000000000000008152506040518060400160405280600481526020017f544f4f4e000000000000000000000000000000000000000000000000000000008152508160039081620000fd91906200056f565b5080600490816200010f91906200056f565b5050506200013262000126620001eb60201b60201c565b620001f360201b60201c565b60008280519060200120905060008280519060200120905060007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90508260e081815250508161010081815250504660a081815250506200019b818484620002b960201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff168152505080610120818152505050505050505062000724565b600033905090565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008383834630604051602001620002d6959493929190620006c7565b6040516020818303038152906040528051906020012090509392505050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200037757607f821691505b6020821081036200038d576200038c6200032f565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620003f77fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620003b8565b620004038683620003b8565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620004506200044a62000444846200041b565b62000425565b6200041b565b9050919050565b6000819050919050565b6200046c836200042f565b620004846200047b8262000457565b848454620003c5565b825550505050565b600090565b6200049b6200048c565b620004a881848462000461565b505050565b5b81811015620004d057620004c460008262000491565b600181019050620004ae565b5050565b601f8211156200051f57620004e98162000393565b620004f484620003a8565b8101602085101562000504578190505b6200051c6200051385620003a8565b830182620004ad565b50505b505050565b600082821c905092915050565b6000620005446000198460080262000524565b1980831691505092915050565b60006200055f838362000531565b9150826002028217905092915050565b6200057a82620002f5565b67ffffffffffffffff81111562000596576200059562000300565b5b620005a282546200035e565b620005af828285620004d4565b600060209050601f831160018114620005e75760008415620005d2578287015190505b620005de858262000551565b8655506200064e565b601f198416620005f78662000393565b60005b828110156200062157848901518255600182019150602085019450602081019050620005fa565b868310156200064157848901516200063d601f89168262000531565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b6200066b8162000656565b82525050565b6200067c816200041b565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620006af8262000682565b9050919050565b620006c181620006a2565b82525050565b600060a082019050620006de600083018862000660565b620006ed602083018762000660565b620006fc604083018662000660565b6200070b606083018562000671565b6200071a6080830184620006b6565b9695505050505050565b60805160a05160c05160e0516101005161012051612789620007746000396000610f5101526000610f9301526000610f7201526000610ea701526000610efd01526000610f2601526127896000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c8063715018a6116100ad578063a457c2d711610071578063a457c2d714610333578063a9059cbb14610363578063d505accf14610393578063dd62ed3e146103af578063f2fde38b146103df5761012c565b8063715018a6146102a157806379cc6790146102ab5780637ecebe00146102c75780638da5cb5b146102f757806395d89b41146103155761012c565b80633644e515116100f45780633644e515146101eb578063395093511461020957806340c10f191461023957806342966c681461025557806370a08231146102715761012c565b806306fdde0314610131578063095ea7b31461014f57806318160ddd1461017f57806323b872dd1461019d578063313ce567146101cd575b600080fd5b6101396103fb565b604051610146919061183a565b60405180910390f35b610169600480360381019061016491906118f5565b61048d565b6040516101769190611950565b60405180910390f35b6101876104b0565b604051610194919061197a565b60405180910390f35b6101b760048036038101906101b29190611995565b6104ba565b6040516101c49190611950565b60405180910390f35b6101d56104e9565b6040516101e29190611a04565b60405180910390f35b6101f36104f2565b6040516102009190611a38565b60405180910390f35b610223600480360381019061021e91906118f5565b610501565b6040516102309190611950565b60405180910390f35b610253600480360381019061024e91906118f5565b610538565b005b61026f600480360381019061026a9190611a53565b61054e565b005b61028b60048036038101906102869190611a80565b610562565b604051610298919061197a565b60405180910390f35b6102a96105aa565b005b6102c560048036038101906102c091906118f5565b6105be565b005b6102e160048036038101906102dc9190611a80565b6105de565b6040516102ee919061197a565b60405180910390f35b6102ff61062e565b60405161030c9190611abc565b60405180910390f35b61031d610658565b60405161032a919061183a565b60405180910390f35b61034d600480360381019061034891906118f5565b6106ea565b60405161035a9190611950565b60405180910390f35b61037d600480360381019061037891906118f5565b610761565b60405161038a9190611950565b60405180910390f35b6103ad60048036038101906103a89190611b2f565b610784565b005b6103c960048036038101906103c49190611bd1565b6108c6565b6040516103d6919061197a565b60405180910390f35b6103f960048036038101906103f49190611a80565b61094d565b005b60606003805461040a90611c40565b80601f016020809104026020016040519081016040528092919081815260200182805461043690611c40565b80156104835780601f1061045857610100808354040283529160200191610483565b820191906000526020600020905b81548152906001019060200180831161046657829003601f168201915b5050505050905090565b6000806104986109d0565b90506104a58185856109d8565b600191505092915050565b6000600254905090565b6000806104c56109d0565b90506104d2858285610ba1565b6104dd858585610c2d565b60019150509392505050565b60006012905090565b60006104fc610ea3565b905090565b60008061050c6109d0565b905061052d81858561051e85896108c6565b6105289190611ca0565b6109d8565b600191505092915050565b610540610fbd565b61054a828261103b565b5050565b61055f6105596109d0565b82611191565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6105b2610fbd565b6105bc600061135e565b565b6105d0826105ca6109d0565b83610ba1565b6105da8282611191565b5050565b6000610627600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611424565b9050919050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606004805461066790611c40565b80601f016020809104026020016040519081016040528092919081815260200182805461069390611c40565b80156106e05780601f106106b5576101008083540402835291602001916106e0565b820191906000526020600020905b8154815290600101906020018083116106c357829003601f168201915b5050505050905090565b6000806106f56109d0565b9050600061070382866108c6565b905083811015610748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f90611d46565b60405180910390fd5b61075582868684036109d8565b60019250505092915050565b60008061076c6109d0565b9050610779818585610c2d565b600191505092915050565b834211156107c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107be90611db2565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886107f68c611432565b8960405160200161080c96959493929190611dd2565b604051602081830303815290604052805190602001209050600061082f82611490565b9050600061083f828787876114aa565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a690611e7f565b60405180910390fd5b6108ba8a8a8a6109d8565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b610955610fbd565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109bb90611f11565b60405180910390fd5b6109cd8161135e565b50565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3e90611fa3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610ab6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aad90612035565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610b94919061197a565b60405180910390a3505050565b6000610bad84846108c6565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c275781811015610c19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c10906120a1565b60405180910390fd5b610c2684848484036109d8565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9390612133565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d02906121c5565b60405180910390fd5b610d168383836114d5565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610d9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9390612257565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e8a919061197a565b60405180910390a3610e9d8484846114da565b50505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015610f1f57507f000000000000000000000000000000000000000000000000000000000000000046145b15610f4c577f00000000000000000000000000000000000000000000000000000000000000009050610fba565b610fb77f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006114df565b90505b90565b610fc56109d0565b73ffffffffffffffffffffffffffffffffffffffff16610fe361062e565b73ffffffffffffffffffffffffffffffffffffffff1614611039576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611030906122c3565b60405180910390fd5b565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036110aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a19061232f565b60405180910390fd5b6110b6600083836114d5565b80600260008282546110c89190611ca0565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611179919061197a565b60405180910390a361118d600083836114da565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f7906123c1565b60405180910390fd5b61120c826000836114d5565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128990612453565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611345919061197a565b60405180910390a3611359836000846114da565b505050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081600001549050919050565b600080600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061147f81611424565b915061148a81611519565b50919050565b60006114a361149d610ea3565b8361152f565b9050919050565b60008060006114bb87878787611562565b915091506114c881611644565b8192505050949350505050565b505050565b505050565b600083838346306040516020016114fa959493929190612473565b6040516020818303038152906040528051906020012090509392505050565b6001816000016000828254019250508190555050565b6000828260405160200161154492919061253e565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561159d57600060039150915061163b565b6000600187878787604051600081526020016040526040516115c29493929190612575565b6020604051602081039080840390855afa1580156115e4573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036116325760006001925092505061163b565b80600092509250505b94509492505050565b60006004811115611658576116576125ba565b5b81600481111561166b5761166a6125ba565b5b03156117a75760016004811115611685576116846125ba565b5b816004811115611698576116976125ba565b5b036116d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116cf90612635565b60405180910390fd5b600260048111156116ec576116eb6125ba565b5b8160048111156116ff576116fe6125ba565b5b0361173f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611736906126a1565b60405180910390fd5b60036004811115611753576117526125ba565b5b816004811115611766576117656125ba565b5b036117a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179d90612733565b60405180910390fd5b5b50565b600081519050919050565b600082825260208201905092915050565b60005b838110156117e45780820151818401526020810190506117c9565b60008484015250505050565b6000601f19601f8301169050919050565b600061180c826117aa565b61181681856117b5565b93506118268185602086016117c6565b61182f816117f0565b840191505092915050565b600060208201905081810360008301526118548184611801565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061188c82611861565b9050919050565b61189c81611881565b81146118a757600080fd5b50565b6000813590506118b981611893565b92915050565b6000819050919050565b6118d2816118bf565b81146118dd57600080fd5b50565b6000813590506118ef816118c9565b92915050565b6000806040838503121561190c5761190b61185c565b5b600061191a858286016118aa565b925050602061192b858286016118e0565b9150509250929050565b60008115159050919050565b61194a81611935565b82525050565b60006020820190506119656000830184611941565b92915050565b611974816118bf565b82525050565b600060208201905061198f600083018461196b565b92915050565b6000806000606084860312156119ae576119ad61185c565b5b60006119bc868287016118aa565b93505060206119cd868287016118aa565b92505060406119de868287016118e0565b9150509250925092565b600060ff82169050919050565b6119fe816119e8565b82525050565b6000602082019050611a1960008301846119f5565b92915050565b6000819050919050565b611a3281611a1f565b82525050565b6000602082019050611a4d6000830184611a29565b92915050565b600060208284031215611a6957611a6861185c565b5b6000611a77848285016118e0565b91505092915050565b600060208284031215611a9657611a9561185c565b5b6000611aa4848285016118aa565b91505092915050565b611ab681611881565b82525050565b6000602082019050611ad16000830184611aad565b92915050565b611ae0816119e8565b8114611aeb57600080fd5b50565b600081359050611afd81611ad7565b92915050565b611b0c81611a1f565b8114611b1757600080fd5b50565b600081359050611b2981611b03565b92915050565b600080600080600080600060e0888a031215611b4e57611b4d61185c565b5b6000611b5c8a828b016118aa565b9750506020611b6d8a828b016118aa565b9650506040611b7e8a828b016118e0565b9550506060611b8f8a828b016118e0565b9450506080611ba08a828b01611aee565b93505060a0611bb18a828b01611b1a565b92505060c0611bc28a828b01611b1a565b91505092959891949750929550565b60008060408385031215611be857611be761185c565b5b6000611bf6858286016118aa565b9250506020611c07858286016118aa565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611c5857607f821691505b602082108103611c6b57611c6a611c11565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611cab826118bf565b9150611cb6836118bf565b9250828201905080821115611cce57611ccd611c71565b5b92915050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000611d306025836117b5565b9150611d3b82611cd4565b604082019050919050565b60006020820190508181036000830152611d5f81611d23565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b6000611d9c601d836117b5565b9150611da782611d66565b602082019050919050565b60006020820190508181036000830152611dcb81611d8f565b9050919050565b600060c082019050611de76000830189611a29565b611df46020830188611aad565b611e016040830187611aad565b611e0e606083018661196b565b611e1b608083018561196b565b611e2860a083018461196b565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b6000611e69601e836117b5565b9150611e7482611e33565b602082019050919050565b60006020820190508181036000830152611e9881611e5c565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000611efb6026836117b5565b9150611f0682611e9f565b604082019050919050565b60006020820190508181036000830152611f2a81611eee565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000611f8d6024836117b5565b9150611f9882611f31565b604082019050919050565b60006020820190508181036000830152611fbc81611f80565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b600061201f6022836117b5565b915061202a82611fc3565b604082019050919050565b6000602082019050818103600083015261204e81612012565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b600061208b601d836117b5565b915061209682612055565b602082019050919050565b600060208201905081810360008301526120ba8161207e565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b600061211d6025836117b5565b9150612128826120c1565b604082019050919050565b6000602082019050818103600083015261214c81612110565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b60006121af6023836117b5565b91506121ba82612153565b604082019050919050565b600060208201905081810360008301526121de816121a2565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006122416026836117b5565b915061224c826121e5565b604082019050919050565b6000602082019050818103600083015261227081612234565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006122ad6020836117b5565b91506122b882612277565b602082019050919050565b600060208201905081810360008301526122dc816122a0565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000612319601f836117b5565b9150612324826122e3565b602082019050919050565b600060208201905081810360008301526123488161230c565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006123ab6021836117b5565b91506123b68261234f565b604082019050919050565b600060208201905081810360008301526123da8161239e565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b600061243d6022836117b5565b9150612448826123e1565b604082019050919050565b6000602082019050818103600083015261246c81612430565b9050919050565b600060a0820190506124886000830188611a29565b6124956020830187611a29565b6124a26040830186611a29565b6124af606083018561196b565b6124bc6080830184611aad565b9695505050505050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b60006125076002836124c6565b9150612512826124d1565b600282019050919050565b6000819050919050565b61253861253382611a1f565b61251d565b82525050565b6000612549826124fa565b91506125558285612527565b6020820191506125658284612527565b6020820191508190509392505050565b600060808201905061258a6000830187611a29565b61259760208301866119f5565b6125a46040830185611a29565b6125b16060830184611a29565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b600061261f6018836117b5565b915061262a826125e9565b602082019050919050565b6000602082019050818103600083015261264e81612612565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b600061268b601f836117b5565b915061269682612655565b602082019050919050565b600060208201905081810360008301526126ba8161267e565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b600061271d6022836117b5565b9150612728826126c1565b604082019050919050565b6000602082019050818103600083015261274c81612710565b905091905056fea2646970667358221220399ac2be191ee6873eadc34398af79eb1388a4941fc12cb669916d03d64c170d64736f6c63430008110033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061012c5760003560e01c8063715018a6116100ad578063a457c2d711610071578063a457c2d714610333578063a9059cbb14610363578063d505accf14610393578063dd62ed3e146103af578063f2fde38b146103df5761012c565b8063715018a6146102a157806379cc6790146102ab5780637ecebe00146102c75780638da5cb5b146102f757806395d89b41146103155761012c565b80633644e515116100f45780633644e515146101eb578063395093511461020957806340c10f191461023957806342966c681461025557806370a08231146102715761012c565b806306fdde0314610131578063095ea7b31461014f57806318160ddd1461017f57806323b872dd1461019d578063313ce567146101cd575b600080fd5b6101396103fb565b604051610146919061183a565b60405180910390f35b610169600480360381019061016491906118f5565b61048d565b6040516101769190611950565b60405180910390f35b6101876104b0565b604051610194919061197a565b60405180910390f35b6101b760048036038101906101b29190611995565b6104ba565b6040516101c49190611950565b60405180910390f35b6101d56104e9565b6040516101e29190611a04565b60405180910390f35b6101f36104f2565b6040516102009190611a38565b60405180910390f35b610223600480360381019061021e91906118f5565b610501565b6040516102309190611950565b60405180910390f35b610253600480360381019061024e91906118f5565b610538565b005b61026f600480360381019061026a9190611a53565b61054e565b005b61028b60048036038101906102869190611a80565b610562565b604051610298919061197a565b60405180910390f35b6102a96105aa565b005b6102c560048036038101906102c091906118f5565b6105be565b005b6102e160048036038101906102dc9190611a80565b6105de565b6040516102ee919061197a565b60405180910390f35b6102ff61062e565b60405161030c9190611abc565b60405180910390f35b61031d610658565b60405161032a919061183a565b60405180910390f35b61034d600480360381019061034891906118f5565b6106ea565b60405161035a9190611950565b60405180910390f35b61037d600480360381019061037891906118f5565b610761565b60405161038a9190611950565b60405180910390f35b6103ad60048036038101906103a89190611b2f565b610784565b005b6103c960048036038101906103c49190611bd1565b6108c6565b6040516103d6919061197a565b60405180910390f35b6103f960048036038101906103f49190611a80565b61094d565b005b60606003805461040a90611c40565b80601f016020809104026020016040519081016040528092919081815260200182805461043690611c40565b80156104835780601f1061045857610100808354040283529160200191610483565b820191906000526020600020905b81548152906001019060200180831161046657829003601f168201915b5050505050905090565b6000806104986109d0565b90506104a58185856109d8565b600191505092915050565b6000600254905090565b6000806104c56109d0565b90506104d2858285610ba1565b6104dd858585610c2d565b60019150509392505050565b60006012905090565b60006104fc610ea3565b905090565b60008061050c6109d0565b905061052d81858561051e85896108c6565b6105289190611ca0565b6109d8565b600191505092915050565b610540610fbd565b61054a828261103b565b5050565b61055f6105596109d0565b82611191565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6105b2610fbd565b6105bc600061135e565b565b6105d0826105ca6109d0565b83610ba1565b6105da8282611191565b5050565b6000610627600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611424565b9050919050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606004805461066790611c40565b80601f016020809104026020016040519081016040528092919081815260200182805461069390611c40565b80156106e05780601f106106b5576101008083540402835291602001916106e0565b820191906000526020600020905b8154815290600101906020018083116106c357829003601f168201915b5050505050905090565b6000806106f56109d0565b9050600061070382866108c6565b905083811015610748576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073f90611d46565b60405180910390fd5b61075582868684036109d8565b60019250505092915050565b60008061076c6109d0565b9050610779818585610c2d565b600191505092915050565b834211156107c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107be90611db2565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886107f68c611432565b8960405160200161080c96959493929190611dd2565b604051602081830303815290604052805190602001209050600061082f82611490565b9050600061083f828787876114aa565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a690611e7f565b60405180910390fd5b6108ba8a8a8a6109d8565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b610955610fbd565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109bb90611f11565b60405180910390fd5b6109cd8161135e565b50565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3e90611fa3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610ab6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aad90612035565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610b94919061197a565b60405180910390a3505050565b6000610bad84846108c6565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c275781811015610c19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c10906120a1565b60405180910390fd5b610c2684848484036109d8565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610c9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9390612133565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610d0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d02906121c5565b60405180910390fd5b610d168383836114d5565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610d9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9390612257565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e8a919061197a565b60405180910390a3610e9d8484846114da565b50505050565b60007f000000000000000000000000b8df4848c8f657734c2e67d32d3fefc64f28119b73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015610f1f57507f000000000000000000000000000000000000000000000000000000000000000146145b15610f4c577f94aadd90c3c525d33c3835d693dc95dac687001cfa71f38a04e31df6c4d86f129050610fba565b610fb77f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f291ca134ce19ab005d44c2bd3db984c2916315a0de3fa78fc1679fac90b4c7fb7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66114df565b90505b90565b610fc56109d0565b73ffffffffffffffffffffffffffffffffffffffff16610fe361062e565b73ffffffffffffffffffffffffffffffffffffffff1614611039576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611030906122c3565b60405180910390fd5b565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036110aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a19061232f565b60405180910390fd5b6110b6600083836114d5565b80600260008282546110c89190611ca0565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611179919061197a565b60405180910390a361118d600083836114da565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f7906123c1565b60405180910390fd5b61120c826000836114d5565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128990612453565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611345919061197a565b60405180910390a3611359836000846114da565b505050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081600001549050919050565b600080600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061147f81611424565b915061148a81611519565b50919050565b60006114a361149d610ea3565b8361152f565b9050919050565b60008060006114bb87878787611562565b915091506114c881611644565b8192505050949350505050565b505050565b505050565b600083838346306040516020016114fa959493929190612473565b6040516020818303038152906040528051906020012090509392505050565b6001816000016000828254019250508190555050565b6000828260405160200161154492919061253e565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561159d57600060039150915061163b565b6000600187878787604051600081526020016040526040516115c29493929190612575565b6020604051602081039080840390855afa1580156115e4573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036116325760006001925092505061163b565b80600092509250505b94509492505050565b60006004811115611658576116576125ba565b5b81600481111561166b5761166a6125ba565b5b03156117a75760016004811115611685576116846125ba565b5b816004811115611698576116976125ba565b5b036116d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116cf90612635565b60405180910390fd5b600260048111156116ec576116eb6125ba565b5b8160048111156116ff576116fe6125ba565b5b0361173f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611736906126a1565b60405180910390fd5b60036004811115611753576117526125ba565b5b816004811115611766576117656125ba565b5b036117a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179d90612733565b60405180910390fd5b5b50565b600081519050919050565b600082825260208201905092915050565b60005b838110156117e45780820151818401526020810190506117c9565b60008484015250505050565b6000601f19601f8301169050919050565b600061180c826117aa565b61181681856117b5565b93506118268185602086016117c6565b61182f816117f0565b840191505092915050565b600060208201905081810360008301526118548184611801565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061188c82611861565b9050919050565b61189c81611881565b81146118a757600080fd5b50565b6000813590506118b981611893565b92915050565b6000819050919050565b6118d2816118bf565b81146118dd57600080fd5b50565b6000813590506118ef816118c9565b92915050565b6000806040838503121561190c5761190b61185c565b5b600061191a858286016118aa565b925050602061192b858286016118e0565b9150509250929050565b60008115159050919050565b61194a81611935565b82525050565b60006020820190506119656000830184611941565b92915050565b611974816118bf565b82525050565b600060208201905061198f600083018461196b565b92915050565b6000806000606084860312156119ae576119ad61185c565b5b60006119bc868287016118aa565b93505060206119cd868287016118aa565b92505060406119de868287016118e0565b9150509250925092565b600060ff82169050919050565b6119fe816119e8565b82525050565b6000602082019050611a1960008301846119f5565b92915050565b6000819050919050565b611a3281611a1f565b82525050565b6000602082019050611a4d6000830184611a29565b92915050565b600060208284031215611a6957611a6861185c565b5b6000611a77848285016118e0565b91505092915050565b600060208284031215611a9657611a9561185c565b5b6000611aa4848285016118aa565b91505092915050565b611ab681611881565b82525050565b6000602082019050611ad16000830184611aad565b92915050565b611ae0816119e8565b8114611aeb57600080fd5b50565b600081359050611afd81611ad7565b92915050565b611b0c81611a1f565b8114611b1757600080fd5b50565b600081359050611b2981611b03565b92915050565b600080600080600080600060e0888a031215611b4e57611b4d61185c565b5b6000611b5c8a828b016118aa565b9750506020611b6d8a828b016118aa565b9650506040611b7e8a828b016118e0565b9550506060611b8f8a828b016118e0565b9450506080611ba08a828b01611aee565b93505060a0611bb18a828b01611b1a565b92505060c0611bc28a828b01611b1a565b91505092959891949750929550565b60008060408385031215611be857611be761185c565b5b6000611bf6858286016118aa565b9250506020611c07858286016118aa565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611c5857607f821691505b602082108103611c6b57611c6a611c11565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611cab826118bf565b9150611cb6836118bf565b9250828201905080821115611cce57611ccd611c71565b5b92915050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000611d306025836117b5565b9150611d3b82611cd4565b604082019050919050565b60006020820190508181036000830152611d5f81611d23565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b6000611d9c601d836117b5565b9150611da782611d66565b602082019050919050565b60006020820190508181036000830152611dcb81611d8f565b9050919050565b600060c082019050611de76000830189611a29565b611df46020830188611aad565b611e016040830187611aad565b611e0e606083018661196b565b611e1b608083018561196b565b611e2860a083018461196b565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b6000611e69601e836117b5565b9150611e7482611e33565b602082019050919050565b60006020820190508181036000830152611e9881611e5c565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000611efb6026836117b5565b9150611f0682611e9f565b604082019050919050565b60006020820190508181036000830152611f2a81611eee565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000611f8d6024836117b5565b9150611f9882611f31565b604082019050919050565b60006020820190508181036000830152611fbc81611f80565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b600061201f6022836117b5565b915061202a82611fc3565b604082019050919050565b6000602082019050818103600083015261204e81612012565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b600061208b601d836117b5565b915061209682612055565b602082019050919050565b600060208201905081810360008301526120ba8161207e565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b600061211d6025836117b5565b9150612128826120c1565b604082019050919050565b6000602082019050818103600083015261214c81612110565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b60006121af6023836117b5565b91506121ba82612153565b604082019050919050565b600060208201905081810360008301526121de816121a2565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006122416026836117b5565b915061224c826121e5565b604082019050919050565b6000602082019050818103600083015261227081612234565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006122ad6020836117b5565b91506122b882612277565b602082019050919050565b600060208201905081810360008301526122dc816122a0565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000612319601f836117b5565b9150612324826122e3565b602082019050919050565b600060208201905081810360008301526123488161230c565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006123ab6021836117b5565b91506123b68261234f565b604082019050919050565b600060208201905081810360008301526123da8161239e565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b600061243d6022836117b5565b9150612448826123e1565b604082019050919050565b6000602082019050818103600083015261246c81612430565b9050919050565b600060a0820190506124886000830188611a29565b6124956020830187611a29565b6124a26040830186611a29565b6124af606083018561196b565b6124bc6080830184611aad565b9695505050505050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b60006125076002836124c6565b9150612512826124d1565b600282019050919050565b6000819050919050565b61253861253382611a1f565b61251d565b82525050565b6000612549826124fa565b91506125558285612527565b6020820191506125658284612527565b6020820191508190509392505050565b600060808201905061258a6000830187611a29565b61259760208301866119f5565b6125a46040830185611a29565b6125b16060830184611a29565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b600061261f6018836117b5565b915061262a826125e9565b602082019050919050565b6000602082019050818103600083015261264e81612612565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b600061268b601f836117b5565b915061269682612655565b602082019050919050565b600060208201905081810360008301526126ba8161267e565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b600061271d6022836117b5565b9150612728826126c1565b604082019050919050565b6000602082019050818103600083015261274c81612710565b905091905056fea2646970667358221220399ac2be191ee6873eadc34398af79eb1388a4941fc12cb669916d03d64c170d64736f6c63430008110033

Deployed Bytecode Sourcemap

58830:234:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43119:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45470:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44239:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46251:295;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44081:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57126:115;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46955:238;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58966:95;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58176:91;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44410:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36544:103;;;:::i;:::-;;58586:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56868:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35896:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43338:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47696:436;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44743:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56157:645;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44999:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36802:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43119:100;43173:13;43206:5;43199:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43119:100;:::o;45470:201::-;45553:4;45570:13;45586:12;:10;:12::i;:::-;45570:28;;45609:32;45618:5;45625:7;45634:6;45609:8;:32::i;:::-;45659:4;45652:11;;;45470:201;;;;:::o;44239:108::-;44300:7;44327:12;;44320:19;;44239:108;:::o;46251:295::-;46382:4;46399:15;46417:12;:10;:12::i;:::-;46399:30;;46440:38;46456:4;46462:7;46471:6;46440:15;:38::i;:::-;46489:27;46499:4;46505:2;46509:6;46489:9;:27::i;:::-;46534:4;46527:11;;;46251:295;;;;;:::o;44081:93::-;44139:5;44164:2;44157:9;;44081:93;:::o;57126:115::-;57186:7;57213:20;:18;:20::i;:::-;57206:27;;57126:115;:::o;46955:238::-;47043:4;47060:13;47076:12;:10;:12::i;:::-;47060:28;;47099:64;47108:5;47115:7;47152:10;47124:25;47134:5;47141:7;47124:9;:25::i;:::-;:38;;;;:::i;:::-;47099:8;:64::i;:::-;47181:4;47174:11;;;46955:238;;;;:::o;58966:95::-;35782:13;:11;:13::i;:::-;59036:17:::1;59042:2;59046:6;59036:5;:17::i;:::-;58966:95:::0;;:::o;58176:91::-;58232:27;58238:12;:10;:12::i;:::-;58252:6;58232:5;:27::i;:::-;58176:91;:::o;44410:127::-;44484:7;44511:9;:18;44521:7;44511:18;;;;;;;;;;;;;;;;44504:25;;44410:127;;;:::o;36544:103::-;35782:13;:11;:13::i;:::-;36609:30:::1;36636:1;36609:18;:30::i;:::-;36544:103::o:0;58586:164::-;58663:46;58679:7;58688:12;:10;:12::i;:::-;58702:6;58663:15;:46::i;:::-;58720:22;58726:7;58735:6;58720:5;:22::i;:::-;58586:164;;:::o;56868:128::-;56937:7;56964:24;:7;:14;56972:5;56964:14;;;;;;;;;;;;;;;:22;:24::i;:::-;56957:31;;56868:128;;;:::o;35896:87::-;35942:7;35969:6;;;;;;;;;;;35962:13;;35896:87;:::o;43338:104::-;43394:13;43427:7;43420:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43338:104;:::o;47696:436::-;47789:4;47806:13;47822:12;:10;:12::i;:::-;47806:28;;47845:24;47872:25;47882:5;47889:7;47872:9;:25::i;:::-;47845:52;;47936:15;47916:16;:35;;47908:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;48029:60;48038:5;48045:7;48073:15;48054:16;:34;48029:8;:60::i;:::-;48120:4;48113:11;;;;47696:436;;;;:::o;44743:193::-;44822:4;44839:13;44855:12;:10;:12::i;:::-;44839:28;;44878;44888:5;44895:2;44899:6;44878:9;:28::i;:::-;44924:4;44917:11;;;44743:193;;;;:::o;56157:645::-;56401:8;56382:15;:27;;56374:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;56456:18;55332:95;56516:5;56523:7;56532:5;56539:16;56549:5;56539:9;:16::i;:::-;56557:8;56487:79;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;56477:90;;;;;;56456:111;;56580:12;56595:28;56612:10;56595:16;:28::i;:::-;56580:43;;56636:14;56653:28;56667:4;56673:1;56676;56679;56653:13;:28::i;:::-;56636:45;;56710:5;56700:15;;:6;:15;;;56692:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;56763:31;56772:5;56779:7;56788:5;56763:8;:31::i;:::-;56363:439;;;56157:645;;;;;;;:::o;44999:151::-;45088:7;45115:11;:18;45127:5;45115:18;;;;;;;;;;;;;;;:27;45134:7;45115:27;;;;;;;;;;;;;;;;45108:34;;44999:151;;;;:::o;36802:201::-;35782:13;:11;:13::i;:::-;36911:1:::1;36891:22;;:8;:22;;::::0;36883:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;36967:28;36986:8;36967:18;:28::i;:::-;36802:201:::0;:::o;34447:98::-;34500:7;34527:10;34520:17;;34447:98;:::o;51723:380::-;51876:1;51859:19;;:5;:19;;;51851:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;51957:1;51938:21;;:7;:21;;;51930:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;52041:6;52011:11;:18;52023:5;52011:18;;;;;;;;;;;;;;;:27;52030:7;52011:27;;;;;;;;;;;;;;;:36;;;;52079:7;52063:32;;52072:5;52063:32;;;52088:6;52063:32;;;;;;:::i;:::-;;;;;;;;51723:380;;;:::o;52394:453::-;52529:24;52556:25;52566:5;52573:7;52556:9;:25::i;:::-;52529:52;;52616:17;52596:16;:37;52592:248;;52678:6;52658:16;:26;;52650:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;52762:51;52771:5;52778:7;52806:6;52787:16;:25;52762:8;:51::i;:::-;52592:248;52518:329;52394:453;;;:::o;48602:840::-;48749:1;48733:18;;:4;:18;;;48725:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;48826:1;48812:16;;:2;:16;;;48804:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;48881:38;48902:4;48908:2;48912:6;48881:20;:38::i;:::-;48932:19;48954:9;:15;48964:4;48954:15;;;;;;;;;;;;;;;;48932:37;;49003:6;48988:11;:21;;48980:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;49120:6;49106:11;:20;49088:9;:15;49098:4;49088:15;;;;;;;;;;;;;;;:38;;;;49323:6;49306:9;:13;49316:2;49306:13;;;;;;;;;;;;;;;;:23;;;;;;;;;;;49373:2;49358:26;;49367:4;49358:26;;;49377:6;49358:26;;;;;;:::i;:::-;;;;;;;;49397:37;49417:4;49423:2;49427:6;49397:19;:37::i;:::-;48714:728;48602:840;;;:::o;30002:314::-;30055:7;30096:12;30079:29;;30087:4;30079:29;;;:66;;;;;30129:16;30112:13;:33;30079:66;30075:234;;;30169:24;30162:31;;;;30075:234;30233:64;30255:10;30267:12;30281:15;30233:21;:64::i;:::-;30226:71;;30002:314;;:::o;36061:132::-;36136:12;:10;:12::i;:::-;36125:23;;:7;:5;:7::i;:::-;:23;;;36117:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;36061:132::o;49729:548::-;49832:1;49813:21;;:7;:21;;;49805:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;49883:49;49912:1;49916:7;49925:6;49883:20;:49::i;:::-;49961:6;49945:12;;:22;;;;;;;:::i;:::-;;;;;;;;50138:6;50116:9;:18;50126:7;50116:18;;;;;;;;;;;;;;;;:28;;;;;;;;;;;50192:7;50171:37;;50188:1;50171:37;;;50201:6;50171:37;;;;;;:::i;:::-;;;;;;;;50221:48;50249:1;50253:7;50262:6;50221:19;:48::i;:::-;49729:548;;:::o;50610:675::-;50713:1;50694:21;;:7;:21;;;50686:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;50766:49;50787:7;50804:1;50808:6;50766:20;:49::i;:::-;50828:22;50853:9;:18;50863:7;50853:18;;;;;;;;;;;;;;;;50828:43;;50908:6;50890:14;:24;;50882:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;51027:6;51010:14;:23;50989:9;:18;50999:7;50989:18;;;;;;;;;;;;;;;:44;;;;51144:6;51128:12;;:22;;;;;;;;;;;51205:1;51179:37;;51188:7;51179:37;;;51209:6;51179:37;;;;;;:::i;:::-;;;;;;;;51229:48;51249:7;51266:1;51270:6;51229:19;:48::i;:::-;50675:610;50610:675;;:::o;37163:191::-;37237:16;37256:6;;;;;;;;;;;37237:25;;37282:8;37273:6;;:17;;;;;;;;;;;;;;;;;;37337:8;37306:40;;37327:8;37306:40;;;;;;;;;;;;37226:128;37163:191;:::o;2216:114::-;2281:7;2308;:14;;;2301:21;;2216:114;;;:::o;57379:207::-;57439:15;57467:30;57500:7;:14;57508:5;57500:14;;;;;;;;;;;;;;;57467:47;;57535:15;:5;:13;:15::i;:::-;57525:25;;57561:17;:5;:15;:17::i;:::-;57456:130;57379:207;;;:::o;31229:167::-;31306:7;31333:55;31355:20;:18;:20::i;:::-;31377:10;31333:21;:55::i;:::-;31326:62;;31229:167;;;:::o;24875:279::-;25003:7;25024:17;25043:18;25065:25;25076:4;25082:1;25085;25088;25065:10;:25::i;:::-;25023:67;;;;25101:18;25113:5;25101:11;:18::i;:::-;25137:9;25130:16;;;;24875:279;;;;;;:::o;53447:125::-;;;;:::o;54176:124::-;;;;:::o;30324:263::-;30468:7;30516:8;30526;30536:11;30549:13;30572:4;30505:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;30495:84;;;;;;30488:91;;30324:263;;;;;:::o;2338:127::-;2445:1;2427:7;:14;;;:19;;;;;;;;;;;2338:127;:::o;26566:196::-;26659:7;26725:15;26742:10;26696:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;26686:68;;;;;;26679:75;;26566:196;;;;:::o;23216:1520::-;23347:7;23356:12;24281:66;24276:1;24268:10;;:79;24264:163;;;24380:1;24384:30;24364:51;;;;;;24264:163;24524:14;24541:24;24551:4;24557:1;24560;24563;24541:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24524:41;;24598:1;24580:20;;:6;:20;;;24576:103;;24633:1;24637:29;24617:50;;;;;;;24576:103;24699:6;24707:20;24691:37;;;;;23216:1520;;;;;;;;:::o;18608:521::-;18686:20;18677:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;18673:449;18723:7;18673:449;18784:29;18775:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;18771:351;;18830:34;;;;;;;;;;:::i;:::-;;;;;;;;18771:351;18895:35;18886:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;18882:240;;18947:41;;;;;;;;;;:::i;:::-;;;;;;;;18882:240;19019:30;19010:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;19006:116;;19066:44;;;;;;;;;;:::i;:::-;;;;;;;;19006:116;18608:521;;:::o;7:99:1:-;59:6;93:5;87:12;77:22;;7:99;;;:::o;112:169::-;196:11;230:6;225:3;218:19;270:4;265:3;261:14;246:29;;112:169;;;;:::o;287:246::-;368:1;378:113;392:6;389:1;386:13;378:113;;;477:1;472:3;468:11;462:18;458:1;453:3;449:11;442:39;414:2;411:1;407:10;402:15;;378:113;;;525:1;516:6;511:3;507:16;500:27;349:184;287:246;;;:::o;539:102::-;580:6;631:2;627:7;622:2;615:5;611:14;607:28;597:38;;539:102;;;:::o;647:377::-;735:3;763:39;796:5;763:39;:::i;:::-;818:71;882:6;877:3;818:71;:::i;:::-;811:78;;898:65;956:6;951:3;944:4;937:5;933:16;898:65;:::i;:::-;988:29;1010:6;988:29;:::i;:::-;983:3;979:39;972:46;;739:285;647:377;;;;:::o;1030:313::-;1143:4;1181:2;1170:9;1166:18;1158:26;;1230:9;1224:4;1220:20;1216:1;1205:9;1201:17;1194:47;1258:78;1331:4;1322:6;1258:78;:::i;:::-;1250:86;;1030:313;;;;:::o;1430:117::-;1539:1;1536;1529:12;1676:126;1713:7;1753:42;1746:5;1742:54;1731:65;;1676:126;;;:::o;1808:96::-;1845:7;1874:24;1892:5;1874:24;:::i;:::-;1863:35;;1808:96;;;:::o;1910:122::-;1983:24;2001:5;1983:24;:::i;:::-;1976:5;1973:35;1963:63;;2022:1;2019;2012:12;1963:63;1910:122;:::o;2038:139::-;2084:5;2122:6;2109:20;2100:29;;2138:33;2165:5;2138:33;:::i;:::-;2038:139;;;;:::o;2183:77::-;2220:7;2249:5;2238:16;;2183:77;;;:::o;2266:122::-;2339:24;2357:5;2339:24;:::i;:::-;2332:5;2329:35;2319:63;;2378:1;2375;2368:12;2319:63;2266:122;:::o;2394:139::-;2440:5;2478:6;2465:20;2456:29;;2494:33;2521:5;2494:33;:::i;:::-;2394:139;;;;:::o;2539:474::-;2607:6;2615;2664:2;2652:9;2643:7;2639:23;2635:32;2632:119;;;2670:79;;:::i;:::-;2632:119;2790:1;2815:53;2860:7;2851:6;2840:9;2836:22;2815:53;:::i;:::-;2805:63;;2761:117;2917:2;2943:53;2988:7;2979:6;2968:9;2964:22;2943:53;:::i;:::-;2933:63;;2888:118;2539:474;;;;;:::o;3019:90::-;3053:7;3096:5;3089:13;3082:21;3071:32;;3019:90;;;:::o;3115:109::-;3196:21;3211:5;3196:21;:::i;:::-;3191:3;3184:34;3115:109;;:::o;3230:210::-;3317:4;3355:2;3344:9;3340:18;3332:26;;3368:65;3430:1;3419:9;3415:17;3406:6;3368:65;:::i;:::-;3230:210;;;;:::o;3446:118::-;3533:24;3551:5;3533:24;:::i;:::-;3528:3;3521:37;3446:118;;:::o;3570:222::-;3663:4;3701:2;3690:9;3686:18;3678:26;;3714:71;3782:1;3771:9;3767:17;3758:6;3714:71;:::i;:::-;3570:222;;;;:::o;3798:619::-;3875:6;3883;3891;3940:2;3928:9;3919:7;3915:23;3911:32;3908:119;;;3946:79;;:::i;:::-;3908:119;4066:1;4091:53;4136:7;4127:6;4116:9;4112:22;4091:53;:::i;:::-;4081:63;;4037:117;4193:2;4219:53;4264:7;4255:6;4244:9;4240:22;4219:53;:::i;:::-;4209:63;;4164:118;4321:2;4347:53;4392:7;4383:6;4372:9;4368:22;4347:53;:::i;:::-;4337:63;;4292:118;3798:619;;;;;:::o;4423:86::-;4458:7;4498:4;4491:5;4487:16;4476:27;;4423:86;;;:::o;4515:112::-;4598:22;4614:5;4598:22;:::i;:::-;4593:3;4586:35;4515:112;;:::o;4633:214::-;4722:4;4760:2;4749:9;4745:18;4737:26;;4773:67;4837:1;4826:9;4822:17;4813:6;4773:67;:::i;:::-;4633:214;;;;:::o;4853:77::-;4890:7;4919:5;4908:16;;4853:77;;;:::o;4936:118::-;5023:24;5041:5;5023:24;:::i;:::-;5018:3;5011:37;4936:118;;:::o;5060:222::-;5153:4;5191:2;5180:9;5176:18;5168:26;;5204:71;5272:1;5261:9;5257:17;5248:6;5204:71;:::i;:::-;5060:222;;;;:::o;5288:329::-;5347:6;5396:2;5384:9;5375:7;5371:23;5367:32;5364:119;;;5402:79;;:::i;:::-;5364:119;5522:1;5547:53;5592:7;5583:6;5572:9;5568:22;5547:53;:::i;:::-;5537:63;;5493:117;5288:329;;;;:::o;5623:::-;5682:6;5731:2;5719:9;5710:7;5706:23;5702:32;5699:119;;;5737:79;;:::i;:::-;5699:119;5857:1;5882:53;5927:7;5918:6;5907:9;5903:22;5882:53;:::i;:::-;5872:63;;5828:117;5623:329;;;;:::o;5958:118::-;6045:24;6063:5;6045:24;:::i;:::-;6040:3;6033:37;5958:118;;:::o;6082:222::-;6175:4;6213:2;6202:9;6198:18;6190:26;;6226:71;6294:1;6283:9;6279:17;6270:6;6226:71;:::i;:::-;6082:222;;;;:::o;6310:118::-;6381:22;6397:5;6381:22;:::i;:::-;6374:5;6371:33;6361:61;;6418:1;6415;6408:12;6361:61;6310:118;:::o;6434:135::-;6478:5;6516:6;6503:20;6494:29;;6532:31;6557:5;6532:31;:::i;:::-;6434:135;;;;:::o;6575:122::-;6648:24;6666:5;6648:24;:::i;:::-;6641:5;6638:35;6628:63;;6687:1;6684;6677:12;6628:63;6575:122;:::o;6703:139::-;6749:5;6787:6;6774:20;6765:29;;6803:33;6830:5;6803:33;:::i;:::-;6703:139;;;;:::o;6848:1199::-;6959:6;6967;6975;6983;6991;6999;7007;7056:3;7044:9;7035:7;7031:23;7027:33;7024:120;;;7063:79;;:::i;:::-;7024:120;7183:1;7208:53;7253:7;7244:6;7233:9;7229:22;7208:53;:::i;:::-;7198:63;;7154:117;7310:2;7336:53;7381:7;7372:6;7361:9;7357:22;7336:53;:::i;:::-;7326:63;;7281:118;7438:2;7464:53;7509:7;7500:6;7489:9;7485:22;7464:53;:::i;:::-;7454:63;;7409:118;7566:2;7592:53;7637:7;7628:6;7617:9;7613:22;7592:53;:::i;:::-;7582:63;;7537:118;7694:3;7721:51;7764:7;7755:6;7744:9;7740:22;7721:51;:::i;:::-;7711:61;;7665:117;7821:3;7848:53;7893:7;7884:6;7873:9;7869:22;7848:53;:::i;:::-;7838:63;;7792:119;7950:3;7977:53;8022:7;8013:6;8002:9;7998:22;7977:53;:::i;:::-;7967:63;;7921:119;6848:1199;;;;;;;;;;:::o;8053:474::-;8121:6;8129;8178:2;8166:9;8157:7;8153:23;8149:32;8146:119;;;8184:79;;:::i;:::-;8146:119;8304:1;8329:53;8374:7;8365:6;8354:9;8350:22;8329:53;:::i;:::-;8319:63;;8275:117;8431:2;8457:53;8502:7;8493:6;8482:9;8478:22;8457:53;:::i;:::-;8447:63;;8402:118;8053:474;;;;;:::o;8533:180::-;8581:77;8578:1;8571:88;8678:4;8675:1;8668:15;8702:4;8699:1;8692:15;8719:320;8763:6;8800:1;8794:4;8790:12;8780:22;;8847:1;8841:4;8837:12;8868:18;8858:81;;8924:4;8916:6;8912:17;8902:27;;8858:81;8986:2;8978:6;8975:14;8955:18;8952:38;8949:84;;9005:18;;:::i;:::-;8949:84;8770:269;8719:320;;;:::o;9045:180::-;9093:77;9090:1;9083:88;9190:4;9187:1;9180:15;9214:4;9211:1;9204:15;9231:191;9271:3;9290:20;9308:1;9290:20;:::i;:::-;9285:25;;9324:20;9342:1;9324:20;:::i;:::-;9319:25;;9367:1;9364;9360:9;9353:16;;9388:3;9385:1;9382:10;9379:36;;;9395:18;;:::i;:::-;9379:36;9231:191;;;;:::o;9428:224::-;9568:34;9564:1;9556:6;9552:14;9545:58;9637:7;9632:2;9624:6;9620:15;9613:32;9428:224;:::o;9658:366::-;9800:3;9821:67;9885:2;9880:3;9821:67;:::i;:::-;9814:74;;9897:93;9986:3;9897:93;:::i;:::-;10015:2;10010:3;10006:12;9999:19;;9658:366;;;:::o;10030:419::-;10196:4;10234:2;10223:9;10219:18;10211:26;;10283:9;10277:4;10273:20;10269:1;10258:9;10254:17;10247:47;10311:131;10437:4;10311:131;:::i;:::-;10303:139;;10030:419;;;:::o;10455:179::-;10595:31;10591:1;10583:6;10579:14;10572:55;10455:179;:::o;10640:366::-;10782:3;10803:67;10867:2;10862:3;10803:67;:::i;:::-;10796:74;;10879:93;10968:3;10879:93;:::i;:::-;10997:2;10992:3;10988:12;10981:19;;10640:366;;;:::o;11012:419::-;11178:4;11216:2;11205:9;11201:18;11193:26;;11265:9;11259:4;11255:20;11251:1;11240:9;11236:17;11229:47;11293:131;11419:4;11293:131;:::i;:::-;11285:139;;11012:419;;;:::o;11437:775::-;11670:4;11708:3;11697:9;11693:19;11685:27;;11722:71;11790:1;11779:9;11775:17;11766:6;11722:71;:::i;:::-;11803:72;11871:2;11860:9;11856:18;11847:6;11803:72;:::i;:::-;11885;11953:2;11942:9;11938:18;11929:6;11885:72;:::i;:::-;11967;12035:2;12024:9;12020:18;12011:6;11967:72;:::i;:::-;12049:73;12117:3;12106:9;12102:19;12093:6;12049:73;:::i;:::-;12132;12200:3;12189:9;12185:19;12176:6;12132:73;:::i;:::-;11437:775;;;;;;;;;:::o;12218:180::-;12358:32;12354:1;12346:6;12342:14;12335:56;12218:180;:::o;12404:366::-;12546:3;12567:67;12631:2;12626:3;12567:67;:::i;:::-;12560:74;;12643:93;12732:3;12643:93;:::i;:::-;12761:2;12756:3;12752:12;12745:19;;12404:366;;;:::o;12776:419::-;12942:4;12980:2;12969:9;12965:18;12957:26;;13029:9;13023:4;13019:20;13015:1;13004:9;13000:17;12993:47;13057:131;13183:4;13057:131;:::i;:::-;13049:139;;12776:419;;;:::o;13201:225::-;13341:34;13337:1;13329:6;13325:14;13318:58;13410:8;13405:2;13397:6;13393:15;13386:33;13201:225;:::o;13432:366::-;13574:3;13595:67;13659:2;13654:3;13595:67;:::i;:::-;13588:74;;13671:93;13760:3;13671:93;:::i;:::-;13789:2;13784:3;13780:12;13773:19;;13432:366;;;:::o;13804:419::-;13970:4;14008:2;13997:9;13993:18;13985:26;;14057:9;14051:4;14047:20;14043:1;14032:9;14028:17;14021:47;14085:131;14211:4;14085:131;:::i;:::-;14077:139;;13804:419;;;:::o;14229:223::-;14369:34;14365:1;14357:6;14353:14;14346:58;14438:6;14433:2;14425:6;14421:15;14414:31;14229:223;:::o;14458:366::-;14600:3;14621:67;14685:2;14680:3;14621:67;:::i;:::-;14614:74;;14697:93;14786:3;14697:93;:::i;:::-;14815:2;14810:3;14806:12;14799:19;;14458:366;;;:::o;14830:419::-;14996:4;15034:2;15023:9;15019:18;15011:26;;15083:9;15077:4;15073:20;15069:1;15058:9;15054:17;15047:47;15111:131;15237:4;15111:131;:::i;:::-;15103:139;;14830:419;;;:::o;15255:221::-;15395:34;15391:1;15383:6;15379:14;15372:58;15464:4;15459:2;15451:6;15447:15;15440:29;15255:221;:::o;15482:366::-;15624:3;15645:67;15709:2;15704:3;15645:67;:::i;:::-;15638:74;;15721:93;15810:3;15721:93;:::i;:::-;15839:2;15834:3;15830:12;15823:19;;15482:366;;;:::o;15854:419::-;16020:4;16058:2;16047:9;16043:18;16035:26;;16107:9;16101:4;16097:20;16093:1;16082:9;16078:17;16071:47;16135:131;16261:4;16135:131;:::i;:::-;16127:139;;15854:419;;;:::o;16279:179::-;16419:31;16415:1;16407:6;16403:14;16396:55;16279:179;:::o;16464:366::-;16606:3;16627:67;16691:2;16686:3;16627:67;:::i;:::-;16620:74;;16703:93;16792:3;16703:93;:::i;:::-;16821:2;16816:3;16812:12;16805:19;;16464:366;;;:::o;16836:419::-;17002:4;17040:2;17029:9;17025:18;17017:26;;17089:9;17083:4;17079:20;17075:1;17064:9;17060:17;17053:47;17117:131;17243:4;17117:131;:::i;:::-;17109:139;;16836:419;;;:::o;17261:224::-;17401:34;17397:1;17389:6;17385:14;17378:58;17470:7;17465:2;17457:6;17453:15;17446:32;17261:224;:::o;17491:366::-;17633:3;17654:67;17718:2;17713:3;17654:67;:::i;:::-;17647:74;;17730:93;17819:3;17730:93;:::i;:::-;17848:2;17843:3;17839:12;17832:19;;17491:366;;;:::o;17863:419::-;18029:4;18067:2;18056:9;18052:18;18044:26;;18116:9;18110:4;18106:20;18102:1;18091:9;18087:17;18080:47;18144:131;18270:4;18144:131;:::i;:::-;18136:139;;17863:419;;;:::o;18288:222::-;18428:34;18424:1;18416:6;18412:14;18405:58;18497:5;18492:2;18484:6;18480:15;18473:30;18288:222;:::o;18516:366::-;18658:3;18679:67;18743:2;18738:3;18679:67;:::i;:::-;18672:74;;18755:93;18844:3;18755:93;:::i;:::-;18873:2;18868:3;18864:12;18857:19;;18516:366;;;:::o;18888:419::-;19054:4;19092:2;19081:9;19077:18;19069:26;;19141:9;19135:4;19131:20;19127:1;19116:9;19112:17;19105:47;19169:131;19295:4;19169:131;:::i;:::-;19161:139;;18888:419;;;:::o;19313:225::-;19453:34;19449:1;19441:6;19437:14;19430:58;19522:8;19517:2;19509:6;19505:15;19498:33;19313:225;:::o;19544:366::-;19686:3;19707:67;19771:2;19766:3;19707:67;:::i;:::-;19700:74;;19783:93;19872:3;19783:93;:::i;:::-;19901:2;19896:3;19892:12;19885:19;;19544:366;;;:::o;19916:419::-;20082:4;20120:2;20109:9;20105:18;20097:26;;20169:9;20163:4;20159:20;20155:1;20144:9;20140:17;20133:47;20197:131;20323:4;20197:131;:::i;:::-;20189:139;;19916:419;;;:::o;20341:182::-;20481:34;20477:1;20469:6;20465:14;20458:58;20341:182;:::o;20529:366::-;20671:3;20692:67;20756:2;20751:3;20692:67;:::i;:::-;20685:74;;20768:93;20857:3;20768:93;:::i;:::-;20886:2;20881:3;20877:12;20870:19;;20529:366;;;:::o;20901:419::-;21067:4;21105:2;21094:9;21090:18;21082:26;;21154:9;21148:4;21144:20;21140:1;21129:9;21125:17;21118:47;21182:131;21308:4;21182:131;:::i;:::-;21174:139;;20901:419;;;:::o;21326:181::-;21466:33;21462:1;21454:6;21450:14;21443:57;21326:181;:::o;21513:366::-;21655:3;21676:67;21740:2;21735:3;21676:67;:::i;:::-;21669:74;;21752:93;21841:3;21752:93;:::i;:::-;21870:2;21865:3;21861:12;21854:19;;21513:366;;;:::o;21885:419::-;22051:4;22089:2;22078:9;22074:18;22066:26;;22138:9;22132:4;22128:20;22124:1;22113:9;22109:17;22102:47;22166:131;22292:4;22166:131;:::i;:::-;22158:139;;21885:419;;;:::o;22310:220::-;22450:34;22446:1;22438:6;22434:14;22427:58;22519:3;22514:2;22506:6;22502:15;22495:28;22310:220;:::o;22536:366::-;22678:3;22699:67;22763:2;22758:3;22699:67;:::i;:::-;22692:74;;22775:93;22864:3;22775:93;:::i;:::-;22893:2;22888:3;22884:12;22877:19;;22536:366;;;:::o;22908:419::-;23074:4;23112:2;23101:9;23097:18;23089:26;;23161:9;23155:4;23151:20;23147:1;23136:9;23132:17;23125:47;23189:131;23315:4;23189:131;:::i;:::-;23181:139;;22908:419;;;:::o;23333:221::-;23473:34;23469:1;23461:6;23457:14;23450:58;23542:4;23537:2;23529:6;23525:15;23518:29;23333:221;:::o;23560:366::-;23702:3;23723:67;23787:2;23782:3;23723:67;:::i;:::-;23716:74;;23799:93;23888:3;23799:93;:::i;:::-;23917:2;23912:3;23908:12;23901:19;;23560:366;;;:::o;23932:419::-;24098:4;24136:2;24125:9;24121:18;24113:26;;24185:9;24179:4;24175:20;24171:1;24160:9;24156:17;24149:47;24213:131;24339:4;24213:131;:::i;:::-;24205:139;;23932:419;;;:::o;24357:664::-;24562:4;24600:3;24589:9;24585:19;24577:27;;24614:71;24682:1;24671:9;24667:17;24658:6;24614:71;:::i;:::-;24695:72;24763:2;24752:9;24748:18;24739:6;24695:72;:::i;:::-;24777;24845:2;24834:9;24830:18;24821:6;24777:72;:::i;:::-;24859;24927:2;24916:9;24912:18;24903:6;24859:72;:::i;:::-;24941:73;25009:3;24998:9;24994:19;24985:6;24941:73;:::i;:::-;24357:664;;;;;;;;:::o;25027:148::-;25129:11;25166:3;25151:18;;25027:148;;;;:::o;25181:214::-;25321:66;25317:1;25309:6;25305:14;25298:90;25181:214;:::o;25401:400::-;25561:3;25582:84;25664:1;25659:3;25582:84;:::i;:::-;25575:91;;25675:93;25764:3;25675:93;:::i;:::-;25793:1;25788:3;25784:11;25777:18;;25401:400;;;:::o;25807:79::-;25846:7;25875:5;25864:16;;25807:79;;;:::o;25892:157::-;25997:45;26017:24;26035:5;26017:24;:::i;:::-;25997:45;:::i;:::-;25992:3;25985:58;25892:157;;:::o;26055:663::-;26296:3;26318:148;26462:3;26318:148;:::i;:::-;26311:155;;26476:75;26547:3;26538:6;26476:75;:::i;:::-;26576:2;26571:3;26567:12;26560:19;;26589:75;26660:3;26651:6;26589:75;:::i;:::-;26689:2;26684:3;26680:12;26673:19;;26709:3;26702:10;;26055:663;;;;;:::o;26724:545::-;26897:4;26935:3;26924:9;26920:19;26912:27;;26949:71;27017:1;27006:9;27002:17;26993:6;26949:71;:::i;:::-;27030:68;27094:2;27083:9;27079:18;27070:6;27030:68;:::i;:::-;27108:72;27176:2;27165:9;27161:18;27152:6;27108:72;:::i;:::-;27190;27258:2;27247:9;27243:18;27234:6;27190:72;:::i;:::-;26724:545;;;;;;;:::o;27275:180::-;27323:77;27320:1;27313:88;27420:4;27417:1;27410:15;27444:4;27441:1;27434:15;27461:174;27601:26;27597:1;27589:6;27585:14;27578:50;27461:174;:::o;27641:366::-;27783:3;27804:67;27868:2;27863:3;27804:67;:::i;:::-;27797:74;;27880:93;27969:3;27880:93;:::i;:::-;27998:2;27993:3;27989:12;27982:19;;27641:366;;;:::o;28013:419::-;28179:4;28217:2;28206:9;28202:18;28194:26;;28266:9;28260:4;28256:20;28252:1;28241:9;28237:17;28230:47;28294:131;28420:4;28294:131;:::i;:::-;28286:139;;28013:419;;;:::o;28438:181::-;28578:33;28574:1;28566:6;28562:14;28555:57;28438:181;:::o;28625:366::-;28767:3;28788:67;28852:2;28847:3;28788:67;:::i;:::-;28781:74;;28864:93;28953:3;28864:93;:::i;:::-;28982:2;28977:3;28973:12;28966:19;;28625:366;;;:::o;28997:419::-;29163:4;29201:2;29190:9;29186:18;29178:26;;29250:9;29244:4;29240:20;29236:1;29225:9;29221:17;29214:47;29278:131;29404:4;29278:131;:::i;:::-;29270:139;;28997:419;;;:::o;29422:221::-;29562:34;29558:1;29550:6;29546:14;29539:58;29631:4;29626:2;29618:6;29614:15;29607:29;29422:221;:::o;29649:366::-;29791:3;29812:67;29876:2;29871:3;29812:67;:::i;:::-;29805:74;;29888:93;29977:3;29888:93;:::i;:::-;30006:2;30001:3;29997:12;29990:19;;29649:366;;;:::o;30021:419::-;30187:4;30225:2;30214:9;30210:18;30202:26;;30274:9;30268:4;30264:20;30260:1;30249:9;30245:17;30238:47;30302:131;30428:4;30302:131;:::i;:::-;30294:139;;30021:419;;;:::o

Swarm Source

ipfs://399ac2be191ee6873eadc34398af79eb1388a4941fc12cb669916d03d64c170d
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.