ETH Price: $3,131.09 (+0.97%)

Token

Gaga (Pepe) (GAGA)
 

Overview

Max Total Supply

420,690,000,000,000 GAGA

Holders

5,501

Market

Price

$0.00 @ 0.000000 ETH (+1.03%)

Onchain Market Cap

$938,138.70

Circulating Supply Market Cap

$937,383.00

Other Info

Token Contract (WITH 18 Decimals)

Balance
132,008.27 GAGA

Value
$0.00 ( ~0 Eth) [0.0000%]
0xd4bC53434C5e12cb41381A556c3c47e1a86e80E3
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

GAGA the Frog - the independent wife of PEPE, is the main character of the #GAGAVERSE. She’s gathering her friends RINO, WOLT, BARY, GROM to prove to PEPE that she can become the #1 meme.

Market

Volume (24H):$89,123.00
Market Capitalization:$937,383.00
Circulating Supply:420,690,000,000,000.00 GAGA
Market Data Source: Coinmarketcap

# Exchange Pair Price  24H Volume % Volume
1
MEXC
GAGA-USDT$0.00
0.0000000 Eth
$46,456.00
21,163,647,693,270.000 GAGA
48.4953%
2
Biconomy.com
GAGA-USDT$0.00
0.0000000 Eth
$32,367.00
15,038,463,290,153.200 GAGA
34.4598%
3
Uniswap V2 (Ethereum)
0XB29DC1703FACD2967BB8ADE2E392385644C6DCA9-0XC02AAA39B223FE8D0A0E5C4F27EAD9083C756CC2$0.00
0.0000000 Eth
$10,360.29
4,812,501,688,065.660 0XB29DC1703FACD2967BB8ADE2E392385644C6DCA9
11.0276%
4
Uniswap V2 (Ethereum)
0X616254B3C79639F89E756495AC687735B27B5E17-0XB29DC1703FACD2967BB8ADE2E392385644C6DCA9$0.00
0.0000000 Eth
$839.64
2,626,010,969,459.800 0X616254B3C79639F89E756495AC687735B27B5E17
6.0174%

Contract Source Code Verified (Exact Match)

Contract Name:
GagaPepe

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license, Audited

Contract Source Code (Solidity)Audit Report

/**
 *Submitted for verification at Etherscan.io on 2024-03-12
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/[email protected]/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/[email protected]/interfaces/IERC5267.sol


// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)

pragma solidity ^0.8.0;

interface IERC5267 {
    /**
     * @dev MAY be emitted to signal that the domain could have changed.
     */
    event EIP712DomainChanged();

    /**
     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
     * signature.
     */
    function eip712Domain()
        external
        view
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        );
}

// File: @openzeppelin/[email protected]/utils/StorageSlot.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
 * _Available since v4.9 for `string`, `bytes`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */
    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */
    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }
}

// File: @openzeppelin/[email protected]/utils/ShortStrings.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol)

pragma solidity ^0.8.8;


// | string  | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA   |
// | length  | 0x                                                              BB |
type ShortString is bytes32;

/**
 * @dev This library provides functions to convert short memory strings
 * into a `ShortString` type that can be used as an immutable variable.
 *
 * Strings of arbitrary length can be optimized using this library if
 * they are short enough (up to 31 bytes) by packing them with their
 * length (1 byte) in a single EVM word (32 bytes). Additionally, a
 * fallback mechanism can be used for every other case.
 *
 * Usage example:
 *
 * ```solidity
 * contract Named {
 *     using ShortStrings for *;
 *
 *     ShortString private immutable _name;
 *     string private _nameFallback;
 *
 *     constructor(string memory contractName) {
 *         _name = contractName.toShortStringWithFallback(_nameFallback);
 *     }
 *
 *     function name() external view returns (string memory) {
 *         return _name.toStringWithFallback(_nameFallback);
 *     }
 * }
 * ```
 */
library ShortStrings {
    // Used as an identifier for strings longer than 31 bytes.
    bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;

    error StringTooLong(string str);
    error InvalidShortString();

    /**
     * @dev Encode a string of at most 31 chars into a `ShortString`.
     *
     * This will trigger a `StringTooLong` error is the input string is too long.
     */
    function toShortString(string memory str) internal pure returns (ShortString) {
        bytes memory bstr = bytes(str);
        if (bstr.length > 31) {
            revert StringTooLong(str);
        }
        return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));
    }

    /**
     * @dev Decode a `ShortString` back to a "normal" string.
     */
    function toString(ShortString sstr) internal pure returns (string memory) {
        uint256 len = byteLength(sstr);
        // using `new string(len)` would work locally but is not memory safe.
        string memory str = new string(32);
        /// @solidity memory-safe-assembly
        assembly {
            mstore(str, len)
            mstore(add(str, 0x20), sstr)
        }
        return str;
    }

    /**
     * @dev Return the length of a `ShortString`.
     */
    function byteLength(ShortString sstr) internal pure returns (uint256) {
        uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
        if (result > 31) {
            revert InvalidShortString();
        }
        return result;
    }

    /**
     * @dev Encode a string into a `ShortString`, or write it to storage if it is too long.
     */
    function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {
        if (bytes(value).length < 32) {
            return toShortString(value);
        } else {
            StorageSlot.getStringSlot(store).value = value;
            return ShortString.wrap(_FALLBACK_SENTINEL);
        }
    }

    /**
     * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     */
    function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return toString(value);
        } else {
            return store;
        }
    }

    /**
     * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     *
     * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of
     * actual characters as the UTF-8 encoding of a single character can span over multiple bytes.
     */
    function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {
            return byteLength(value);
        } else {
            return bytes(store).length;
        }
    }
}

// File: @openzeppelin/[email protected]/utils/math/SignedMath.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

// File: @openzeppelin/[email protected]/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

// File: @openzeppelin/[email protected]/utils/Strings.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;



/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

// File: @openzeppelin/[email protected]/utils/cryptography/ECDSA.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\n32")
            mstore(0x1c, hash)
            message := keccak256(0x00, 0x3c)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, "\x19\x01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            data := keccak256(ptr, 0x42)
        }
    }

    /**
     * @dev Returns an Ethereum Signed Data with intended validator, created from a
     * `validator` and `data` according to the version 0 of EIP-191.
     *
     * See {recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x00", validator, data));
    }
}

// File: @openzeppelin/[email protected]/utils/cryptography/EIP712.sol


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

pragma solidity ^0.8.8;




/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
 * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the
 * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
 *
 * _Available since v3.4._
 *
 * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
 */
abstract contract EIP712 is IERC5267 {
    using ShortStrings for *;

    bytes32 private constant _TYPE_HASH =
        keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _cachedDomainSeparator;
    uint256 private immutable _cachedChainId;
    address private immutable _cachedThis;

    bytes32 private immutable _hashedName;
    bytes32 private immutable _hashedVersion;

    ShortString private immutable _name;
    ShortString private immutable _version;
    string private _nameFallback;
    string private _versionFallback;

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        _name = name.toShortStringWithFallback(_nameFallback);
        _version = version.toShortStringWithFallback(_versionFallback);
        _hashedName = keccak256(bytes(name));
        _hashedVersion = keccak256(bytes(version));

        _cachedChainId = block.chainid;
        _cachedDomainSeparator = _buildDomainSeparator();
        _cachedThis = address(this);
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _cachedThis && block.chainid == _cachedChainId) {
            return _cachedDomainSeparator;
        } else {
            return _buildDomainSeparator();
        }
    }

    function _buildDomainSeparator() private view returns (bytes32) {
        return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }

    /**
     * @dev See {EIP-5267}.
     *
     * _Available since v4.9._
     */
    function eip712Domain()
        public
        view
        virtual
        override
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        return (
            hex"0f", // 01111
            _name.toStringWithFallback(_nameFallback),
            _version.toStringWithFallback(_versionFallback),
            block.chainid,
            address(this),
            bytes32(0),
            new uint256[](0)
        );
    }
}

// File: @openzeppelin/[email protected]/token/ERC20/extensions/IERC20Permit.sol


// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

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

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

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

// File: @openzeppelin/[email protected]/utils/Context.sol


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

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/[email protected]/token/ERC20/IERC20.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// File: @openzeppelin/[email protected]/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/[email protected]/token/ERC20/ERC20.sol


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

pragma solidity ^0.8.0;




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

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

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

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

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

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

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

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

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

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

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

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

        return true;
    }

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

        _beforeTokenTransfer(from, to, amount);

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

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/[email protected]/token/ERC20/extensions/ERC20Permit.sol


// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/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: contracts/HelloWorld.sol


// Compatible with OpenZeppelin Contracts ^4.9.2
pragma solidity ^0.8.9;



contract GagaPepe is ERC20, ERC20Permit {
    constructor() ERC20("Gaga (Pepe)", "GAGA") ERC20Permit("Gaga (Pepe)") {
        _mint(msg.sender, 420690000000000 * 10 ** decimals());
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"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":[],"name":"EIP712DomainChanged","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":[],"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":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"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":"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"}]

6101606040523480156200001257600080fd5b506040518060400160405280600b81526020017f4761676120285065706529000000000000000000000000000000000000000000815250806040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506040518060400160405280600b81526020017f47616761202850657065290000000000000000000000000000000000000000008152506040518060400160405280600481526020017f4741474100000000000000000000000000000000000000000000000000000000815250816003908051906020019062000104929190620004dd565b5080600490805190602001906200011d929190620004dd565b5050506200013b6005836200022460201b6200091c1790919060201c565b61012081815250506200015e6006826200022460201b6200091c1790919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a081815250506200019d6200028860201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250505050506200021e33620001f0620002e560201b60201c565b600a620001fe919062000727565b66017e9d8602b40062000212919062000778565b620002ee60201b60201c565b62000b6f565b60006020835110156200024a5762000242836200045c60201b60201c565b905062000282565b826200026183620004c960201b620009671760201c565b600001908051906020019062000279929190620004dd565b5060ff60001b90505b92915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e051610100514630604051602001620002ca9594939291906200084a565b60405160208183030381529060405280519060200120905090565b60006012905090565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000361576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003589062000908565b60405180910390fd5b6200037560008383620004d360201b60201c565b80600260008282546200038991906200092a565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200043c919062000987565b60405180910390a36200045860008383620004d860201b60201c565b5050565b600080829050601f81511115620004ac57826040517f305a27a9000000000000000000000000000000000000000000000000000000008152600401620004a3919062000a37565b60405180910390fd5b805181620004ba9062000a9a565b60001c1760001b915050919050565b6000819050919050565b505050565b505050565b828054620004eb9062000b39565b90600052602060002090601f0160209004810192826200050f57600085556200055b565b82601f106200052a57805160ff19168380011785556200055b565b828001600101855582156200055b579182015b828111156200055a5782518255916020019190600101906200053d565b5b5090506200056a91906200056e565b5090565b5b80821115620005895760008160009055506001016200056f565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160011c9050919050565b6000808291508390505b60018511156200061b57808604811115620005f357620005f26200058d565b5b6001851615620006035780820291505b80810290506200061385620005bc565b9450620005d3565b94509492505050565b60008262000636576001905062000709565b8162000646576000905062000709565b81600181146200065f57600281146200066a57620006a0565b600191505062000709565b60ff8411156200067f576200067e6200058d565b5b8360020a9150848211156200069957620006986200058d565b5b5062000709565b5060208310610133831016604e8410600b8410161715620006da5782820a905083811115620006d457620006d36200058d565b5b62000709565b620006e98484846001620005c9565b925090508184048111156200070357620007026200058d565b5b81810290505b9392505050565b6000819050919050565b600060ff82169050919050565b6000620007348262000710565b915062000741836200071a565b9250620007707fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000624565b905092915050565b6000620007858262000710565b9150620007928362000710565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615620007ce57620007cd6200058d565b5b828202905092915050565b6000819050919050565b620007ee81620007d9565b82525050565b620007ff8162000710565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620008328262000805565b9050919050565b620008448162000825565b82525050565b600060a082019050620008616000830188620007e3565b620008706020830187620007e3565b6200087f6040830186620007e3565b6200088e6060830185620007f4565b6200089d608083018462000839565b9695505050505050565b600082825260208201905092915050565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6000620008f0601f83620008a7565b9150620008fd82620008b8565b602082019050919050565b600060208201905081810360008301526200092381620008e1565b9050919050565b6000620009378262000710565b9150620009448362000710565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156200097c576200097b6200058d565b5b828201905092915050565b60006020820190506200099e6000830184620007f4565b92915050565b600081519050919050565b60005b83811015620009cf578082015181840152602081019050620009b2565b83811115620009df576000848401525b50505050565b6000601f19601f8301169050919050565b600062000a0382620009a4565b62000a0f8185620008a7565b935062000a21818560208601620009af565b62000a2c81620009e5565b840191505092915050565b6000602082019050818103600083015262000a538184620009f6565b905092915050565b600081519050919050565b6000819050602082019050919050565b600062000a848251620007d9565b80915050919050565b600082821b905092915050565b600062000aa78262000a5b565b8262000ab38462000a66565b905062000ac08162000a76565b9250602082101562000b035762000afe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080262000a8d565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000b5257607f821691505b6020821081141562000b695762000b6862000b0a565b5b50919050565b60805160a05160c05160e05161010051610120516101405161244d62000bca600039600061056c0152600061053801526000611118015260006110f701526000610e4c01526000610ea201526000610ecb015261244d6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806370a0823111610097578063a457c2d711610066578063a457c2d7146102a4578063a9059cbb146102d4578063d505accf14610304578063dd62ed3e14610320576100f5565b806370a08231146102025780637ecebe001461023257806384b0196e1461026257806395d89b4114610286576100f5565b806323b872dd116100d357806323b872dd14610166578063313ce567146101965780633644e515146101b457806339509351146101d2576100f5565b806306fdde03146100fa578063095ea7b31461011857806318160ddd14610148575b600080fd5b610102610350565b60405161010f9190611610565b60405180910390f35b610132600480360381019061012d91906116cb565b6103e2565b60405161013f9190611726565b60405180910390f35b610150610405565b60405161015d9190611750565b60405180910390f35b610180600480360381019061017b919061176b565b61040f565b60405161018d9190611726565b60405180910390f35b61019e61043e565b6040516101ab91906117da565b60405180910390f35b6101bc610447565b6040516101c9919061180e565b60405180910390f35b6101ec60048036038101906101e791906116cb565b610456565b6040516101f99190611726565b60405180910390f35b61021c60048036038101906102179190611829565b61048d565b6040516102299190611750565b60405180910390f35b61024c60048036038101906102479190611829565b6104d5565b6040516102599190611750565b60405180910390f35b61026a610525565b60405161027d979695949392919061195e565b60405180910390f35b61028e610627565b60405161029b9190611610565b60405180910390f35b6102be60048036038101906102b991906116cb565b6106b9565b6040516102cb9190611726565b60405180910390f35b6102ee60048036038101906102e991906116cb565b610730565b6040516102fb9190611726565b60405180910390f35b61031e60048036038101906103199190611a3a565b610753565b005b61033a60048036038101906103359190611adc565b610895565b6040516103479190611750565b60405180910390f35b60606003805461035f90611b4b565b80601f016020809104026020016040519081016040528092919081815260200182805461038b90611b4b565b80156103d85780601f106103ad576101008083540402835291602001916103d8565b820191906000526020600020905b8154815290600101906020018083116103bb57829003601f168201915b5050505050905090565b6000806103ed610971565b90506103fa818585610979565b600191505092915050565b6000600254905090565b60008061041a610971565b9050610427858285610b44565b610432858585610bd0565b60019150509392505050565b60006012905090565b6000610451610e48565b905090565b600080610461610971565b90506104828185856104738589610895565b61047d9190611bac565b610979565b600191505092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600061051e600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020610eff565b9050919050565b60006060806000806000606061056560057f0000000000000000000000000000000000000000000000000000000000000000610f0d90919063ffffffff16565b61059960067f0000000000000000000000000000000000000000000000000000000000000000610f0d90919063ffffffff16565b46306000801b600067ffffffffffffffff8111156105ba576105b9611c02565b5b6040519080825280602002602001820160405280156105e85781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b60606004805461063690611b4b565b80601f016020809104026020016040519081016040528092919081815260200182805461066290611b4b565b80156106af5780601f10610684576101008083540402835291602001916106af565b820191906000526020600020905b81548152906001019060200180831161069257829003601f168201915b5050505050905090565b6000806106c4610971565b905060006106d28286610895565b905083811015610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070e90611ca3565b60405180910390fd5b6107248286868403610979565b60019250505092915050565b60008061073b610971565b9050610748818585610bd0565b600191505092915050565b83421115610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078d90611d0f565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886107c58c610fbd565b896040516020016107db96959493929190611d2f565b60405160208183030381529060405280519060200120905060006107fe8261101b565b9050600061080e82878787611035565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461087e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087590611ddc565b60405180910390fd5b6108898a8a8a610979565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60006020835110156109385761093183611060565b9050610961565b8261094283610967565b60000190805190602001906109589291906114d4565b5060ff60001b90505b92915050565b6000819050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e090611e6e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610a59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5090611f00565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610b379190611750565b60405180910390a3505050565b6000610b508484610895565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bca5781811015610bbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb390611f6c565b60405180910390fd5b610bc98484848403610979565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3790611ffe565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610cb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca790612090565b60405180910390fd5b610cbb8383836110c8565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610d41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3890612122565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e2f9190611750565b60405180910390a3610e428484846110cd565b50505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015610ec457507f000000000000000000000000000000000000000000000000000000000000000046145b15610ef1577f00000000000000000000000000000000000000000000000000000000000000009050610efc565b610ef96110d2565b90505b90565b600081600001549050919050565b606060ff60001b8314610f2a57610f2383611168565b9050610fb7565b818054610f3690611b4b565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6290611b4b565b8015610faf5780601f10610f8457610100808354040283529160200191610faf565b820191906000526020600020905b815481529060010190602001808311610f9257829003601f168201915b505050505090505b92915050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061100a81610eff565b9150611015816111dc565b50919050565b600061102e611028610e48565b836111f2565b9050919050565b600080600061104687878787611233565b9150915061105381611316565b8192505050949350505050565b600080829050601f815111156110ad57826040517f305a27a90000000000000000000000000000000000000000000000000000000081526004016110a49190611610565b60405180910390fd5b8051816110b99061217f565b60001c1760001b915050919050565b505050565b505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000463060405160200161114d9594939291906121e6565b60405160208183030381529060405280519060200120905090565b6060600061117583611484565b90506000602067ffffffffffffffff81111561119457611193611c02565b5b6040519080825280601f01601f1916602001820160405280156111c65781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b6001816000016000828254019250508190555050565b60006040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561126e57600060039150915061130d565b6000600187878787604051600081526020016040526040516112939493929190612239565b6020604051602081039080840390855afa1580156112b5573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156113045760006001925092505061130d565b80600092509250505b94509492505050565b6000600481111561132a5761132961227e565b5b81600481111561133d5761133c61227e565b5b141561134857611481565b6001600481111561135c5761135b61227e565b5b81600481111561136f5761136e61227e565b5b14156113b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a7906122f9565b60405180910390fd5b600260048111156113c4576113c361227e565b5b8160048111156113d7576113d661227e565b5b1415611418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140f90612365565b60405180910390fd5b6003600481111561142c5761142b61227e565b5b81600481111561143f5761143e61227e565b5b1415611480576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611477906123f7565b60405180910390fd5b5b50565b60008060ff8360001c169050601f8111156114cb576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b8280546114e090611b4b565b90600052602060002090601f0160209004810192826115025760008555611549565b82601f1061151b57805160ff1916838001178555611549565b82800160010185558215611549579182015b8281111561154857825182559160200191906001019061152d565b5b509050611556919061155a565b5090565b5b8082111561157357600081600090555060010161155b565b5090565b600081519050919050565b600082825260208201905092915050565b60005b838110156115b1578082015181840152602081019050611596565b838111156115c0576000848401525b50505050565b6000601f19601f8301169050919050565b60006115e282611577565b6115ec8185611582565b93506115fc818560208601611593565b611605816115c6565b840191505092915050565b6000602082019050818103600083015261162a81846115d7565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061166282611637565b9050919050565b61167281611657565b811461167d57600080fd5b50565b60008135905061168f81611669565b92915050565b6000819050919050565b6116a881611695565b81146116b357600080fd5b50565b6000813590506116c58161169f565b92915050565b600080604083850312156116e2576116e1611632565b5b60006116f085828601611680565b9250506020611701858286016116b6565b9150509250929050565b60008115159050919050565b6117208161170b565b82525050565b600060208201905061173b6000830184611717565b92915050565b61174a81611695565b82525050565b60006020820190506117656000830184611741565b92915050565b60008060006060848603121561178457611783611632565b5b600061179286828701611680565b93505060206117a386828701611680565b92505060406117b4868287016116b6565b9150509250925092565b600060ff82169050919050565b6117d4816117be565b82525050565b60006020820190506117ef60008301846117cb565b92915050565b6000819050919050565b611808816117f5565b82525050565b600060208201905061182360008301846117ff565b92915050565b60006020828403121561183f5761183e611632565b5b600061184d84828501611680565b91505092915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b61188b81611856565b82525050565b61189a81611657565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6118d581611695565b82525050565b60006118e783836118cc565b60208301905092915050565b6000602082019050919050565b600061190b826118a0565b61191581856118ab565b9350611920836118bc565b8060005b8381101561195157815161193888826118db565b9750611943836118f3565b925050600181019050611924565b5085935050505092915050565b600060e082019050611973600083018a611882565b818103602083015261198581896115d7565b9050818103604083015261199981886115d7565b90506119a86060830187611741565b6119b56080830186611891565b6119c260a08301856117ff565b81810360c08301526119d48184611900565b905098975050505050505050565b6119eb816117be565b81146119f657600080fd5b50565b600081359050611a08816119e2565b92915050565b611a17816117f5565b8114611a2257600080fd5b50565b600081359050611a3481611a0e565b92915050565b600080600080600080600060e0888a031215611a5957611a58611632565b5b6000611a678a828b01611680565b9750506020611a788a828b01611680565b9650506040611a898a828b016116b6565b9550506060611a9a8a828b016116b6565b9450506080611aab8a828b016119f9565b93505060a0611abc8a828b01611a25565b92505060c0611acd8a828b01611a25565b91505092959891949750929550565b60008060408385031215611af357611af2611632565b5b6000611b0185828601611680565b9250506020611b1285828601611680565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611b6357607f821691505b60208210811415611b7757611b76611b1c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611bb782611695565b9150611bc283611695565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611bf757611bf6611b7d565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000611c8d602583611582565b9150611c9882611c31565b604082019050919050565b60006020820190508181036000830152611cbc81611c80565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b6000611cf9601d83611582565b9150611d0482611cc3565b602082019050919050565b60006020820190508181036000830152611d2881611cec565b9050919050565b600060c082019050611d4460008301896117ff565b611d516020830188611891565b611d5e6040830187611891565b611d6b6060830186611741565b611d786080830185611741565b611d8560a0830184611741565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b6000611dc6601e83611582565b9150611dd182611d90565b602082019050919050565b60006020820190508181036000830152611df581611db9565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000611e58602483611582565b9150611e6382611dfc565b604082019050919050565b60006020820190508181036000830152611e8781611e4b565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000611eea602283611582565b9150611ef582611e8e565b604082019050919050565b60006020820190508181036000830152611f1981611edd565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000611f56601d83611582565b9150611f6182611f20565b602082019050919050565b60006020820190508181036000830152611f8581611f49565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000611fe8602583611582565b9150611ff382611f8c565b604082019050919050565b6000602082019050818103600083015261201781611fdb565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061207a602383611582565b91506120858261201e565b604082019050919050565b600060208201905081810360008301526120a98161206d565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b600061210c602683611582565b9150612117826120b0565b604082019050919050565b6000602082019050818103600083015261213b816120ff565b9050919050565b600081519050919050565b6000819050602082019050919050565b600061216982516117f5565b80915050919050565b600082821b905092915050565b600061218a82612142565b826121948461214d565b905061219f8161215d565b925060208210156121df576121da7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802612172565b831692505b5050919050565b600060a0820190506121fb60008301886117ff565b61220860208301876117ff565b61221560408301866117ff565b6122226060830185611741565b61222f6080830184611891565b9695505050505050565b600060808201905061224e60008301876117ff565b61225b60208301866117cb565b61226860408301856117ff565b61227560608301846117ff565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b60006122e3601883611582565b91506122ee826122ad565b602082019050919050565b60006020820190508181036000830152612312816122d6565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b600061234f601f83611582565b915061235a82612319565b602082019050919050565b6000602082019050818103600083015261237e81612342565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b60006123e1602283611582565b91506123ec82612385565b604082019050919050565b60006020820190508181036000830152612410816123d4565b905091905056fea264697066735822122043a7a647c831e3c63b88d92001035a0b9fddb06d6e8b10db0ff6b6981a86138964736f6c63430008090033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100f55760003560e01c806370a0823111610097578063a457c2d711610066578063a457c2d7146102a4578063a9059cbb146102d4578063d505accf14610304578063dd62ed3e14610320576100f5565b806370a08231146102025780637ecebe001461023257806384b0196e1461026257806395d89b4114610286576100f5565b806323b872dd116100d357806323b872dd14610166578063313ce567146101965780633644e515146101b457806339509351146101d2576100f5565b806306fdde03146100fa578063095ea7b31461011857806318160ddd14610148575b600080fd5b610102610350565b60405161010f9190611610565b60405180910390f35b610132600480360381019061012d91906116cb565b6103e2565b60405161013f9190611726565b60405180910390f35b610150610405565b60405161015d9190611750565b60405180910390f35b610180600480360381019061017b919061176b565b61040f565b60405161018d9190611726565b60405180910390f35b61019e61043e565b6040516101ab91906117da565b60405180910390f35b6101bc610447565b6040516101c9919061180e565b60405180910390f35b6101ec60048036038101906101e791906116cb565b610456565b6040516101f99190611726565b60405180910390f35b61021c60048036038101906102179190611829565b61048d565b6040516102299190611750565b60405180910390f35b61024c60048036038101906102479190611829565b6104d5565b6040516102599190611750565b60405180910390f35b61026a610525565b60405161027d979695949392919061195e565b60405180910390f35b61028e610627565b60405161029b9190611610565b60405180910390f35b6102be60048036038101906102b991906116cb565b6106b9565b6040516102cb9190611726565b60405180910390f35b6102ee60048036038101906102e991906116cb565b610730565b6040516102fb9190611726565b60405180910390f35b61031e60048036038101906103199190611a3a565b610753565b005b61033a60048036038101906103359190611adc565b610895565b6040516103479190611750565b60405180910390f35b60606003805461035f90611b4b565b80601f016020809104026020016040519081016040528092919081815260200182805461038b90611b4b565b80156103d85780601f106103ad576101008083540402835291602001916103d8565b820191906000526020600020905b8154815290600101906020018083116103bb57829003601f168201915b5050505050905090565b6000806103ed610971565b90506103fa818585610979565b600191505092915050565b6000600254905090565b60008061041a610971565b9050610427858285610b44565b610432858585610bd0565b60019150509392505050565b60006012905090565b6000610451610e48565b905090565b600080610461610971565b90506104828185856104738589610895565b61047d9190611bac565b610979565b600191505092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600061051e600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020610eff565b9050919050565b60006060806000806000606061056560057f476167612028506570652900000000000000000000000000000000000000000b610f0d90919063ffffffff16565b61059960067f3100000000000000000000000000000000000000000000000000000000000001610f0d90919063ffffffff16565b46306000801b600067ffffffffffffffff8111156105ba576105b9611c02565b5b6040519080825280602002602001820160405280156105e85781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b60606004805461063690611b4b565b80601f016020809104026020016040519081016040528092919081815260200182805461066290611b4b565b80156106af5780601f10610684576101008083540402835291602001916106af565b820191906000526020600020905b81548152906001019060200180831161069257829003601f168201915b5050505050905090565b6000806106c4610971565b905060006106d28286610895565b905083811015610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070e90611ca3565b60405180910390fd5b6107248286868403610979565b60019250505092915050565b60008061073b610971565b9050610748818585610bd0565b600191505092915050565b83421115610796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078d90611d0f565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886107c58c610fbd565b896040516020016107db96959493929190611d2f565b60405160208183030381529060405280519060200120905060006107fe8261101b565b9050600061080e82878787611035565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461087e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087590611ddc565b60405180910390fd5b6108898a8a8a610979565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60006020835110156109385761093183611060565b9050610961565b8261094283610967565b60000190805190602001906109589291906114d4565b5060ff60001b90505b92915050565b6000819050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e090611e6e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610a59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5090611f00565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610b379190611750565b60405180910390a3505050565b6000610b508484610895565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610bca5781811015610bbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bb390611f6c565b60405180910390fd5b610bc98484848403610979565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3790611ffe565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610cb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca790612090565b60405180910390fd5b610cbb8383836110c8565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610d41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3890612122565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610e2f9190611750565b60405180910390a3610e428484846110cd565b50505050565b60007f000000000000000000000000b29dc1703facd2967bb8ade2e392385644c6dca973ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015610ec457507f000000000000000000000000000000000000000000000000000000000000000146145b15610ef1577f4e071d6faecd052210f1c0ff7f45b58c577ce184f691a0fdec1b3d8b7c82c2bf9050610efc565b610ef96110d2565b90505b90565b600081600001549050919050565b606060ff60001b8314610f2a57610f2383611168565b9050610fb7565b818054610f3690611b4b565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6290611b4b565b8015610faf5780601f10610f8457610100808354040283529160200191610faf565b820191906000526020600020905b815481529060010190602001808311610f9257829003601f168201915b505050505090505b92915050565b600080600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061100a81610eff565b9150611015816111dc565b50919050565b600061102e611028610e48565b836111f2565b9050919050565b600080600061104687878787611233565b9150915061105381611316565b8192505050949350505050565b600080829050601f815111156110ad57826040517f305a27a90000000000000000000000000000000000000000000000000000000081526004016110a49190611610565b60405180910390fd5b8051816110b99061217f565b60001c1760001b915050919050565b505050565b505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7ff04aa1bd6065ba1ef0758093f4e56b28d3c9a6aca53bb3e5873802383f9bce6d7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6463060405160200161114d9594939291906121e6565b60405160208183030381529060405280519060200120905090565b6060600061117583611484565b90506000602067ffffffffffffffff81111561119457611193611c02565b5b6040519080825280601f01601f1916602001820160405280156111c65781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b6001816000016000828254019250508190555050565b60006040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561126e57600060039150915061130d565b6000600187878787604051600081526020016040526040516112939493929190612239565b6020604051602081039080840390855afa1580156112b5573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156113045760006001925092505061130d565b80600092509250505b94509492505050565b6000600481111561132a5761132961227e565b5b81600481111561133d5761133c61227e565b5b141561134857611481565b6001600481111561135c5761135b61227e565b5b81600481111561136f5761136e61227e565b5b14156113b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a7906122f9565b60405180910390fd5b600260048111156113c4576113c361227e565b5b8160048111156113d7576113d661227e565b5b1415611418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161140f90612365565b60405180910390fd5b6003600481111561142c5761142b61227e565b5b81600481111561143f5761143e61227e565b5b1415611480576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611477906123f7565b60405180910390fd5b5b50565b60008060ff8360001c169050601f8111156114cb576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b8280546114e090611b4b565b90600052602060002090601f0160209004810192826115025760008555611549565b82601f1061151b57805160ff1916838001178555611549565b82800160010185558215611549579182015b8281111561154857825182559160200191906001019061152d565b5b509050611556919061155a565b5090565b5b8082111561157357600081600090555060010161155b565b5090565b600081519050919050565b600082825260208201905092915050565b60005b838110156115b1578082015181840152602081019050611596565b838111156115c0576000848401525b50505050565b6000601f19601f8301169050919050565b60006115e282611577565b6115ec8185611582565b93506115fc818560208601611593565b611605816115c6565b840191505092915050565b6000602082019050818103600083015261162a81846115d7565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061166282611637565b9050919050565b61167281611657565b811461167d57600080fd5b50565b60008135905061168f81611669565b92915050565b6000819050919050565b6116a881611695565b81146116b357600080fd5b50565b6000813590506116c58161169f565b92915050565b600080604083850312156116e2576116e1611632565b5b60006116f085828601611680565b9250506020611701858286016116b6565b9150509250929050565b60008115159050919050565b6117208161170b565b82525050565b600060208201905061173b6000830184611717565b92915050565b61174a81611695565b82525050565b60006020820190506117656000830184611741565b92915050565b60008060006060848603121561178457611783611632565b5b600061179286828701611680565b93505060206117a386828701611680565b92505060406117b4868287016116b6565b9150509250925092565b600060ff82169050919050565b6117d4816117be565b82525050565b60006020820190506117ef60008301846117cb565b92915050565b6000819050919050565b611808816117f5565b82525050565b600060208201905061182360008301846117ff565b92915050565b60006020828403121561183f5761183e611632565b5b600061184d84828501611680565b91505092915050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b61188b81611856565b82525050565b61189a81611657565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6118d581611695565b82525050565b60006118e783836118cc565b60208301905092915050565b6000602082019050919050565b600061190b826118a0565b61191581856118ab565b9350611920836118bc565b8060005b8381101561195157815161193888826118db565b9750611943836118f3565b925050600181019050611924565b5085935050505092915050565b600060e082019050611973600083018a611882565b818103602083015261198581896115d7565b9050818103604083015261199981886115d7565b90506119a86060830187611741565b6119b56080830186611891565b6119c260a08301856117ff565b81810360c08301526119d48184611900565b905098975050505050505050565b6119eb816117be565b81146119f657600080fd5b50565b600081359050611a08816119e2565b92915050565b611a17816117f5565b8114611a2257600080fd5b50565b600081359050611a3481611a0e565b92915050565b600080600080600080600060e0888a031215611a5957611a58611632565b5b6000611a678a828b01611680565b9750506020611a788a828b01611680565b9650506040611a898a828b016116b6565b9550506060611a9a8a828b016116b6565b9450506080611aab8a828b016119f9565b93505060a0611abc8a828b01611a25565b92505060c0611acd8a828b01611a25565b91505092959891949750929550565b60008060408385031215611af357611af2611632565b5b6000611b0185828601611680565b9250506020611b1285828601611680565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611b6357607f821691505b60208210811415611b7757611b76611b1c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611bb782611695565b9150611bc283611695565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611bf757611bf6611b7d565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b6000611c8d602583611582565b9150611c9882611c31565b604082019050919050565b60006020820190508181036000830152611cbc81611c80565b9050919050565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b6000611cf9601d83611582565b9150611d0482611cc3565b602082019050919050565b60006020820190508181036000830152611d2881611cec565b9050919050565b600060c082019050611d4460008301896117ff565b611d516020830188611891565b611d5e6040830187611891565b611d6b6060830186611741565b611d786080830185611741565b611d8560a0830184611741565b979650505050505050565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b6000611dc6601e83611582565b9150611dd182611d90565b602082019050919050565b60006020820190508181036000830152611df581611db9565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000611e58602483611582565b9150611e6382611dfc565b604082019050919050565b60006020820190508181036000830152611e8781611e4b565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b6000611eea602283611582565b9150611ef582611e8e565b604082019050919050565b60006020820190508181036000830152611f1981611edd565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b6000611f56601d83611582565b9150611f6182611f20565b602082019050919050565b60006020820190508181036000830152611f8581611f49565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b6000611fe8602583611582565b9150611ff382611f8c565b604082019050919050565b6000602082019050818103600083015261201781611fdb565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b600061207a602383611582565b91506120858261201e565b604082019050919050565b600060208201905081810360008301526120a98161206d565b9050919050565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b600061210c602683611582565b9150612117826120b0565b604082019050919050565b6000602082019050818103600083015261213b816120ff565b9050919050565b600081519050919050565b6000819050602082019050919050565b600061216982516117f5565b80915050919050565b600082821b905092915050565b600061218a82612142565b826121948461214d565b905061219f8161215d565b925060208210156121df576121da7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802612172565b831692505b5050919050565b600060a0820190506121fb60008301886117ff565b61220860208301876117ff565b61221560408301866117ff565b6122226060830185611741565b61222f6080830184611891565b9695505050505050565b600060808201905061224e60008301876117ff565b61225b60208301866117cb565b61226860408301856117ff565b61227560608301846117ff565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b60006122e3601883611582565b91506122ee826122ad565b602082019050919050565b60006020820190508181036000830152612312816122d6565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b600061234f601f83611582565b915061235a82612319565b602082019050919050565b6000602082019050818103600083015261237e81612342565b9050919050565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b60006123e1602283611582565b91506123ec82612385565b604082019050919050565b60006020820190508181036000830152612410816123d4565b905091905056fea264697066735822122043a7a647c831e3c63b88d92001035a0b9fddb06d6e8b10db0ff6b6981a86138964736f6c63430008090033

Deployed Bytecode Sourcemap

66868:192:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52475:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54835:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53604:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55616:261;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53446:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66281:115;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56286:238;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53775:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66023:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42792:657;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;52694:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57027:436;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54108:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65312:645;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54364:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52475:100;52529:13;52562:5;52555:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52475:100;:::o;54835:201::-;54918:4;54935:13;54951:12;:10;:12::i;:::-;54935:28;;54974:32;54983:5;54990:7;54999:6;54974:8;:32::i;:::-;55024:4;55017:11;;;54835:201;;;;:::o;53604:108::-;53665:7;53692:12;;53685:19;;53604:108;:::o;55616:261::-;55713:4;55730:15;55748:12;:10;:12::i;:::-;55730:30;;55771:38;55787:4;55793:7;55802:6;55771:15;:38::i;:::-;55820:27;55830:4;55836:2;55840:6;55820:9;:27::i;:::-;55865:4;55858:11;;;55616:261;;;;;:::o;53446:93::-;53504:5;53529:2;53522:9;;53446:93;:::o;66281:115::-;66341:7;66368:20;:18;:20::i;:::-;66361:27;;66281:115;:::o;56286:238::-;56374:4;56391:13;56407:12;:10;:12::i;:::-;56391:28;;56430:64;56439:5;56446:7;56483:10;56455:25;56465:5;56472:7;56455:9;:25::i;:::-;:38;;;;:::i;:::-;56430:8;:64::i;:::-;56512:4;56505:11;;;56286:238;;;;:::o;53775:127::-;53849:7;53876:9;:18;53886:7;53876:18;;;;;;;;;;;;;;;;53869:25;;53775:127;;;:::o;66023:128::-;66092:7;66119:24;:7;:14;66127:5;66119:14;;;;;;;;;;;;;;;:22;:24::i;:::-;66112:31;;66023:128;;;:::o;42792:657::-;42913:13;42941:18;42974:21;43010:15;43040:25;43080:12;43107:27;43215:41;43242:13;43215:5;:26;;:41;;;;:::i;:::-;43271:47;43301:16;43271:8;:29;;:47;;;;:::i;:::-;43333:13;43369:4;43397:1;43389:10;;43428:1;43414:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43162:279;;;;;;;;;;;;;;;;;;;;;42792:657;;;;;;;:::o;52694:104::-;52750:13;52783:7;52776:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52694:104;:::o;57027:436::-;57120:4;57137:13;57153:12;:10;:12::i;:::-;57137:28;;57176:24;57203:25;57213:5;57220:7;57203:9;:25::i;:::-;57176:52;;57267:15;57247:16;:35;;57239:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;57360:60;57369:5;57376:7;57404:15;57385:16;:34;57360:8;:60::i;:::-;57451:4;57444:11;;;;57027:436;;;;:::o;54108:193::-;54187:4;54204:13;54220:12;:10;:12::i;:::-;54204:28;;54243;54253:5;54260:2;54264:6;54243:9;:28::i;:::-;54289:4;54282:11;;;54108:193;;;;:::o;65312:645::-;65556:8;65537:15;:27;;65529:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;65611:18;64487:95;65671:5;65678:7;65687:5;65694:16;65704:5;65694:9;:16::i;:::-;65712:8;65642:79;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;65632:90;;;;;;65611:111;;65735:12;65750:28;65767:10;65750:16;:28::i;:::-;65735:43;;65791:14;65808:28;65822:4;65828:1;65831;65834;65808:13;:28::i;:::-;65791:45;;65865:5;65855:15;;:6;:15;;;65847:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;65918:31;65927:5;65934:7;65943:5;65918:8;:31::i;:::-;65518:439;;;65312:645;;;;;;;:::o;54364:151::-;54453:7;54480:11;:18;54492:5;54480:18;;;;;;;;;;;;;;;:27;54499:7;54480:27;;;;;;;;;;;;;;;;54473:34;;54364:151;;;;:::o;9574:348::-;9670:11;9720:2;9704:5;9698:19;:24;9694:221;;;9746:20;9760:5;9746:13;:20::i;:::-;9739:27;;;;9694:221;9840:5;9799:32;9825:5;9799:25;:32::i;:::-;:38;;:46;;;;;;;;;;;;:::i;:::-;;8003:66;9884:18;;9860:43;;9574:348;;;;;:::o;5761:207::-;5829:20;5940:10;5930:20;;5761:207;;;:::o;46515:98::-;46568:7;46595:10;46588:17;;46515:98;:::o;61020:346::-;61139:1;61122:19;;:5;:19;;;;61114:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61220:1;61201:21;;:7;:21;;;;61193:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61304:6;61274:11;:18;61286:5;61274:18;;;;;;;;;;;;;;;:27;61293:7;61274:27;;;;;;;;;;;;;;;:36;;;;61342:7;61326:32;;61335:5;61326:32;;;61351:6;61326:32;;;;;;:::i;:::-;;;;;;;;61020:346;;;:::o;61657:419::-;61758:24;61785:25;61795:5;61802:7;61785:9;:25::i;:::-;61758:52;;61845:17;61825:16;:37;61821:248;;61907:6;61887:16;:26;;61879:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61991:51;62000:5;62007:7;62035:6;62016:16;:25;61991:8;:51::i;:::-;61821:248;61747:329;61657:419;;;:::o;57933:806::-;58046:1;58030:18;;:4;:18;;;;58022:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;58123:1;58109:16;;:2;:16;;;;58101:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;58178:38;58199:4;58205:2;58209:6;58178:20;:38::i;:::-;58229:19;58251:9;:15;58261:4;58251:15;;;;;;;;;;;;;;;;58229:37;;58300:6;58285:11;:21;;58277:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;58417:6;58403:11;:20;58385:9;:15;58395:4;58385:15;;;;;;;;;;;;;;;:38;;;;58620:6;58603:9;:13;58613:2;58603:13;;;;;;;;;;;;;;;;:23;;;;;;;;;;;58670:2;58655:26;;58664:4;58655:26;;;58674:6;58655:26;;;;;;:::i;:::-;;;;;;;;58694:37;58714:4;58720:2;58724:6;58694:19;:37::i;:::-;58011:728;57933:806;;;:::o;41430:268::-;41483:7;41524:11;41507:28;;41515:4;41507:28;;;:63;;;;;41556:14;41539:13;:31;41507:63;41503:188;;;41594:22;41587:29;;;;41503:188;41656:23;:21;:23::i;:::-;41649:30;;41430:268;;:::o;911:114::-;976:7;1003;:14;;;996:21;;911:114;;;:::o;10058:274::-;10152:13;8003:66;10211:18;;10201:5;10182:47;10178:147;;10253:15;10262:5;10253:8;:15::i;:::-;10246:22;;;;10178:147;10308:5;10301:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10058:274;;;;;:::o;66534:207::-;66594:15;66622:30;66655:7;:14;66663:5;66655:14;;;;;;;;;;;;;;;66622:47;;66690:15;:5;:13;:15::i;:::-;66680:25;;66716:17;:5;:15;:17::i;:::-;66611:130;66534:207;;;:::o;42530:167::-;42607:7;42634:55;42656:20;:18;:20::i;:::-;42678:10;42634:21;:55::i;:::-;42627:62;;42530:167;;;:::o;35103:236::-;35188:7;35209:17;35228:18;35250:25;35261:4;35267:1;35270;35273;35250:10;:25::i;:::-;35208:67;;;;35286:18;35298:5;35286:11;:18::i;:::-;35322:9;35315:16;;;;35103:236;;;;;;:::o;8331:292::-;8396:11;8420:17;8446:3;8420:30;;8479:2;8465:4;:11;:16;8461:74;;;8519:3;8505:18;;;;;;;;;;;:::i;:::-;;;;;;;;8461:74;8602:4;:11;8593:4;8585:13;;;:::i;:::-;8577:22;;:36;8569:45;;8545:70;;;8331:292;;;:::o;62676:91::-;;;;:::o;63371:90::-;;;;:::o;41706:182::-;41761:7;39622:95;41821:11;41834:14;41850:13;41873:4;41798:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;41788:92;;;;;;41781:99;;41706:182;:::o;8712:415::-;8771:13;8797:11;8811:16;8822:4;8811:10;:16::i;:::-;8797:30;;8917:17;8948:2;8937:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8917:34;;9042:3;9037;9030:16;9083:4;9076;9071:3;9067:14;9060:28;9116:3;9109:10;;;;8712:415;;;:::o;1033:127::-;1140:1;1122:7;:14;;;:19;;;;;;;;;;;1033:127;:::o;36887:406::-;36980:12;37090:4;37084:11;37121:10;37116:3;37109:23;37169:15;37162:4;37157:3;37153:14;37146:39;37222:10;37215:4;37210:3;37206:14;37199:34;37270:4;37265:3;37255:20;37247:28;;37058:228;36887:406;;;;:::o;33487:1477::-;33575:7;33584:12;34509:66;34504:1;34496:10;;:79;34492:163;;;34608:1;34612:30;34592:51;;;;;;34492:163;34752:14;34769:24;34779:4;34785:1;34788;34791;34769:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34752:41;;34826:1;34808:20;;:6;:20;;;34804:103;;;34861:1;34865:29;34845:50;;;;;;;34804:103;34927:6;34935:20;34919:37;;;;;33487:1477;;;;;;;;:::o;28947:521::-;29025:20;29016:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;29012:449;;;29062:7;;29012:449;29123:29;29114:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;29110:351;;;29169:34;;;;;;;;;;:::i;:::-;;;;;;;;29110:351;29234:35;29225:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;29221:240;;;29286:41;;;;;;;;;;:::i;:::-;;;;;;;;29221:240;29358:30;29349:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;29345:116;;;29405:44;;;;;;;;;;:::i;:::-;;;;;;;;29345:116;28947:521;;:::o;9204:251::-;9265:7;9285:14;9338:4;9329;9302:33;;:40;9285:57;;9366:2;9357:6;:11;9353:71;;;9392:20;;;;;;;;;;;;;;9353:71;9441:6;9434:13;;;9204:251;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::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:307::-;355:1;365:113;379:6;376:1;373:13;365:113;;;464:1;459:3;455:11;449:18;445:1;440:3;436:11;429:39;401:2;398:1;394:10;389:15;;365:113;;;496:6;493:1;490:13;487:101;;;576:1;567:6;562:3;558:16;551:27;487:101;336:258;287:307;;;:::o;600:102::-;641:6;692:2;688:7;683:2;676:5;672:14;668:28;658:38;;600:102;;;:::o;708:364::-;796:3;824:39;857:5;824:39;:::i;:::-;879:71;943:6;938:3;879:71;:::i;:::-;872:78;;959:52;1004:6;999:3;992:4;985:5;981:16;959:52;:::i;:::-;1036:29;1058:6;1036:29;:::i;:::-;1031:3;1027:39;1020:46;;800:272;708:364;;;;:::o;1078:313::-;1191:4;1229:2;1218:9;1214:18;1206:26;;1278:9;1272:4;1268:20;1264:1;1253:9;1249:17;1242:47;1306:78;1379:4;1370:6;1306:78;:::i;:::-;1298:86;;1078:313;;;;:::o;1478:117::-;1587:1;1584;1577:12;1724:126;1761:7;1801:42;1794:5;1790:54;1779:65;;1724:126;;;:::o;1856:96::-;1893:7;1922:24;1940:5;1922:24;:::i;:::-;1911:35;;1856:96;;;:::o;1958:122::-;2031:24;2049:5;2031:24;:::i;:::-;2024:5;2021:35;2011:63;;2070:1;2067;2060:12;2011:63;1958:122;:::o;2086:139::-;2132:5;2170:6;2157:20;2148:29;;2186:33;2213:5;2186:33;:::i;:::-;2086:139;;;;:::o;2231:77::-;2268:7;2297:5;2286:16;;2231:77;;;:::o;2314:122::-;2387:24;2405:5;2387:24;:::i;:::-;2380:5;2377:35;2367:63;;2426:1;2423;2416:12;2367:63;2314:122;:::o;2442:139::-;2488:5;2526:6;2513:20;2504:29;;2542:33;2569:5;2542:33;:::i;:::-;2442:139;;;;:::o;2587:474::-;2655:6;2663;2712:2;2700:9;2691:7;2687:23;2683:32;2680:119;;;2718:79;;:::i;:::-;2680:119;2838:1;2863:53;2908:7;2899:6;2888:9;2884:22;2863:53;:::i;:::-;2853:63;;2809:117;2965:2;2991:53;3036:7;3027:6;3016:9;3012:22;2991:53;:::i;:::-;2981:63;;2936:118;2587:474;;;;;:::o;3067:90::-;3101:7;3144:5;3137:13;3130:21;3119:32;;3067:90;;;:::o;3163:109::-;3244:21;3259:5;3244:21;:::i;:::-;3239:3;3232:34;3163:109;;:::o;3278:210::-;3365:4;3403:2;3392:9;3388:18;3380:26;;3416:65;3478:1;3467:9;3463:17;3454:6;3416:65;:::i;:::-;3278:210;;;;:::o;3494:118::-;3581:24;3599:5;3581:24;:::i;:::-;3576:3;3569:37;3494:118;;:::o;3618:222::-;3711:4;3749:2;3738:9;3734:18;3726:26;;3762:71;3830:1;3819:9;3815:17;3806:6;3762:71;:::i;:::-;3618:222;;;;:::o;3846:619::-;3923:6;3931;3939;3988:2;3976:9;3967:7;3963:23;3959:32;3956:119;;;3994:79;;:::i;:::-;3956:119;4114:1;4139:53;4184:7;4175:6;4164:9;4160:22;4139:53;:::i;:::-;4129:63;;4085:117;4241:2;4267:53;4312:7;4303:6;4292:9;4288:22;4267:53;:::i;:::-;4257:63;;4212:118;4369:2;4395:53;4440:7;4431:6;4420:9;4416:22;4395:53;:::i;:::-;4385:63;;4340:118;3846:619;;;;;:::o;4471:86::-;4506:7;4546:4;4539:5;4535:16;4524:27;;4471:86;;;:::o;4563:112::-;4646:22;4662:5;4646:22;:::i;:::-;4641:3;4634:35;4563:112;;:::o;4681:214::-;4770:4;4808:2;4797:9;4793:18;4785:26;;4821:67;4885:1;4874:9;4870:17;4861:6;4821:67;:::i;:::-;4681:214;;;;:::o;4901:77::-;4938:7;4967:5;4956:16;;4901:77;;;:::o;4984:118::-;5071:24;5089:5;5071:24;:::i;:::-;5066:3;5059:37;4984:118;;:::o;5108:222::-;5201:4;5239:2;5228:9;5224:18;5216:26;;5252:71;5320:1;5309:9;5305:17;5296:6;5252:71;:::i;:::-;5108:222;;;;:::o;5336:329::-;5395:6;5444:2;5432:9;5423:7;5419:23;5415:32;5412:119;;;5450:79;;:::i;:::-;5412:119;5570:1;5595:53;5640:7;5631:6;5620:9;5616:22;5595:53;:::i;:::-;5585:63;;5541:117;5336:329;;;;:::o;5671:149::-;5707:7;5747:66;5740:5;5736:78;5725:89;;5671:149;;;:::o;5826:115::-;5911:23;5928:5;5911:23;:::i;:::-;5906:3;5899:36;5826:115;;:::o;5947:118::-;6034:24;6052:5;6034:24;:::i;:::-;6029:3;6022:37;5947:118;;:::o;6071:114::-;6138:6;6172:5;6166:12;6156:22;;6071:114;;;:::o;6191:184::-;6290:11;6324:6;6319:3;6312:19;6364:4;6359:3;6355:14;6340:29;;6191:184;;;;:::o;6381:132::-;6448:4;6471:3;6463:11;;6501:4;6496:3;6492:14;6484:22;;6381:132;;;:::o;6519:108::-;6596:24;6614:5;6596:24;:::i;:::-;6591:3;6584:37;6519:108;;:::o;6633:179::-;6702:10;6723:46;6765:3;6757:6;6723:46;:::i;:::-;6801:4;6796:3;6792:14;6778:28;;6633:179;;;;:::o;6818:113::-;6888:4;6920;6915:3;6911:14;6903:22;;6818:113;;;:::o;6967:732::-;7086:3;7115:54;7163:5;7115:54;:::i;:::-;7185:86;7264:6;7259:3;7185:86;:::i;:::-;7178:93;;7295:56;7345:5;7295:56;:::i;:::-;7374:7;7405:1;7390:284;7415:6;7412:1;7409:13;7390:284;;;7491:6;7485:13;7518:63;7577:3;7562:13;7518:63;:::i;:::-;7511:70;;7604:60;7657:6;7604:60;:::i;:::-;7594:70;;7450:224;7437:1;7434;7430:9;7425:14;;7390:284;;;7394:14;7690:3;7683:10;;7091:608;;;6967:732;;;;:::o;7705:1215::-;8054:4;8092:3;8081:9;8077:19;8069:27;;8106:69;8172:1;8161:9;8157:17;8148:6;8106:69;:::i;:::-;8222:9;8216:4;8212:20;8207:2;8196:9;8192:18;8185:48;8250:78;8323:4;8314:6;8250:78;:::i;:::-;8242:86;;8375:9;8369:4;8365:20;8360:2;8349:9;8345:18;8338:48;8403:78;8476:4;8467:6;8403:78;:::i;:::-;8395:86;;8491:72;8559:2;8548:9;8544:18;8535:6;8491:72;:::i;:::-;8573:73;8641:3;8630:9;8626:19;8617:6;8573:73;:::i;:::-;8656;8724:3;8713:9;8709:19;8700:6;8656:73;:::i;:::-;8777:9;8771:4;8767:20;8761:3;8750:9;8746:19;8739:49;8805:108;8908:4;8899:6;8805:108;:::i;:::-;8797:116;;7705:1215;;;;;;;;;;:::o;8926:118::-;8997:22;9013:5;8997:22;:::i;:::-;8990:5;8987:33;8977:61;;9034:1;9031;9024:12;8977:61;8926:118;:::o;9050:135::-;9094:5;9132:6;9119:20;9110:29;;9148:31;9173:5;9148:31;:::i;:::-;9050:135;;;;:::o;9191:122::-;9264:24;9282:5;9264:24;:::i;:::-;9257:5;9254:35;9244:63;;9303:1;9300;9293:12;9244:63;9191:122;:::o;9319:139::-;9365:5;9403:6;9390:20;9381:29;;9419:33;9446:5;9419:33;:::i;:::-;9319:139;;;;:::o;9464:1199::-;9575:6;9583;9591;9599;9607;9615;9623;9672:3;9660:9;9651:7;9647:23;9643:33;9640:120;;;9679:79;;:::i;:::-;9640:120;9799:1;9824:53;9869:7;9860:6;9849:9;9845:22;9824:53;:::i;:::-;9814:63;;9770:117;9926:2;9952:53;9997:7;9988:6;9977:9;9973:22;9952:53;:::i;:::-;9942:63;;9897:118;10054:2;10080:53;10125:7;10116:6;10105:9;10101:22;10080:53;:::i;:::-;10070:63;;10025:118;10182:2;10208:53;10253:7;10244:6;10233:9;10229:22;10208:53;:::i;:::-;10198:63;;10153:118;10310:3;10337:51;10380:7;10371:6;10360:9;10356:22;10337:51;:::i;:::-;10327:61;;10281:117;10437:3;10464:53;10509:7;10500:6;10489:9;10485:22;10464:53;:::i;:::-;10454:63;;10408:119;10566:3;10593:53;10638:7;10629:6;10618:9;10614:22;10593:53;:::i;:::-;10583:63;;10537:119;9464:1199;;;;;;;;;;:::o;10669:474::-;10737:6;10745;10794:2;10782:9;10773:7;10769:23;10765:32;10762:119;;;10800:79;;:::i;:::-;10762:119;10920:1;10945:53;10990:7;10981:6;10970:9;10966:22;10945:53;:::i;:::-;10935:63;;10891:117;11047:2;11073:53;11118:7;11109:6;11098:9;11094:22;11073:53;:::i;:::-;11063:63;;11018:118;10669:474;;;;;:::o;11149:180::-;11197:77;11194:1;11187:88;11294:4;11291:1;11284:15;11318:4;11315:1;11308:15;11335:320;11379:6;11416:1;11410:4;11406:12;11396:22;;11463:1;11457:4;11453:12;11484:18;11474:81;;11540:4;11532:6;11528:17;11518:27;;11474:81;11602:2;11594:6;11591:14;11571:18;11568:38;11565:84;;;11621:18;;:::i;:::-;11565:84;11386:269;11335:320;;;:::o;11661:180::-;11709:77;11706:1;11699:88;11806:4;11803:1;11796:15;11830:4;11827:1;11820:15;11847:305;11887:3;11906:20;11924:1;11906:20;:::i;:::-;11901:25;;11940:20;11958:1;11940:20;:::i;:::-;11935:25;;12094:1;12026:66;12022:74;12019:1;12016:81;12013:107;;;12100:18;;:::i;:::-;12013:107;12144:1;12141;12137:9;12130:16;;11847:305;;;;:::o;12158:180::-;12206:77;12203:1;12196:88;12303:4;12300:1;12293:15;12327:4;12324:1;12317:15;12344:224;12484:34;12480:1;12472:6;12468:14;12461:58;12553:7;12548:2;12540:6;12536:15;12529:32;12344:224;:::o;12574:366::-;12716:3;12737:67;12801:2;12796:3;12737:67;:::i;:::-;12730:74;;12813:93;12902:3;12813:93;:::i;:::-;12931:2;12926:3;12922:12;12915:19;;12574:366;;;:::o;12946:419::-;13112:4;13150:2;13139:9;13135:18;13127:26;;13199:9;13193:4;13189:20;13185:1;13174:9;13170:17;13163:47;13227:131;13353:4;13227:131;:::i;:::-;13219:139;;12946:419;;;:::o;13371:179::-;13511:31;13507:1;13499:6;13495:14;13488:55;13371:179;:::o;13556:366::-;13698:3;13719:67;13783:2;13778:3;13719:67;:::i;:::-;13712:74;;13795:93;13884:3;13795:93;:::i;:::-;13913:2;13908:3;13904:12;13897:19;;13556:366;;;:::o;13928:419::-;14094:4;14132:2;14121:9;14117:18;14109:26;;14181:9;14175:4;14171:20;14167:1;14156:9;14152:17;14145:47;14209:131;14335:4;14209:131;:::i;:::-;14201:139;;13928:419;;;:::o;14353:775::-;14586:4;14624:3;14613:9;14609:19;14601:27;;14638:71;14706:1;14695:9;14691:17;14682:6;14638:71;:::i;:::-;14719:72;14787:2;14776:9;14772:18;14763:6;14719:72;:::i;:::-;14801;14869:2;14858:9;14854:18;14845:6;14801:72;:::i;:::-;14883;14951:2;14940:9;14936:18;14927:6;14883:72;:::i;:::-;14965:73;15033:3;15022:9;15018:19;15009:6;14965:73;:::i;:::-;15048;15116:3;15105:9;15101:19;15092:6;15048:73;:::i;:::-;14353:775;;;;;;;;;:::o;15134:180::-;15274:32;15270:1;15262:6;15258:14;15251:56;15134:180;:::o;15320:366::-;15462:3;15483:67;15547:2;15542:3;15483:67;:::i;:::-;15476:74;;15559:93;15648:3;15559:93;:::i;:::-;15677:2;15672:3;15668:12;15661:19;;15320:366;;;:::o;15692:419::-;15858:4;15896:2;15885:9;15881:18;15873:26;;15945:9;15939:4;15935:20;15931:1;15920:9;15916:17;15909:47;15973:131;16099:4;15973:131;:::i;:::-;15965:139;;15692:419;;;:::o;16117:223::-;16257:34;16253:1;16245:6;16241:14;16234:58;16326:6;16321:2;16313:6;16309:15;16302:31;16117:223;:::o;16346:366::-;16488:3;16509:67;16573:2;16568:3;16509:67;:::i;:::-;16502:74;;16585:93;16674:3;16585:93;:::i;:::-;16703:2;16698:3;16694:12;16687:19;;16346:366;;;:::o;16718:419::-;16884:4;16922:2;16911:9;16907:18;16899:26;;16971:9;16965:4;16961:20;16957:1;16946:9;16942:17;16935:47;16999:131;17125:4;16999:131;:::i;:::-;16991:139;;16718:419;;;:::o;17143:221::-;17283:34;17279:1;17271:6;17267:14;17260:58;17352:4;17347:2;17339:6;17335:15;17328:29;17143:221;:::o;17370:366::-;17512:3;17533:67;17597:2;17592:3;17533:67;:::i;:::-;17526:74;;17609:93;17698:3;17609:93;:::i;:::-;17727:2;17722:3;17718:12;17711:19;;17370:366;;;:::o;17742:419::-;17908:4;17946:2;17935:9;17931:18;17923:26;;17995:9;17989:4;17985:20;17981:1;17970:9;17966:17;17959:47;18023:131;18149:4;18023:131;:::i;:::-;18015:139;;17742:419;;;:::o;18167:179::-;18307:31;18303:1;18295:6;18291:14;18284:55;18167:179;:::o;18352:366::-;18494:3;18515:67;18579:2;18574:3;18515:67;:::i;:::-;18508:74;;18591:93;18680:3;18591:93;:::i;:::-;18709:2;18704:3;18700:12;18693:19;;18352:366;;;:::o;18724:419::-;18890:4;18928:2;18917:9;18913:18;18905:26;;18977:9;18971:4;18967:20;18963:1;18952:9;18948:17;18941:47;19005:131;19131:4;19005:131;:::i;:::-;18997:139;;18724:419;;;:::o;19149:224::-;19289:34;19285:1;19277:6;19273:14;19266:58;19358:7;19353:2;19345:6;19341:15;19334:32;19149:224;:::o;19379:366::-;19521:3;19542:67;19606:2;19601:3;19542:67;:::i;:::-;19535:74;;19618:93;19707:3;19618:93;:::i;:::-;19736:2;19731:3;19727:12;19720:19;;19379:366;;;:::o;19751:419::-;19917:4;19955:2;19944:9;19940:18;19932:26;;20004:9;19998:4;19994:20;19990:1;19979:9;19975:17;19968:47;20032:131;20158:4;20032:131;:::i;:::-;20024:139;;19751:419;;;:::o;20176:222::-;20316:34;20312:1;20304:6;20300:14;20293:58;20385:5;20380:2;20372:6;20368:15;20361:30;20176:222;:::o;20404:366::-;20546:3;20567:67;20631:2;20626:3;20567:67;:::i;:::-;20560:74;;20643:93;20732:3;20643:93;:::i;:::-;20761:2;20756:3;20752:12;20745:19;;20404:366;;;:::o;20776:419::-;20942:4;20980:2;20969:9;20965:18;20957:26;;21029:9;21023:4;21019:20;21015:1;21004:9;21000:17;20993:47;21057:131;21183:4;21057:131;:::i;:::-;21049:139;;20776:419;;;:::o;21201:225::-;21341:34;21337:1;21329:6;21325:14;21318:58;21410:8;21405:2;21397:6;21393:15;21386:33;21201:225;:::o;21432:366::-;21574:3;21595:67;21659:2;21654:3;21595:67;:::i;:::-;21588:74;;21671:93;21760:3;21671:93;:::i;:::-;21789:2;21784:3;21780:12;21773:19;;21432:366;;;:::o;21804:419::-;21970:4;22008:2;21997:9;21993:18;21985:26;;22057:9;22051:4;22047:20;22043:1;22032:9;22028:17;22021:47;22085:131;22211:4;22085:131;:::i;:::-;22077:139;;21804:419;;;:::o;22229:98::-;22280:6;22314:5;22308:12;22298:22;;22229:98;;;:::o;22333:116::-;22384:4;22407:3;22399:11;;22437:4;22432:3;22428:14;22420:22;;22333:116;;;:::o;22455:154::-;22498:11;22534:29;22558:3;22552:10;22534:29;:::i;:::-;22597:5;22573:29;;22510:99;22455:154;;;:::o;22615:107::-;22659:8;22709:5;22703:4;22699:16;22678:37;;22615:107;;;;:::o;22728:594::-;22812:5;22843:38;22875:5;22843:38;:::i;:::-;22906:5;22933:40;22967:5;22933:40;:::i;:::-;22921:52;;22992:35;23018:8;22992:35;:::i;:::-;22983:44;;23051:2;23043:6;23040:14;23037:278;;;23122:169;23207:66;23177:6;23173:2;23169:15;23166:1;23162:23;23122:169;:::i;:::-;23099:5;23078:227;23069:236;;23037:278;22818:504;;22728:594;;;:::o;23328:664::-;23533:4;23571:3;23560:9;23556:19;23548:27;;23585:71;23653:1;23642:9;23638:17;23629:6;23585:71;:::i;:::-;23666:72;23734:2;23723:9;23719:18;23710:6;23666:72;:::i;:::-;23748;23816:2;23805:9;23801:18;23792:6;23748:72;:::i;:::-;23830;23898:2;23887:9;23883:18;23874:6;23830:72;:::i;:::-;23912:73;23980:3;23969:9;23965:19;23956:6;23912:73;:::i;:::-;23328:664;;;;;;;;:::o;23998:545::-;24171:4;24209:3;24198:9;24194:19;24186:27;;24223:71;24291:1;24280:9;24276:17;24267:6;24223:71;:::i;:::-;24304:68;24368:2;24357:9;24353:18;24344:6;24304:68;:::i;:::-;24382:72;24450:2;24439:9;24435:18;24426:6;24382:72;:::i;:::-;24464;24532:2;24521:9;24517:18;24508:6;24464:72;:::i;:::-;23998:545;;;;;;;:::o;24549:180::-;24597:77;24594:1;24587:88;24694:4;24691:1;24684:15;24718:4;24715:1;24708:15;24735:174;24875:26;24871:1;24863:6;24859:14;24852:50;24735:174;:::o;24915:366::-;25057:3;25078:67;25142:2;25137:3;25078:67;:::i;:::-;25071:74;;25154:93;25243:3;25154:93;:::i;:::-;25272:2;25267:3;25263:12;25256:19;;24915:366;;;:::o;25287:419::-;25453:4;25491:2;25480:9;25476:18;25468:26;;25540:9;25534:4;25530:20;25526:1;25515:9;25511:17;25504:47;25568:131;25694:4;25568:131;:::i;:::-;25560:139;;25287:419;;;:::o;25712:181::-;25852:33;25848:1;25840:6;25836:14;25829:57;25712:181;:::o;25899:366::-;26041:3;26062:67;26126:2;26121:3;26062:67;:::i;:::-;26055:74;;26138:93;26227:3;26138:93;:::i;:::-;26256:2;26251:3;26247:12;26240:19;;25899:366;;;:::o;26271:419::-;26437:4;26475:2;26464:9;26460:18;26452:26;;26524:9;26518:4;26514:20;26510:1;26499:9;26495:17;26488:47;26552:131;26678:4;26552:131;:::i;:::-;26544:139;;26271:419;;;:::o;26696:221::-;26836:34;26832:1;26824:6;26820:14;26813:58;26905:4;26900:2;26892:6;26888:15;26881:29;26696:221;:::o;26923:366::-;27065:3;27086:67;27150:2;27145:3;27086:67;:::i;:::-;27079:74;;27162:93;27251:3;27162:93;:::i;:::-;27280:2;27275:3;27271:12;27264:19;;26923:366;;;:::o;27295:419::-;27461:4;27499:2;27488:9;27484:18;27476:26;;27548:9;27542:4;27538:20;27534:1;27523:9;27519:17;27512:47;27576:131;27702:4;27576:131;:::i;:::-;27568:139;;27295:419;;;:::o

Swarm Source

ipfs://43a7a647c831e3c63b88d92001035a0b9fddb06d6e8b10db0ff6b6981a861389
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.