ETH Price: $2,051.91 (-9.84%)

Token

WISH (WISH)
 

Overview

Max Total Supply

198,971,164,599.675706893731961564 WISH

Holders

10

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
WISH

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 100000 runs

Other Settings:
default evmVersion, Apache-2.0 license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: BSD-4-Clause
/*
 * ABDK Math 64.64 Smart Contract Library.  Copyright © 2019 by ABDK Consulting.
 * Author: Mikhail Vladimirov <[email protected]>
 */
pragma solidity ^0.8.6;

/**
 * Smart contract library of mathematical functions operating with signed
 * 64.64-bit fixed point numbers.  Signed 64.64-bit fixed point number is
 * basically a simple fraction whose numerator is signed 128-bit integer and
 * denominator is 2^64.  As long as denominator is always the same, there is no
 * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are
 * represented by int128 type holding only the numerator.
 */
library ABDKMath64x64 {
    /*
     * Minimum value signed 64.64-bit fixed point number may have.
     */
    int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;

    /*
     * Maximum value signed 64.64-bit fixed point number may have.
     */
    int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

    /**
     * Convert signed 256-bit integer number into signed 64.64-bit fixed point
     * number.  Revert on overflow.
     *
     * @param x signed 256-bit integer number
     * @return signed 64.64-bit fixed point number
     */
    function fromInt(int256 x) internal pure returns (int128) {
        unchecked {
            require(x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
            return int128(x << 64);
        }
    }

    /**
     * Convert signed 64.64 fixed point number into signed 64-bit integer number
     * rounding down.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64-bit integer number
     */
    function toInt(int128 x) internal pure returns (int64) {
        unchecked {
            return int64(x >> 64);
        }
    }

    /**
     * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point
     * number.  Revert on overflow.
     *
     * @param x unsigned 256-bit integer number
     * @return signed 64.64-bit fixed point number
     */
    function fromUInt(uint256 x) internal pure returns (int128) {
        unchecked {
            require(x <= 0x7FFFFFFFFFFFFFFF);
            return int128(int256(x << 64));
        }
    }

    /**
     * Convert signed 64.64 fixed point number into unsigned 64-bit integer
     * number rounding down.  Revert on underflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return unsigned 64-bit integer number
     */
    function toUInt(int128 x) internal pure returns (uint64) {
        unchecked {
            require(x >= 0);
            return uint64(uint128(x >> 64));
        }
    }

    /**
     * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point
     * number rounding down.  Revert on overflow.
     *
     * @param x signed 128.128-bin fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function from128x128(int256 x) internal pure returns (int128) {
        unchecked {
            int256 result = x >> 64;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Convert signed 64.64 fixed point number into signed 128.128 fixed point
     * number.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 128.128 fixed point number
     */
    function to128x128(int128 x) internal pure returns (int256) {
        unchecked {
            return int256(x) << 64;
        }
    }

    /**
     * Calculate x + y.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function add(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            int256 result = int256(x) + y;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate x - y.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function sub(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            int256 result = int256(x) - y;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate x * y rounding down.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function mul(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            int256 result = (int256(x) * y) >> 64;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point
     * number and y is signed 256-bit integer number.  Revert on overflow.
     *
     * @param x signed 64.64 fixed point number
     * @param y signed 256-bit integer number
     * @return signed 256-bit integer number
     */
    function muli(int128 x, int256 y) internal pure returns (int256) {
        unchecked {
            if (x == MIN_64x64) {
                require(
                    y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
                        y <= 0x1000000000000000000000000000000000000000000000000
                );
                return -y << 63;
            } else {
                bool negativeResult = false;
                if (x < 0) {
                    x = -x;
                    negativeResult = true;
                }
                if (y < 0) {
                    y = -y; // We rely on overflow behavior here
                    negativeResult = !negativeResult;
                }
                uint256 absoluteResult = mulu(x, uint256(y));
                if (negativeResult) {
                    require(
                        absoluteResult <=
                            0x8000000000000000000000000000000000000000000000000000000000000000
                    );
                    return -int256(absoluteResult); // We rely on overflow behavior here
                } else {
                    require(
                        absoluteResult <=
                            0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                    );
                    return int256(absoluteResult);
                }
            }
        }
    }

    /**
     * Calculate x * y rounding down, where x is signed 64.64 fixed point number
     * and y is unsigned 256-bit integer number.  Revert on overflow.
     *
     * @param x signed 64.64 fixed point number
     * @param y unsigned 256-bit integer number
     * @return unsigned 256-bit integer number
     */
    function mulu(int128 x, uint256 y) internal pure returns (uint256) {
        unchecked {
            if (y == 0) return 0;

            require(x >= 0);

            uint256 lo = (uint256(int256(x)) *
                (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
            uint256 hi = uint256(int256(x)) * (y >> 128);

            require(hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
            hi <<= 64;

            require(
                hi <=
                    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -
                        lo
            );
            return hi + lo;
        }
    }

    /**
     * Calculate x / y rounding towards zero.  Revert on overflow or when y is
     * zero.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function div(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            require(y != 0);
            int256 result = (int256(x) << 64) / y;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate x / y rounding towards zero, where x and y are signed 256-bit
     * integer numbers.  Revert on overflow or when y is zero.
     *
     * @param x signed 256-bit integer number
     * @param y signed 256-bit integer number
     * @return signed 64.64-bit fixed point number
     */
    function divi(int256 x, int256 y) internal pure returns (int128) {
        unchecked {
            require(y != 0);

            bool negativeResult = false;
            if (x < 0) {
                x = -x; // We rely on overflow behavior here
                negativeResult = true;
            }
            if (y < 0) {
                y = -y; // We rely on overflow behavior here
                negativeResult = !negativeResult;
            }
            uint128 absoluteResult = divuu(uint256(x), uint256(y));
            if (negativeResult) {
                require(absoluteResult <= 0x80000000000000000000000000000000);
                return -int128(absoluteResult); // We rely on overflow behavior here
            } else {
                require(absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
                return int128(absoluteResult); // We rely on overflow behavior here
            }
        }
    }

    /**
     * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
     * integer numbers.  Revert on overflow or when y is zero.
     *
     * @param x unsigned 256-bit integer number
     * @param y unsigned 256-bit integer number
     * @return signed 64.64-bit fixed point number
     */
    function divu(uint256 x, uint256 y) internal pure returns (int128) {
        unchecked {
            require(y != 0);
            uint128 result = divuu(x, y);
            require(result <= uint128(MAX_64x64));
            return int128(result);
        }
    }

    /**
     * Calculate -x.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function neg(int128 x) internal pure returns (int128) {
        unchecked {
            require(x != MIN_64x64);
            return -x;
        }
    }

    /**
     * Calculate |x|.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function abs(int128 x) internal pure returns (int128) {
        unchecked {
            require(x != MIN_64x64);
            return x < 0 ? -x : x;
        }
    }

    /**
     * Calculate 1 / x rounding towards zero.  Revert on overflow or when x is
     * zero.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function inv(int128 x) internal pure returns (int128) {
        unchecked {
            require(x != 0);
            int256 result = int256(0x100000000000000000000000000000000) / x;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function avg(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            return int128((int256(x) + int256(y)) >> 1);
        }
    }

    /**
     * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.
     * Revert on overflow or in case x * y is negative.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function gavg(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            int256 m = int256(x) * int256(y);
            require(m >= 0);
            require(
                m <
                    0x4000000000000000000000000000000000000000000000000000000000000000
            );
            return int128(sqrtu(uint256(m)));
        }
    }

    /**
     * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number
     * and y is unsigned 256-bit integer number.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y uint256 value
     * @return signed 64.64-bit fixed point number
     */
    function pow(int128 x, uint256 y) internal pure returns (int128) {
        unchecked {
            bool negative = x < 0 && y & 1 == 1;

            uint256 absX = uint128(x < 0 ? -x : x);
            uint256 absResult;
            absResult = 0x100000000000000000000000000000000;

            if (absX <= 0x10000000000000000) {
                absX <<= 63;
                while (y != 0) {
                    if (y & 0x1 != 0) {
                        absResult = (absResult * absX) >> 127;
                    }
                    absX = (absX * absX) >> 127;

                    if (y & 0x2 != 0) {
                        absResult = (absResult * absX) >> 127;
                    }
                    absX = (absX * absX) >> 127;

                    if (y & 0x4 != 0) {
                        absResult = (absResult * absX) >> 127;
                    }
                    absX = (absX * absX) >> 127;

                    if (y & 0x8 != 0) {
                        absResult = (absResult * absX) >> 127;
                    }
                    absX = (absX * absX) >> 127;

                    y >>= 4;
                }

                absResult >>= 64;
            } else {
                uint256 absXShift = 63;
                if (absX < 0x1000000000000000000000000) {
                    absX <<= 32;
                    absXShift -= 32;
                }
                if (absX < 0x10000000000000000000000000000) {
                    absX <<= 16;
                    absXShift -= 16;
                }
                if (absX < 0x1000000000000000000000000000000) {
                    absX <<= 8;
                    absXShift -= 8;
                }
                if (absX < 0x10000000000000000000000000000000) {
                    absX <<= 4;
                    absXShift -= 4;
                }
                if (absX < 0x40000000000000000000000000000000) {
                    absX <<= 2;
                    absXShift -= 2;
                }
                if (absX < 0x80000000000000000000000000000000) {
                    absX <<= 1;
                    absXShift -= 1;
                }

                uint256 resultShift = 0;
                while (y != 0) {
                    require(absXShift < 64);

                    if (y & 0x1 != 0) {
                        absResult = (absResult * absX) >> 127;
                        resultShift += absXShift;
                        if (absResult > 0x100000000000000000000000000000000) {
                            absResult >>= 1;
                            resultShift += 1;
                        }
                    }
                    absX = (absX * absX) >> 127;
                    absXShift <<= 1;
                    if (absX >= 0x100000000000000000000000000000000) {
                        absX >>= 1;
                        absXShift += 1;
                    }

                    y >>= 1;
                }

                require(resultShift < 64);
                absResult >>= 64 - resultShift;
            }
            int256 result = negative ? -int256(absResult) : int256(absResult);
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate sqrt (x) rounding down.  Revert if x < 0.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function sqrt(int128 x) internal pure returns (int128) {
        unchecked {
            require(x >= 0);
            return int128(sqrtu(uint256(int256(x)) << 64));
        }
    }

    /**
     * Calculate binary logarithm of x.  Revert if x <= 0.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function log_2(int128 x) internal pure returns (int128) {
        unchecked {
            require(x > 0);

            int256 msb = 0;
            int256 xc = x;
            if (xc >= 0x10000000000000000) {
                xc >>= 64;
                msb += 64;
            }
            if (xc >= 0x100000000) {
                xc >>= 32;
                msb += 32;
            }
            if (xc >= 0x10000) {
                xc >>= 16;
                msb += 16;
            }
            if (xc >= 0x100) {
                xc >>= 8;
                msb += 8;
            }
            if (xc >= 0x10) {
                xc >>= 4;
                msb += 4;
            }
            if (xc >= 0x4) {
                xc >>= 2;
                msb += 2;
            }
            if (xc >= 0x2) msb += 1; // No need to shift xc anymore

            int256 result = (msb - 64) << 64;
            uint256 ux = uint256(int256(x)) << uint256(127 - msb);
            for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
                ux *= ux;
                uint256 b = ux >> 255;
                ux >>= 127 + b;
                result += bit * int256(b);
            }

            return int128(result);
        }
    }

    /**
     * Calculate natural logarithm of x.  Revert if x <= 0.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function ln(int128 x) internal pure returns (int128) {
        unchecked {
            require(x > 0);

            return
                int128(
                    int256(
                        (uint256(int256(log_2(x))) *
                            0xB17217F7D1CF79ABC9E3B39803F2F6AF) >> 128
                    )
                );
        }
    }

    /**
     * Calculate binary exponent of x.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function exp_2(int128 x) internal pure returns (int128) {
        unchecked {
            require(x < 0x400000000000000000); // Overflow

            if (x < -0x400000000000000000) return 0; // Underflow

            uint256 result = 0x80000000000000000000000000000000;

            if (x & 0x8000000000000000 > 0)
                result = (result * 0x16A09E667F3BCC908B2FB1366EA957D3E) >> 128;
            if (x & 0x4000000000000000 > 0)
                result = (result * 0x1306FE0A31B7152DE8D5A46305C85EDEC) >> 128;
            if (x & 0x2000000000000000 > 0)
                result = (result * 0x1172B83C7D517ADCDF7C8C50EB14A791F) >> 128;
            if (x & 0x1000000000000000 > 0)
                result = (result * 0x10B5586CF9890F6298B92B71842A98363) >> 128;
            if (x & 0x800000000000000 > 0)
                result = (result * 0x1059B0D31585743AE7C548EB68CA417FD) >> 128;
            if (x & 0x400000000000000 > 0)
                result = (result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8) >> 128;
            if (x & 0x200000000000000 > 0)
                result = (result * 0x10163DA9FB33356D84A66AE336DCDFA3F) >> 128;
            if (x & 0x100000000000000 > 0)
                result = (result * 0x100B1AFA5ABCBED6129AB13EC11DC9543) >> 128;
            if (x & 0x80000000000000 > 0)
                result = (result * 0x10058C86DA1C09EA1FF19D294CF2F679B) >> 128;
            if (x & 0x40000000000000 > 0)
                result = (result * 0x1002C605E2E8CEC506D21BFC89A23A00F) >> 128;
            if (x & 0x20000000000000 > 0)
                result = (result * 0x100162F3904051FA128BCA9C55C31E5DF) >> 128;
            if (x & 0x10000000000000 > 0)
                result = (result * 0x1000B175EFFDC76BA38E31671CA939725) >> 128;
            if (x & 0x8000000000000 > 0)
                result = (result * 0x100058BA01FB9F96D6CACD4B180917C3D) >> 128;
            if (x & 0x4000000000000 > 0)
                result = (result * 0x10002C5CC37DA9491D0985C348C68E7B3) >> 128;
            if (x & 0x2000000000000 > 0)
                result = (result * 0x1000162E525EE054754457D5995292026) >> 128;
            if (x & 0x1000000000000 > 0)
                result = (result * 0x10000B17255775C040618BF4A4ADE83FC) >> 128;
            if (x & 0x800000000000 > 0)
                result = (result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB) >> 128;
            if (x & 0x400000000000 > 0)
                result = (result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9) >> 128;
            if (x & 0x200000000000 > 0)
                result = (result * 0x10000162E43F4F831060E02D839A9D16D) >> 128;
            if (x & 0x100000000000 > 0)
                result = (result * 0x100000B1721BCFC99D9F890EA06911763) >> 128;
            if (x & 0x80000000000 > 0)
                result = (result * 0x10000058B90CF1E6D97F9CA14DBCC1628) >> 128;
            if (x & 0x40000000000 > 0)
                result = (result * 0x1000002C5C863B73F016468F6BAC5CA2B) >> 128;
            if (x & 0x20000000000 > 0)
                result = (result * 0x100000162E430E5A18F6119E3C02282A5) >> 128;
            if (x & 0x10000000000 > 0)
                result = (result * 0x1000000B1721835514B86E6D96EFD1BFE) >> 128;
            if (x & 0x8000000000 > 0)
                result = (result * 0x100000058B90C0B48C6BE5DF846C5B2EF) >> 128;
            if (x & 0x4000000000 > 0)
                result = (result * 0x10000002C5C8601CC6B9E94213C72737A) >> 128;
            if (x & 0x2000000000 > 0)
                result = (result * 0x1000000162E42FFF037DF38AA2B219F06) >> 128;
            if (x & 0x1000000000 > 0)
                result = (result * 0x10000000B17217FBA9C739AA5819F44F9) >> 128;
            if (x & 0x800000000 > 0)
                result = (result * 0x1000000058B90BFCDEE5ACD3C1CEDC823) >> 128;
            if (x & 0x400000000 > 0)
                result = (result * 0x100000002C5C85FE31F35A6A30DA1BE50) >> 128;
            if (x & 0x200000000 > 0)
                result = (result * 0x10000000162E42FF0999CE3541B9FFFCF) >> 128;
            if (x & 0x100000000 > 0)
                result = (result * 0x100000000B17217F80F4EF5AADDA45554) >> 128;
            if (x & 0x80000000 > 0)
                result = (result * 0x10000000058B90BFBF8479BD5A81B51AD) >> 128;
            if (x & 0x40000000 > 0)
                result = (result * 0x1000000002C5C85FDF84BD62AE30A74CC) >> 128;
            if (x & 0x20000000 > 0)
                result = (result * 0x100000000162E42FEFB2FED257559BDAA) >> 128;
            if (x & 0x10000000 > 0)
                result = (result * 0x1000000000B17217F7D5A7716BBA4A9AE) >> 128;
            if (x & 0x8000000 > 0)
                result = (result * 0x100000000058B90BFBE9DDBAC5E109CCE) >> 128;
            if (x & 0x4000000 > 0)
                result = (result * 0x10000000002C5C85FDF4B15DE6F17EB0D) >> 128;
            if (x & 0x2000000 > 0)
                result = (result * 0x1000000000162E42FEFA494F1478FDE05) >> 128;
            if (x & 0x1000000 > 0)
                result = (result * 0x10000000000B17217F7D20CF927C8E94C) >> 128;
            if (x & 0x800000 > 0)
                result = (result * 0x1000000000058B90BFBE8F71CB4E4B33D) >> 128;
            if (x & 0x400000 > 0)
                result = (result * 0x100000000002C5C85FDF477B662B26945) >> 128;
            if (x & 0x200000 > 0)
                result = (result * 0x10000000000162E42FEFA3AE53369388C) >> 128;
            if (x & 0x100000 > 0)
                result = (result * 0x100000000000B17217F7D1D351A389D40) >> 128;
            if (x & 0x80000 > 0)
                result = (result * 0x10000000000058B90BFBE8E8B2D3D4EDE) >> 128;
            if (x & 0x40000 > 0)
                result = (result * 0x1000000000002C5C85FDF4741BEA6E77E) >> 128;
            if (x & 0x20000 > 0)
                result = (result * 0x100000000000162E42FEFA39FE95583C2) >> 128;
            if (x & 0x10000 > 0)
                result = (result * 0x1000000000000B17217F7D1CFB72B45E1) >> 128;
            if (x & 0x8000 > 0)
                result = (result * 0x100000000000058B90BFBE8E7CC35C3F0) >> 128;
            if (x & 0x4000 > 0)
                result = (result * 0x10000000000002C5C85FDF473E242EA38) >> 128;
            if (x & 0x2000 > 0)
                result = (result * 0x1000000000000162E42FEFA39F02B772C) >> 128;
            if (x & 0x1000 > 0)
                result = (result * 0x10000000000000B17217F7D1CF7D83C1A) >> 128;
            if (x & 0x800 > 0)
                result = (result * 0x1000000000000058B90BFBE8E7BDCBE2E) >> 128;
            if (x & 0x400 > 0)
                result = (result * 0x100000000000002C5C85FDF473DEA871F) >> 128;
            if (x & 0x200 > 0)
                result = (result * 0x10000000000000162E42FEFA39EF44D91) >> 128;
            if (x & 0x100 > 0)
                result = (result * 0x100000000000000B17217F7D1CF79E949) >> 128;
            if (x & 0x80 > 0)
                result = (result * 0x10000000000000058B90BFBE8E7BCE544) >> 128;
            if (x & 0x40 > 0)
                result = (result * 0x1000000000000002C5C85FDF473DE6ECA) >> 128;
            if (x & 0x20 > 0)
                result = (result * 0x100000000000000162E42FEFA39EF366F) >> 128;
            if (x & 0x10 > 0)
                result = (result * 0x1000000000000000B17217F7D1CF79AFA) >> 128;
            if (x & 0x8 > 0)
                result = (result * 0x100000000000000058B90BFBE8E7BCD6D) >> 128;
            if (x & 0x4 > 0)
                result = (result * 0x10000000000000002C5C85FDF473DE6B2) >> 128;
            if (x & 0x2 > 0)
                result = (result * 0x1000000000000000162E42FEFA39EF358) >> 128;
            if (x & 0x1 > 0)
                result = (result * 0x10000000000000000B17217F7D1CF79AB) >> 128;

            result >>= uint256(int256(63 - (x >> 64)));
            require(result <= uint256(int256(MAX_64x64)));

            return int128(int256(result));
        }
    }

    /**
     * Calculate natural exponent of x.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function exp(int128 x) internal pure returns (int128) {
        unchecked {
            require(x < 0x400000000000000000); // Overflow

            if (x < -0x400000000000000000) return 0; // Underflow

            return
                exp_2(
                    int128(
                        (int256(x) * 0x171547652B82FE1777D0FFDA0D23A7D12) >> 128
                    )
                );
        }
    }

    /**
     * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
     * integer numbers.  Revert on overflow or when y is zero.
     *
     * @param x unsigned 256-bit integer number
     * @param y unsigned 256-bit integer number
     * @return unsigned 64.64-bit fixed point number
     */
    function divuu(uint256 x, uint256 y) private pure returns (uint128) {
        unchecked {
            require(y != 0);

            uint256 result;

            if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
                result = (x << 64) / y;
            else {
                uint256 msb = 192;
                uint256 xc = x >> 192;
                if (xc >= 0x100000000) {
                    xc >>= 32;
                    msb += 32;
                }
                if (xc >= 0x10000) {
                    xc >>= 16;
                    msb += 16;
                }
                if (xc >= 0x100) {
                    xc >>= 8;
                    msb += 8;
                }
                if (xc >= 0x10) {
                    xc >>= 4;
                    msb += 4;
                }
                if (xc >= 0x4) {
                    xc >>= 2;
                    msb += 2;
                }
                if (xc >= 0x2) msb += 1; // No need to shift xc anymore

                result = (x << (255 - msb)) / (((y - 1) >> (msb - 191)) + 1);
                require(result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

                uint256 hi = result * (y >> 128);
                uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

                uint256 xh = x >> 192;
                uint256 xl = x << 64;

                if (xl < lo) xh -= 1;
                xl -= lo; // We rely on overflow behavior here
                lo = hi << 128;
                if (xl < lo) xh -= 1;
                xl -= lo; // We rely on overflow behavior here

                assert(xh == hi >> 128);

                result += xl / y;
            }

            require(result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
            return uint128(result);
        }
    }

    /**
     * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer
     * number.
     *
     * @param x unsigned 256-bit integer number
     * @return unsigned 128-bit integer number
     */
    function sqrtu(uint256 x) private pure returns (uint128) {
        unchecked {
            if (x == 0) return 0;
            else {
                uint256 xx = x;
                uint256 r = 1;
                if (xx >= 0x100000000000000000000000000000000) {
                    xx >>= 128;
                    r <<= 64;
                }
                if (xx >= 0x10000000000000000) {
                    xx >>= 64;
                    r <<= 32;
                }
                if (xx >= 0x100000000) {
                    xx >>= 32;
                    r <<= 16;
                }
                if (xx >= 0x10000) {
                    xx >>= 16;
                    r <<= 8;
                }
                if (xx >= 0x100) {
                    xx >>= 8;
                    r <<= 4;
                }
                if (xx >= 0x10) {
                    xx >>= 4;
                    r <<= 2;
                }
                if (xx >= 0x8) {
                    r <<= 1;
                }
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1; // Seven iterations should be enough
                uint256 r1 = x / r;
                return uint128(r < r1 ? r : r1);
            }
        }
    }
}




abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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




library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}



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);
}




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);
}



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);
}



contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

        return true;
    }

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

        _beforeTokenTransfer(from, to, amount);

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

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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


library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}



contract WISH is ERC20 {
    /* WISH  starts at $0.00000001 on 2023 Mar 6th, enriches 100m times till 2033 Jan 21st, and stablizes at $1.00000005841 */
    using SafeERC20 for ERC20;
    mapping(address => bool) public isUSD;
    mapping(address => uint256) public Decimals;
    uint256 public constant launchTime = 1678104000; /* Mon Mar 06 2023 12:00:00 GMT+0000 */
    uint256 public constant stableTime = 1989925200; /* Fri Jan 21 2033 13:00:00 GMT+0000 */
    address private constant wishFundationAddr =
        0x709D83004eB79Cf752B5D4f021d3652c97Ad1561; 

    constructor(
        address usdt,
        uint256 usdtDecimal,
        address usdc,
        uint256 usdcDecimal,
        address busd,
        uint256 busdDecimal,
        address dai,
        uint256 daiDecimal
    ) ERC20("WISH", "WISH") {
        isUSD[usdt] = true;
        Decimals[usdt] = usdtDecimal;
        isUSD[usdc] = true;
        Decimals[usdc] = usdcDecimal;
        isUSD[busd] = true;
        Decimals[busd] = busdDecimal;
        isUSD[dai] = true;
        Decimals[dai] = daiDecimal;
    }

    function convert6To18(uint256 amount, uint256 decimal)
        public
        pure
        returns (uint256)
    {
        if (decimal == 6) return amount * 1e12;

        return amount;
    }

    function convert18To6(uint256 usd, uint256 decimal)
        public
        pure
        returns (uint256)
    {
        if (decimal == 6) return usd / 1e12;

        return usd;
    }

    function getWishFundationAddress() public pure returns (address) {
        return wishFundationAddr;
    }

    /**
     * The current price of WISH is always 6.4428653X of the price a year ago
     *   y = 6.4428653^(ticktock / 365 days)
     */
    function getPrice() public view returns (uint256) {
        uint256 ticktock;

        if (block.timestamp <= launchTime) return 10000000000; /* WISH price stablizes at $0.00000001 before 2023 Mar 6 */
        if (block.timestamp >= stableTime) return 1000000058410266000; /* WISH price stablizes at $1.00000005841 after 2033 Jan 21 */

        ticktock = block.timestamp - launchTime;

        int128 base = ABDKMath64x64.div(
            ABDKMath64x64.fromUInt(64428653),
            ABDKMath64x64.fromUInt(10000000)
        );
        int128 exponential = ABDKMath64x64.div(
            ABDKMath64x64.fromUInt(ticktock),
            ABDKMath64x64.fromUInt(365 days)
        );

        /**
         * Basic logarithm rule:
         *   x = a^(log_a(x))
         * And deduce it:
         *   x^y = a^(y*log_a(x))
         * When a equals 2
         *   x^y = 2^(y*log_2(x))
         */
        return
            ABDKMath64x64.mulu(
                ABDKMath64x64.exp_2(
                    ABDKMath64x64.mul(exponential, ABDKMath64x64.log_2(base))
                ),
                1e10
            );
    }

    function Buy(address usd, uint256 amount) external returns (bool) {
        require(isUSD[usd], "USD ERROR");
        uint256 _commissionFee = ((amount * 5) / 100);
        uint256 remain = amount - _commissionFee;

        ERC20(usd).safeTransferFrom(
            msg.sender,
            getWishFundationAddress(),
            _commissionFee
        );
        ERC20(usd).safeTransferFrom(msg.sender, address(this), remain);

        remain = convert6To18(remain, Decimals[usd]);
        uint256 wishes = (remain * 1e18) / getPrice();

        _mint(msg.sender, wishes);

        return true;
    }

    function Sell(address usd, uint256 wishes) external returns (bool) {
        require(isUSD[usd], "USD ERROR");

        _burn(msg.sender, wishes);

        uint256 _usd = (wishes * getPrice()) / 1e18;
        _usd = convert18To6(_usd, Decimals[usd]);
        uint256 _commissionFee = ((_usd * 2) / 10);
        uint256 _remain = _usd - _commissionFee;

        ERC20(usd).safeTransfer(getWishFundationAddress(), _commissionFee);
        ERC20(usd).safeTransfer(msg.sender, _remain);
        return true;
    }

    function burn(uint256 wishes) external {
        _burn(msg.sender, wishes);
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"usdt","type":"address"},{"internalType":"uint256","name":"usdtDecimal","type":"uint256"},{"internalType":"address","name":"usdc","type":"address"},{"internalType":"uint256","name":"usdcDecimal","type":"uint256"},{"internalType":"address","name":"busd","type":"address"},{"internalType":"uint256","name":"busdDecimal","type":"uint256"},{"internalType":"address","name":"dai","type":"address"},{"internalType":"uint256","name":"daiDecimal","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"usd","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Buy","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"Decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"usd","type":"address"},{"internalType":"uint256","name":"wishes","type":"uint256"}],"name":"Sell","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"wishes","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"usd","type":"uint256"},{"internalType":"uint256","name":"decimal","type":"uint256"}],"name":"convert18To6","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"decimal","type":"uint256"}],"name":"convert6To18","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","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":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWishFundationAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isUSD","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stableTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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"}]

60806040523480156200001157600080fd5b506040516200291d3803806200291d8339810160408190526200003491620001e4565b6040805180820182526004808252630ae92a6960e31b602080840182815285518087019096529285528401528151919291620000739160039162000121565b5080516200008990600490602084019062000121565b5050506001600160a01b0397881660009081526005602081815260408084208054600160ff19918216811790925560068085528387209d909d559a8d16855283835281852080548c16821790558b835281852099909955968b16835281815286832080548a168917905589815286832095909555929098168852908252828720805490951690931790935592909152912055620002a5565b8280546200012f9062000268565b90600052602060002090601f0160209004810192826200015357600085556200019e565b82601f106200016e57805160ff19168380011785556200019e565b828001600101855582156200019e579182015b828111156200019e57825182559160200191906001019062000181565b50620001ac929150620001b0565b5090565b5b80821115620001ac5760008155600101620001b1565b80516001600160a01b0381168114620001df57600080fd5b919050565b600080600080600080600080610100898b0312156200020257600080fd5b6200020d89620001c7565b9750602089015196506200022460408a01620001c7565b9550606089015194506200023b60808a01620001c7565b935060a089015192506200025260c08a01620001c7565b915060e089015190509295985092959890939650565b600181811c908216806200027d57607f821691505b602082108114156200029f57634e487b7160e01b600052602260045260246000fd5b50919050565b61266880620002b56000396000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c80635e5e995c116100d8578063a457c2d71161008c578063dd62ed3e11610066578063dd62ed3e1461033d578063e3d4187f14610383578063f0848c041461039657600080fd5b8063a457c2d7146102f7578063a9059cbb1461030a578063b09d5a501461031d57600080fd5b8063790ca413116100bd578063790ca413146102dc57806395d89b41146102e757806398d5fdca146102ef57600080fd5b80635e5e995c1461029357806370a08231146102a657600080fd5b806323b872dd1161013a578063395093511161011457806339509351146102585780633e7111091461026b57806342966c681461027e57600080fd5b806323b872dd1461021457806326f968bb14610227578063313ce5671461024957600080fd5b80630fbab74b1161016b5780630fbab74b146101c857806318160ddd146101e9578063231ade9d146101f157600080fd5b806306fdde0314610187578063095ea7b3146101a5575b600080fd5b61018f6103a1565b60405161019c919061245c565b60405180910390f35b6101b86101b33660046123b9565b610433565b604051901515815260200161019c565b6101db6101d636600461241e565b61044d565b60405190815260200161019c565b6002546101db565b6101b86101ff36600461232f565b60056020526000908152604090205460ff1681565b6101b861022236600461237d565b610475565b60405173709d83004eb79cf752b5d4f021d3652c97ad1561815260200161019c565b6040516012815260200161019c565b6101b86102663660046123b9565b610499565b6101db61027936600461241e565b6104e5565b61029161028c366004612405565b6104ff565b005b6101b86102a13660046123b9565b61050c565b6101db6102b436600461232f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101db636405d5c081565b61018f610692565b6101db6106a1565b6101b86103053660046123b9565b610757565b6101b86103183660046123b9565b610828565b6101db61032b36600461232f565b60066020526000908152604090205481565b6101db61034b36600461234a565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101b86103913660046123b9565b610836565b6101db63769bd95081565b6060600380546103b090612580565b80601f01602080910402602001604051908101604052809291908181526020018280546103dc90612580565b80156104295780601f106103fe57610100808354040283529160200191610429565b820191906000526020600020905b81548152906001019060200180831161040c57829003601f168201915b5050505050905090565b6000336104418185856109ab565b60019150505b92915050565b6000816006141561046e576104678364e8d4a51000612500565b9050610447565b5090919050565b600033610483858285610b5f565b61048e858585610c36565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061044190829086906104e09087906124ad565b6109ab565b6000816006141561046e5761046764e8d4a51000846124c5565b6105093382610ea5565b50565b73ffffffffffffffffffffffffffffffffffffffff821660009081526005602052604081205460ff166105a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f555344204552524f52000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6105aa3383610ea5565b6000670de0b6b3a76400006105bd6106a1565b6105c79085612500565b6105d191906124c5565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600660205260409020549091506106059082906104e5565b90506000600a610616836002612500565b61062091906124c5565b9050600061062e828461253d565b905061066573ffffffffffffffffffffffffffffffffffffffff871673709d83004eb79cf752b5d4f021d3652c97ad156184611066565b61068673ffffffffffffffffffffffffffffffffffffffff87163383611066565b50600195945050505050565b6060600480546103b090612580565b600080636405d5c042116106bb576402540be40091505090565b63769bd95042106106d557670de0b6c140e9ed9091505090565b6106e3636405d5c04261253d565b905060006107086106f76303d71a6d61113a565b6107036298968061113a565b611158565b905060006107256107188461113a565b6107036301e1338061113a565b905061074f61074461073f8361073a866111d9565b6112db565b611332565b6402540be400611e1b565b935050505090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561081b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610597565b61048e82868684036109ab565b600033610441818585610c36565b73ffffffffffffffffffffffffffffffffffffffff821660009081526005602052604081205460ff166108c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f555344204552524f5200000000000000000000000000000000000000000000006044820152606401610597565b600060646108d4846005612500565b6108de91906124c5565b905060006108ec828561253d565b905061092473ffffffffffffffffffffffffffffffffffffffff86163373709d83004eb79cf752b5d4f021d3652c97ad156185611e9d565b61094673ffffffffffffffffffffffffffffffffffffffff8616333084611e9d565b73ffffffffffffffffffffffffffffffffffffffff851660009081526006602052604090205461097790829061044d565b905060006109836106a1565b61099583670de0b6b3a7640000612500565b61099f91906124c5565b90506106863382611efb565b73ffffffffffffffffffffffffffffffffffffffff8316610a4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff8216610af0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c305781811015610c23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610597565b610c3084848484036109ab565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff8216610d7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610c30565b73ffffffffffffffffffffffffffffffffffffffff8216610f48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610ffe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610b52565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526110619084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611fee565b6000677fffffffffffffff82111561115157600080fd5b5060401b90565b600081600f0b6000141561116b57600080fd5b600082600f0b604085600f0b901b8161118657611186612603565b0590507fffffffffffffffffffffffffffffffff8000000000000000000000000000000081128015906111c957506f7fffffffffffffffffffffffffffffff8113155b6111d257600080fd5b9392505050565b60008082600f0b136111ea57600080fd5b6000600f83900b680100000000000000008112611209576040918201911d5b640100000000811261121d576020918201911d5b62010000811261122f576010918201911d5b6101008112611240576008918201911d5b60108112611250576004918201911d5b60048112611260576002918201911d5b6002811261126f576001820191505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0820160401b600f85900b607f8490031b6780000000000000005b60008113156112d05790800260ff81901c8281029390930192607f011c9060011d6112aa565b509095945050505050565b6000600f83810b9083900b0260401d7fffffffffffffffffffffffffffffffff8000000000000000000000000000000081128015906111c957506f7fffffffffffffffffffffffffffffff8113156111d257600080fd5b60006840000000000000000082600f0b1261134c57600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000082600f0b121561137f57506000919050565b6f8000000000000000000000000000000060006780000000000000008416600f0b13156113bd5770016a09e667f3bcc908b2fb1366ea957d3e0260801c5b60008367400000000000000016600f0b13156113ea577001306fe0a31b7152de8d5a46305c85edec0260801c5b60008367200000000000000016600f0b1315611417577001172b83c7d517adcdf7c8c50eb14a791f0260801c5b60008367100000000000000016600f0b13156114445770010b5586cf9890f6298b92b71842a983630260801c5b60008367080000000000000016600f0b1315611471577001059b0d31585743ae7c548eb68ca417fd0260801c5b60008367040000000000000016600f0b131561149e57700102c9a3e778060ee6f7caca4f7a29bde80260801c5b60008367020000000000000016600f0b13156114cb5770010163da9fb33356d84a66ae336dcdfa3f0260801c5b60008367010000000000000016600f0b13156114f857700100b1afa5abcbed6129ab13ec11dc95430260801c5b600083668000000000000016600f0b13156115245770010058c86da1c09ea1ff19d294cf2f679b0260801c5b600083664000000000000016600f0b1315611550577001002c605e2e8cec506d21bfc89a23a00f0260801c5b600083662000000000000016600f0b131561157c57700100162f3904051fa128bca9c55c31e5df0260801c5b600083661000000000000016600f0b13156115a8577001000b175effdc76ba38e31671ca9397250260801c5b600083660800000000000016600f0b13156115d457700100058ba01fb9f96d6cacd4b180917c3d0260801c5b600083660400000000000016600f0b13156116005770010002c5cc37da9491d0985c348c68e7b30260801c5b600083660200000000000016600f0b131561162c577001000162e525ee054754457d59952920260260801c5b600083660100000000000016600f0b13156116585770010000b17255775c040618bf4a4ade83fc0260801c5b6000836580000000000016600f0b1315611683577001000058b91b5bc9ae2eed81e9b7d4cfab0260801c5b6000836540000000000016600f0b13156116ae57700100002c5c89d5ec6ca4d7c8acc017b7c90260801c5b6000836520000000000016600f0b13156116d95770010000162e43f4f831060e02d839a9d16d0260801c5b6000836510000000000016600f0b131561170457700100000b1721bcfc99d9f890ea069117630260801c5b6000836508000000000016600f0b131561172f5770010000058b90cf1e6d97f9ca14dbcc16280260801c5b6000836504000000000016600f0b131561175a577001000002c5c863b73f016468f6bac5ca2b0260801c5b6000836502000000000016600f0b131561178557700100000162e430e5a18f6119e3c02282a50260801c5b6000836501000000000016600f0b13156117b0577001000000b1721835514b86e6d96efd1bfe0260801c5b60008364800000000016600f0b13156117da57700100000058b90c0b48c6be5df846c5b2ef0260801c5b60008364400000000016600f0b13156118045770010000002c5c8601cc6b9e94213c72737a0260801c5b60008364200000000016600f0b131561182e577001000000162e42fff037df38aa2b219f060260801c5b60008364100000000016600f0b13156118585770010000000b17217fba9c739aa5819f44f90260801c5b60008364080000000016600f0b1315611882577001000000058b90bfcdee5acd3c1cedc8230260801c5b60008364040000000016600f0b13156118ac57700100000002c5c85fe31f35a6a30da1be500260801c5b60008364020000000016600f0b13156118d65770010000000162e42ff0999ce3541b9fffcf0260801c5b60008364010000000016600f0b131561190057700100000000b17217f80f4ef5aadda455540260801c5b600083638000000016600f0b13156119295770010000000058b90bfbf8479bd5a81b51ad0260801c5b600083634000000016600f0b1315611952577001000000002c5c85fdf84bd62ae30a74cc0260801c5b600083632000000016600f0b131561197b57700100000000162e42fefb2fed257559bdaa0260801c5b600083631000000016600f0b13156119a4577001000000000b17217f7d5a7716bba4a9ae0260801c5b600083630800000016600f0b13156119cd57700100000000058b90bfbe9ddbac5e109cce0260801c5b600083630400000016600f0b13156119f65770010000000002c5c85fdf4b15de6f17eb0d0260801c5b600083630200000016600f0b1315611a1f577001000000000162e42fefa494f1478fde050260801c5b600083630100000016600f0b1315611a485770010000000000b17217f7d20cf927c8e94c0260801c5b6000836280000016600f0b1315611a70577001000000000058b90bfbe8f71cb4e4b33d0260801c5b6000836240000016600f0b1315611a9857700100000000002c5c85fdf477b662b269450260801c5b6000836220000016600f0b1315611ac05770010000000000162e42fefa3ae53369388c0260801c5b6000836210000016600f0b1315611ae857700100000000000b17217f7d1d351a389d400260801c5b6000836208000016600f0b1315611b105770010000000000058b90bfbe8e8b2d3d4ede0260801c5b6000836204000016600f0b1315611b38577001000000000002c5c85fdf4741bea6e77e0260801c5b6000836202000016600f0b1315611b6057700100000000000162e42fefa39fe95583c20260801c5b6000836201000016600f0b1315611b88577001000000000000b17217f7d1cfb72b45e10260801c5b60008361800016600f0b1315611baf57700100000000000058b90bfbe8e7cc35c3f00260801c5b60008361400016600f0b1315611bd65770010000000000002c5c85fdf473e242ea380260801c5b60008361200016600f0b1315611bfd577001000000000000162e42fefa39f02b772c0260801c5b60008361100016600f0b1315611c245770010000000000000b17217f7d1cf7d83c1a0260801c5b60008361080016600f0b1315611c4b577001000000000000058b90bfbe8e7bdcbe2e0260801c5b60008361040016600f0b1315611c7257700100000000000002c5c85fdf473dea871f0260801c5b60008361020016600f0b1315611c995770010000000000000162e42fefa39ef44d910260801c5b60008361010016600f0b1315611cc057700100000000000000b17217f7d1cf79e9490260801c5b600083608016600f0b1315611ce65770010000000000000058b90bfbe8e7bce5440260801c5b600083604016600f0b1315611d0c577001000000000000002c5c85fdf473de6eca0260801c5b600083602016600f0b1315611d3257700100000000000000162e42fefa39ef366f0260801c5b600083601016600f0b1315611d58577001000000000000000b17217f7d1cf79afa0260801c5b600083600816600f0b1315611d7e57700100000000000000058b90bfbe8e7bcd6d0260801c5b600083600416600f0b1315611da45770010000000000000002c5c85fdf473de6b20260801c5b600083600216600f0b1315611dca577001000000000000000162e42fefa39ef3580260801c5b600083600116600f0b1315611df05770010000000000000000b17217f7d1cf79ab0260801c5b600f83810b60401d603f03900b1c6f7fffffffffffffffffffffffffffffff81111561044757600080fd5b600081611e2a57506000610447565b600083600f0b1215611e3b57600080fd5b600f83900b6fffffffffffffffffffffffffffffffff8316810260401c90608084901c0277ffffffffffffffffffffffffffffffffffffffffffffffff811115611e8457600080fd5b60401b8119811115611e9557600080fd5b019392505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610c309085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016110b8565b73ffffffffffffffffffffffffffffffffffffffff8216611f78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610597565b8060026000828254611f8a91906124ad565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000612050826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166120fa9092919063ffffffff16565b805190915015611061578080602001905181019061206e91906123e3565b611061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610597565b60606121098484600085612111565b949350505050565b6060824710156121a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610597565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516121cc9190612440565b60006040518083038185875af1925050503d8060008114612209576040519150601f19603f3d011682016040523d82523d6000602084013e61220e565b606091505b509150915061221f8783838761222a565b979650505050505050565b606083156122bd5782516122b65773ffffffffffffffffffffffffffffffffffffffff85163b6122b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610597565b5081612109565b61210983838151156122d25781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610597919061245c565b803573ffffffffffffffffffffffffffffffffffffffff8116811461232a57600080fd5b919050565b60006020828403121561234157600080fd5b6111d282612306565b6000806040838503121561235d57600080fd5b61236683612306565b915061237460208401612306565b90509250929050565b60008060006060848603121561239257600080fd5b61239b84612306565b92506123a960208501612306565b9150604084013590509250925092565b600080604083850312156123cc57600080fd5b6123d583612306565b946020939093013593505050565b6000602082840312156123f557600080fd5b815180151581146111d257600080fd5b60006020828403121561241757600080fd5b5035919050565b6000806040838503121561243157600080fd5b50508035926020909101359150565b60008251612452818460208701612554565b9190910192915050565b602081526000825180602084015261247b816040850160208701612554565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600082198211156124c0576124c06125d4565b500190565b6000826124fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612538576125386125d4565b500290565b60008282101561254f5761254f6125d4565b500390565b60005b8381101561256f578181015183820152602001612557565b83811115610c305750506000910152565b600181811c9082168061259457607f821691505b602082108114156125ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea26469706673582212208ee9f364e952dda9098e7abc216259292915971b45c828b40123c1fb0a51283d64736f6c63430008060033000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000000000000000000000000000000000000000000006000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000060000000000000000000000004fabb145d64652a948d72533023f6e7a623c7c5300000000000000000000000000000000000000000000000000000000000000120000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000012

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101825760003560e01c80635e5e995c116100d8578063a457c2d71161008c578063dd62ed3e11610066578063dd62ed3e1461033d578063e3d4187f14610383578063f0848c041461039657600080fd5b8063a457c2d7146102f7578063a9059cbb1461030a578063b09d5a501461031d57600080fd5b8063790ca413116100bd578063790ca413146102dc57806395d89b41146102e757806398d5fdca146102ef57600080fd5b80635e5e995c1461029357806370a08231146102a657600080fd5b806323b872dd1161013a578063395093511161011457806339509351146102585780633e7111091461026b57806342966c681461027e57600080fd5b806323b872dd1461021457806326f968bb14610227578063313ce5671461024957600080fd5b80630fbab74b1161016b5780630fbab74b146101c857806318160ddd146101e9578063231ade9d146101f157600080fd5b806306fdde0314610187578063095ea7b3146101a5575b600080fd5b61018f6103a1565b60405161019c919061245c565b60405180910390f35b6101b86101b33660046123b9565b610433565b604051901515815260200161019c565b6101db6101d636600461241e565b61044d565b60405190815260200161019c565b6002546101db565b6101b86101ff36600461232f565b60056020526000908152604090205460ff1681565b6101b861022236600461237d565b610475565b60405173709d83004eb79cf752b5d4f021d3652c97ad1561815260200161019c565b6040516012815260200161019c565b6101b86102663660046123b9565b610499565b6101db61027936600461241e565b6104e5565b61029161028c366004612405565b6104ff565b005b6101b86102a13660046123b9565b61050c565b6101db6102b436600461232f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101db636405d5c081565b61018f610692565b6101db6106a1565b6101b86103053660046123b9565b610757565b6101b86103183660046123b9565b610828565b6101db61032b36600461232f565b60066020526000908152604090205481565b6101db61034b36600461234a565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101b86103913660046123b9565b610836565b6101db63769bd95081565b6060600380546103b090612580565b80601f01602080910402602001604051908101604052809291908181526020018280546103dc90612580565b80156104295780601f106103fe57610100808354040283529160200191610429565b820191906000526020600020905b81548152906001019060200180831161040c57829003601f168201915b5050505050905090565b6000336104418185856109ab565b60019150505b92915050565b6000816006141561046e576104678364e8d4a51000612500565b9050610447565b5090919050565b600033610483858285610b5f565b61048e858585610c36565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061044190829086906104e09087906124ad565b6109ab565b6000816006141561046e5761046764e8d4a51000846124c5565b6105093382610ea5565b50565b73ffffffffffffffffffffffffffffffffffffffff821660009081526005602052604081205460ff166105a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f555344204552524f52000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6105aa3383610ea5565b6000670de0b6b3a76400006105bd6106a1565b6105c79085612500565b6105d191906124c5565b73ffffffffffffffffffffffffffffffffffffffff85166000908152600660205260409020549091506106059082906104e5565b90506000600a610616836002612500565b61062091906124c5565b9050600061062e828461253d565b905061066573ffffffffffffffffffffffffffffffffffffffff871673709d83004eb79cf752b5d4f021d3652c97ad156184611066565b61068673ffffffffffffffffffffffffffffffffffffffff87163383611066565b50600195945050505050565b6060600480546103b090612580565b600080636405d5c042116106bb576402540be40091505090565b63769bd95042106106d557670de0b6c140e9ed9091505090565b6106e3636405d5c04261253d565b905060006107086106f76303d71a6d61113a565b6107036298968061113a565b611158565b905060006107256107188461113a565b6107036301e1338061113a565b905061074f61074461073f8361073a866111d9565b6112db565b611332565b6402540be400611e1b565b935050505090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091908381101561081b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610597565b61048e82868684036109ab565b600033610441818585610c36565b73ffffffffffffffffffffffffffffffffffffffff821660009081526005602052604081205460ff166108c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f555344204552524f5200000000000000000000000000000000000000000000006044820152606401610597565b600060646108d4846005612500565b6108de91906124c5565b905060006108ec828561253d565b905061092473ffffffffffffffffffffffffffffffffffffffff86163373709d83004eb79cf752b5d4f021d3652c97ad156185611e9d565b61094673ffffffffffffffffffffffffffffffffffffffff8616333084611e9d565b73ffffffffffffffffffffffffffffffffffffffff851660009081526006602052604090205461097790829061044d565b905060006109836106a1565b61099583670de0b6b3a7640000612500565b61099f91906124c5565b90506106863382611efb565b73ffffffffffffffffffffffffffffffffffffffff8316610a4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff8216610af0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610c305781811015610c23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610597565b610c3084848484036109ab565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610cd9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff8216610d7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610e32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610c30565b73ffffffffffffffffffffffffffffffffffffffff8216610f48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610ffe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610597565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610b52565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526110619084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611fee565b6000677fffffffffffffff82111561115157600080fd5b5060401b90565b600081600f0b6000141561116b57600080fd5b600082600f0b604085600f0b901b8161118657611186612603565b0590507fffffffffffffffffffffffffffffffff8000000000000000000000000000000081128015906111c957506f7fffffffffffffffffffffffffffffff8113155b6111d257600080fd5b9392505050565b60008082600f0b136111ea57600080fd5b6000600f83900b680100000000000000008112611209576040918201911d5b640100000000811261121d576020918201911d5b62010000811261122f576010918201911d5b6101008112611240576008918201911d5b60108112611250576004918201911d5b60048112611260576002918201911d5b6002811261126f576001820191505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0820160401b600f85900b607f8490031b6780000000000000005b60008113156112d05790800260ff81901c8281029390930192607f011c9060011d6112aa565b509095945050505050565b6000600f83810b9083900b0260401d7fffffffffffffffffffffffffffffffff8000000000000000000000000000000081128015906111c957506f7fffffffffffffffffffffffffffffff8113156111d257600080fd5b60006840000000000000000082600f0b1261134c57600080fd5b7fffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000082600f0b121561137f57506000919050565b6f8000000000000000000000000000000060006780000000000000008416600f0b13156113bd5770016a09e667f3bcc908b2fb1366ea957d3e0260801c5b60008367400000000000000016600f0b13156113ea577001306fe0a31b7152de8d5a46305c85edec0260801c5b60008367200000000000000016600f0b1315611417577001172b83c7d517adcdf7c8c50eb14a791f0260801c5b60008367100000000000000016600f0b13156114445770010b5586cf9890f6298b92b71842a983630260801c5b60008367080000000000000016600f0b1315611471577001059b0d31585743ae7c548eb68ca417fd0260801c5b60008367040000000000000016600f0b131561149e57700102c9a3e778060ee6f7caca4f7a29bde80260801c5b60008367020000000000000016600f0b13156114cb5770010163da9fb33356d84a66ae336dcdfa3f0260801c5b60008367010000000000000016600f0b13156114f857700100b1afa5abcbed6129ab13ec11dc95430260801c5b600083668000000000000016600f0b13156115245770010058c86da1c09ea1ff19d294cf2f679b0260801c5b600083664000000000000016600f0b1315611550577001002c605e2e8cec506d21bfc89a23a00f0260801c5b600083662000000000000016600f0b131561157c57700100162f3904051fa128bca9c55c31e5df0260801c5b600083661000000000000016600f0b13156115a8577001000b175effdc76ba38e31671ca9397250260801c5b600083660800000000000016600f0b13156115d457700100058ba01fb9f96d6cacd4b180917c3d0260801c5b600083660400000000000016600f0b13156116005770010002c5cc37da9491d0985c348c68e7b30260801c5b600083660200000000000016600f0b131561162c577001000162e525ee054754457d59952920260260801c5b600083660100000000000016600f0b13156116585770010000b17255775c040618bf4a4ade83fc0260801c5b6000836580000000000016600f0b1315611683577001000058b91b5bc9ae2eed81e9b7d4cfab0260801c5b6000836540000000000016600f0b13156116ae57700100002c5c89d5ec6ca4d7c8acc017b7c90260801c5b6000836520000000000016600f0b13156116d95770010000162e43f4f831060e02d839a9d16d0260801c5b6000836510000000000016600f0b131561170457700100000b1721bcfc99d9f890ea069117630260801c5b6000836508000000000016600f0b131561172f5770010000058b90cf1e6d97f9ca14dbcc16280260801c5b6000836504000000000016600f0b131561175a577001000002c5c863b73f016468f6bac5ca2b0260801c5b6000836502000000000016600f0b131561178557700100000162e430e5a18f6119e3c02282a50260801c5b6000836501000000000016600f0b13156117b0577001000000b1721835514b86e6d96efd1bfe0260801c5b60008364800000000016600f0b13156117da57700100000058b90c0b48c6be5df846c5b2ef0260801c5b60008364400000000016600f0b13156118045770010000002c5c8601cc6b9e94213c72737a0260801c5b60008364200000000016600f0b131561182e577001000000162e42fff037df38aa2b219f060260801c5b60008364100000000016600f0b13156118585770010000000b17217fba9c739aa5819f44f90260801c5b60008364080000000016600f0b1315611882577001000000058b90bfcdee5acd3c1cedc8230260801c5b60008364040000000016600f0b13156118ac57700100000002c5c85fe31f35a6a30da1be500260801c5b60008364020000000016600f0b13156118d65770010000000162e42ff0999ce3541b9fffcf0260801c5b60008364010000000016600f0b131561190057700100000000b17217f80f4ef5aadda455540260801c5b600083638000000016600f0b13156119295770010000000058b90bfbf8479bd5a81b51ad0260801c5b600083634000000016600f0b1315611952577001000000002c5c85fdf84bd62ae30a74cc0260801c5b600083632000000016600f0b131561197b57700100000000162e42fefb2fed257559bdaa0260801c5b600083631000000016600f0b13156119a4577001000000000b17217f7d5a7716bba4a9ae0260801c5b600083630800000016600f0b13156119cd57700100000000058b90bfbe9ddbac5e109cce0260801c5b600083630400000016600f0b13156119f65770010000000002c5c85fdf4b15de6f17eb0d0260801c5b600083630200000016600f0b1315611a1f577001000000000162e42fefa494f1478fde050260801c5b600083630100000016600f0b1315611a485770010000000000b17217f7d20cf927c8e94c0260801c5b6000836280000016600f0b1315611a70577001000000000058b90bfbe8f71cb4e4b33d0260801c5b6000836240000016600f0b1315611a9857700100000000002c5c85fdf477b662b269450260801c5b6000836220000016600f0b1315611ac05770010000000000162e42fefa3ae53369388c0260801c5b6000836210000016600f0b1315611ae857700100000000000b17217f7d1d351a389d400260801c5b6000836208000016600f0b1315611b105770010000000000058b90bfbe8e8b2d3d4ede0260801c5b6000836204000016600f0b1315611b38577001000000000002c5c85fdf4741bea6e77e0260801c5b6000836202000016600f0b1315611b6057700100000000000162e42fefa39fe95583c20260801c5b6000836201000016600f0b1315611b88577001000000000000b17217f7d1cfb72b45e10260801c5b60008361800016600f0b1315611baf57700100000000000058b90bfbe8e7cc35c3f00260801c5b60008361400016600f0b1315611bd65770010000000000002c5c85fdf473e242ea380260801c5b60008361200016600f0b1315611bfd577001000000000000162e42fefa39f02b772c0260801c5b60008361100016600f0b1315611c245770010000000000000b17217f7d1cf7d83c1a0260801c5b60008361080016600f0b1315611c4b577001000000000000058b90bfbe8e7bdcbe2e0260801c5b60008361040016600f0b1315611c7257700100000000000002c5c85fdf473dea871f0260801c5b60008361020016600f0b1315611c995770010000000000000162e42fefa39ef44d910260801c5b60008361010016600f0b1315611cc057700100000000000000b17217f7d1cf79e9490260801c5b600083608016600f0b1315611ce65770010000000000000058b90bfbe8e7bce5440260801c5b600083604016600f0b1315611d0c577001000000000000002c5c85fdf473de6eca0260801c5b600083602016600f0b1315611d3257700100000000000000162e42fefa39ef366f0260801c5b600083601016600f0b1315611d58577001000000000000000b17217f7d1cf79afa0260801c5b600083600816600f0b1315611d7e57700100000000000000058b90bfbe8e7bcd6d0260801c5b600083600416600f0b1315611da45770010000000000000002c5c85fdf473de6b20260801c5b600083600216600f0b1315611dca577001000000000000000162e42fefa39ef3580260801c5b600083600116600f0b1315611df05770010000000000000000b17217f7d1cf79ab0260801c5b600f83810b60401d603f03900b1c6f7fffffffffffffffffffffffffffffff81111561044757600080fd5b600081611e2a57506000610447565b600083600f0b1215611e3b57600080fd5b600f83900b6fffffffffffffffffffffffffffffffff8316810260401c90608084901c0277ffffffffffffffffffffffffffffffffffffffffffffffff811115611e8457600080fd5b60401b8119811115611e9557600080fd5b019392505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052610c309085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016110b8565b73ffffffffffffffffffffffffffffffffffffffff8216611f78576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610597565b8060026000828254611f8a91906124ad565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6000612050826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166120fa9092919063ffffffff16565b805190915015611061578080602001905181019061206e91906123e3565b611061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610597565b60606121098484600085612111565b949350505050565b6060824710156121a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610597565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516121cc9190612440565b60006040518083038185875af1925050503d8060008114612209576040519150601f19603f3d011682016040523d82523d6000602084013e61220e565b606091505b509150915061221f8783838761222a565b979650505050505050565b606083156122bd5782516122b65773ffffffffffffffffffffffffffffffffffffffff85163b6122b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610597565b5081612109565b61210983838151156122d25781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610597919061245c565b803573ffffffffffffffffffffffffffffffffffffffff8116811461232a57600080fd5b919050565b60006020828403121561234157600080fd5b6111d282612306565b6000806040838503121561235d57600080fd5b61236683612306565b915061237460208401612306565b90509250929050565b60008060006060848603121561239257600080fd5b61239b84612306565b92506123a960208501612306565b9150604084013590509250925092565b600080604083850312156123cc57600080fd5b6123d583612306565b946020939093013593505050565b6000602082840312156123f557600080fd5b815180151581146111d257600080fd5b60006020828403121561241757600080fd5b5035919050565b6000806040838503121561243157600080fd5b50508035926020909101359150565b60008251612452818460208701612554565b9190910192915050565b602081526000825180602084015261247b816040850160208701612554565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600082198211156124c0576124c06125d4565b500190565b6000826124fb577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612538576125386125d4565b500290565b60008282101561254f5761254f6125d4565b500390565b60005b8381101561256f578181015183820152602001612557565b83811115610c305750506000910152565b600181811c9082168061259457607f821691505b602082108114156125ce577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea26469706673582212208ee9f364e952dda9098e7abc216259292915971b45c828b40123c1fb0a51283d64736f6c63430008060033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000000000000000000000000000000000000000000006000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000060000000000000000000000004fabb145d64652a948d72533023f6e7a623c7c5300000000000000000000000000000000000000000000000000000000000000120000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000012

-----Decoded View---------------
Arg [0] : usdt (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [1] : usdtDecimal (uint256): 6
Arg [2] : usdc (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [3] : usdcDecimal (uint256): 6
Arg [4] : busd (address): 0x4Fabb145d64652a948d72533023f6E7A623C7C53
Arg [5] : busdDecimal (uint256): 18
Arg [6] : dai (address): 0x6B175474E89094C44Da98b954EedeAC495271d0F
Arg [7] : daiDecimal (uint256): 18

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [2] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [4] : 0000000000000000000000004fabb145d64652a948d72533023f6e7a623c7c53
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [6] : 0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000012


Deployed Bytecode Sourcemap

61568:4172:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46525:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;48876:201;;;;;;:::i;:::-;;:::i;:::-;;;3363:14:1;;3356:22;3338:41;;3326:2;3311:18;48876:201:0;3293:92:1;62682:200:0;;;;;;:::i;:::-;;:::i;:::-;;;9450:25:1;;;9438:2;9423:18;62682:200:0;9405:76:1;47645:108:0;47733:12;;47645:108;;61758:37;;;;;;:::i;:::-;;;;;;;;;;;;;;;;49657:295;;;;;;:::i;:::-;;:::i;63089:108::-;;;62094:42;2408:74:1;;2396:2;2381:18;63089:108:0;2363:125:1;47487:93:0;;;47570:2;9628:36:1;;9616:2;9601:18;47487:93:0;9583:87:1;50361:238:0;;;;;;:::i;:::-;;:::i;62890:191::-;;;;;;:::i;:::-;;:::i;65654:83::-;;;;;;:::i;:::-;;:::i;:::-;;65124:522;;;;;;:::i;:::-;;:::i;47816:127::-;;;;;;:::i;:::-;47917:18;;47890:7;47917:18;;;;;;;;;;;;47816:127;61852:47;;61889:10;61852:47;;46744:104;;;:::i;63348:1143::-;;;:::i;51102:436::-;;;;;;:::i;:::-;;:::i;48149:193::-;;;;;;:::i;:::-;;:::i;61802:43::-;;;;;;:::i;:::-;;;;;;;;;;;;;;48405:151;;;;;;:::i;:::-;48521:18;;;;48494:7;48521:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;48405:151;64499:617;;;;;;:::i;:::-;;:::i;61946:47::-;;61983:10;61946:47;;46525:100;46579:13;46612:5;46605:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46525:100;:::o;48876:201::-;48959:4;31638:10;49015:32;31638:10;49031:7;49040:6;49015:8;:32::i;:::-;49065:4;49058:11;;;48876:201;;;;;:::o;62682:200::-;62785:7;62814;62825:1;62814:12;62810:38;;;62835:13;:6;62844:4;62835:13;:::i;:::-;62828:20;;;;62810:38;-1:-1:-1;62868:6:0;;62682:200;-1:-1:-1;62682:200:0:o;49657:295::-;49788:4;31638:10;49846:38;49862:4;31638:10;49877:6;49846:15;:38::i;:::-;49895:27;49905:4;49911:2;49915:6;49895:9;:27::i;:::-;-1:-1:-1;49940:4:0;;49657:295;-1:-1:-1;;;;49657:295:0:o;50361:238::-;31638:10;50449:4;48521:18;;;:11;:18;;;;;;;;;:27;;;;;;;;;;50449:4;;31638:10;50505:64;;31638:10;;48521:27;;50530:38;;50558:10;;50530:38;:::i;:::-;50505:8;:64::i;62890:191::-;62990:7;63019;63030:1;63019:12;63015:35;;;63040:10;63046:4;63040:3;:10;:::i;65654:83::-;65704:25;65710:10;65722:6;65704:5;:25::i;:::-;65654:83;:::o;65124:522::-;65210:10;;;65185:4;65210:10;;;:5;:10;;;;;;;;65202:32;;;;;;;4443:2:1;65202:32:0;;;4425:21:1;4482:1;4462:18;;;4455:29;4520:11;4500:18;;;4493:39;4549:18;;65202:32:0;;;;;;;;;65247:25;65253:10;65265:6;65247:5;:25::i;:::-;65285:12;65324:4;65310:10;:8;:10::i;:::-;65301:19;;:6;:19;:::i;:::-;65300:28;;;;:::i;:::-;65365:13;;;;;;;:8;:13;;;;;;65285:43;;-1:-1:-1;65346:33:0;;65285:43;;65346:12;:33::i;:::-;65339:40;-1:-1:-1;65390:22:0;65429:2;65417:8;65339:40;65424:1;65417:8;:::i;:::-;65416:15;;;;:::i;:::-;65390:42;-1:-1:-1;65443:15:0;65461:21;65390:42;65461:4;:21;:::i;:::-;65443:39;-1:-1:-1;65495:66:0;:23;;;62094:42;65546:14;65495:23;:66::i;:::-;65572:44;:23;;;65596:10;65608:7;65572:23;:44::i;:::-;-1:-1:-1;65634:4:0;;65124:522;-1:-1:-1;;;;;65124:522:0:o;46744:104::-;46800:13;46833:7;46826:14;;;;;:::i;63348:1143::-;63389:7;63409:16;61889:10;63442:15;:29;63438:53;;63480:11;63473:18;;;63348:1143;:::o;63438:53::-;61983:10;63566:15;:29;63562:61;;63604:19;63597:26;;;63348:1143;:::o;63562:61::-;63710:28;61889:10;63710:15;:28;:::i;:::-;63699:39;;63751:11;63765:122;63797:32;63820:8;63797:22;:32::i;:::-;63844;63867:8;63844:22;:32::i;:::-;63765:17;:122::i;:::-;63751:136;;63898:18;63919:122;63951:32;63974:8;63951:22;:32::i;:::-;63998;64021:8;63998:22;:32::i;63919:122::-;63898:143;;64290:193;64327:118;64369:57;64387:11;64400:25;64420:4;64400:19;:25::i;:::-;64369:17;:57::i;:::-;64327:19;:118::i;:::-;64464:4;64290:18;:193::i;:::-;64270:213;;;;;63348:1143;:::o;51102:436::-;31638:10;51195:4;48521:18;;;:11;:18;;;;;;;;;:27;;;;;;;;;;51195:4;;31638:10;51342:15;51322:16;:35;;51314:85;;;;;;;8740:2:1;51314:85:0;;;8722:21:1;8779:2;8759:18;;;8752:30;8818:34;8798:18;;;8791:62;8889:7;8869:18;;;8862:35;8914:19;;51314:85:0;8712:227:1;51314:85:0;51435:60;51444:5;51451:7;51479:15;51460:16;:34;51435:8;:60::i;48149:193::-;48228:4;31638:10;48284:28;31638:10;48301:2;48305:6;48284:9;:28::i;64499:617::-;64584:10;;;64559:4;64584:10;;;:5;:10;;;;;;;;64576:32;;;;;;;4443:2:1;64576:32:0;;;4425:21:1;4482:1;4462:18;;;4455:29;4520:11;4500:18;;;4493:39;4549:18;;64576:32:0;4415:158:1;64576:32:0;64619:22;64660:3;64646:10;:6;64655:1;64646:10;:::i;:::-;64645:18;;;;:::i;:::-;64619:45;-1:-1:-1;64675:14:0;64692:23;64619:45;64692:6;:23;:::i;:::-;64675:40;-1:-1:-1;64728:132:0;:27;;;64770:10;62094:42;64835:14;64728:27;:132::i;:::-;64871:62;:27;;;64899:10;64919:4;64926:6;64871:27;:62::i;:::-;64976:13;;;;;;;:8;:13;;;;;;64955:35;;64968:6;;64955:12;:35::i;:::-;64946:44;;65001:14;65036:10;:8;:10::i;:::-;65019:13;:6;65028:4;65019:13;:::i;:::-;65018:28;;;;:::i;:::-;65001:45;;65059:25;65065:10;65077:6;65059:5;:25::i;55129:380::-;55265:19;;;55257:68;;;;;;;7566:2:1;55257:68:0;;;7548:21:1;7605:2;7585:18;;;7578:30;7644:34;7624:18;;;7617:62;7715:6;7695:18;;;7688:34;7739:19;;55257:68:0;7538:226:1;55257:68:0;55344:21;;;55336:68;;;;;;;5183:2:1;55336:68:0;;;5165:21:1;5222:2;5202:18;;;5195:30;5261:34;5241:18;;;5234:62;5332:4;5312:18;;;5305:32;5354:19;;55336:68:0;5155:224:1;55336:68:0;55417:18;;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;55469:32;;9450:25:1;;;55469:32:0;;9423:18:1;55469:32:0;;;;;;;;55129:380;;;:::o;55800:453::-;48521:18;;;;55935:24;48521:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;56022:17;56002:37;;55998:248;;56084:6;56064:16;:26;;56056:68;;;;;;;5586:2:1;56056:68:0;;;5568:21:1;5625:2;5605:18;;;5598:30;5664:31;5644:18;;;5637:59;5713:18;;56056:68:0;5558:179:1;56056:68:0;56168:51;56177:5;56184:7;56212:6;56193:16;:25;56168:8;:51::i;:::-;55924:329;55800:453;;;:::o;52008:840::-;52139:18;;;52131:68;;;;;;;7160:2:1;52131:68:0;;;7142:21:1;7199:2;7179:18;;;7172:30;7238:34;7218:18;;;7211:62;7309:7;7289:18;;;7282:35;7334:19;;52131:68:0;7132:227:1;52131:68:0;52218:16;;;52210:64;;;;;;;4039:2:1;52210:64:0;;;4021:21:1;4078:2;4058:18;;;4051:30;4117:34;4097:18;;;4090:62;4188:5;4168:18;;;4161:33;4211:19;;52210:64:0;4011:225:1;52210:64:0;52360:15;;;52338:19;52360:15;;;;;;;;;;;52394:21;;;;52386:72;;;;;;;5944:2:1;52386:72:0;;;5926:21:1;5983:2;5963:18;;;5956:30;6022:34;6002:18;;;5995:62;6093:8;6073:18;;;6066:36;6119:19;;52386:72:0;5916:228:1;52386:72:0;52494:15;;;;:9;:15;;;;;;;;;;;52512:20;;;52494:38;;52712:13;;;;;;;;;;:23;;;;;;52764:26;;9450:25:1;;;52712:13:0;;52764:26;;9423:18:1;52764:26:0;;;;;;;52803:37;54016:675;;54100:21;;;54092:67;;;;;;;6758:2:1;54092:67:0;;;6740:21:1;6797:2;6777:18;;;6770:30;6836:34;6816:18;;;6809:62;6907:3;6887:18;;;6880:31;6928:19;;54092:67:0;6730:223:1;54092:67:0;54259:18;;;54234:22;54259:18;;;;;;;;;;;54296:24;;;;54288:71;;;;;;;4780:2:1;54288:71:0;;;4762:21:1;4819:2;4799:18;;;4792:30;4858:34;4838:18;;;4831:62;4929:4;4909:18;;;4902:32;4951:19;;54288:71:0;4752:224:1;54288:71:0;54395:18;;;:9;:18;;;;;;;;;;;54416:23;;;54395:44;;54534:12;:22;;;;;;;54585:37;9450:25:1;;;54395:9:0;;:18;54585:37;;9423:18:1;54585:37:0;9405:76:1;54635:48:0;54081:610;54016:675;;:::o;57774:211::-;57918:58;;3100:42:1;3088:55;;57918:58:0;;;3070:74:1;3160:18;;;3153:34;;;57891:86:0;;57911:5;;57941:23;;3043:18:1;;57918:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57891:19;:86::i;2113:192::-;2165:6;2222:18;2217:1;:23;;2209:32;;;;;;-1:-1:-1;2282:2:0;2277:7;;2113:192::o;8167:288::-;8223:6;8275:1;:6;;8280:1;8275:6;;8267:15;;;;;;8297:13;8333:1;8313:21;;8327:2;8321:1;8314:9;;:15;;8313:21;;;;;:::i;:::-;;;-1:-1:-1;831:35:0;8357:19;;;;;:42;;-1:-1:-1;996:34:0;8380:19;;;8357:42;8349:51;;;;;;8429:6;8167:288;-1:-1:-1;;;8167:288:0:o;16921:1271::-;16969:6;17025:1;17021;:5;;;17013:14;;;;;;17044:10;17073:13;;;;17111:19;17105:25;;17101:103;;17158:2;17179:9;;;;17151;17101:103;17228:11;17222:2;:17;17218:95;;17267:2;17288:9;;;;17260;17218:95;17337:7;17331:2;:13;17327:91;;17372:2;17393:9;;;;17365;17327:91;17442:5;17436:2;:11;17432:87;;17475:1;17495:8;;;;17468;17432:87;17543:4;17537:2;:10;17533:86;;17575:1;17595:8;;;;17568;17533:86;17643:3;17637:2;:9;17633:85;;17674:1;17694:8;;;;17667;17633:85;17742:3;17736:2;:9;17732:23;;17754:1;17747:8;;;;17732:23;17820:8;;;17833:2;17819:16;17871:9;;;;17893:3;:9;;;17863:40;17936:18;17918:218;17962:1;17956:3;:7;17918:218;;;17995:8;;;18040:3;18034:9;;;18105:15;;;18095:25;;;;;18069:3;:7;18062:14;;17973:1;17965:9;17918:218;;;-1:-1:-1;18166:6:0;;16921:1271;-1:-1:-1;;;;;16921:1271:0:o;4857:258::-;4913:6;4974:13;:9;;;:13;;;;;4992:2;4973:21;831:35;5017:19;;;;;:42;;-1:-1:-1;996:34:0;5040:19;;;5009:51;;;;;18959:8044;19007:6;19063:20;19059:1;:24;;;19051:33;;;;;;19121:21;19117:1;:25;;;19113:39;;;-1:-1:-1;19151:1:0;;18959:8044;-1:-1:-1;18959:8044:0:o;19113:39::-;19199:34;19182:14;19258:18;19254:22;;:26;;;19250:111;;;19318:35;19309:44;19358:3;19308:53;19250:111;19405:1;19380;19384:18;19380:22;:26;;;19376:111;;;19444:35;19435:44;19484:3;19434:53;19376:111;19531:1;19506;19510:18;19506:22;:26;;;19502:111;;;19570:35;19561:44;19610:3;19560:53;19502:111;19657:1;19632;19636:18;19632:22;:26;;;19628:111;;;19696:35;19687:44;19736:3;19686:53;19628:111;19782:1;19758;19762:17;19758:21;:25;;;19754:110;;;19821:35;19812:44;19861:3;19811:53;19754:110;19907:1;19883;19887:17;19883:21;:25;;;19879:110;;;19946:35;19937:44;19986:3;19936:53;19879:110;20032:1;20008;20012:17;20008:21;:25;;;20004:110;;;20071:35;20062:44;20111:3;20061:53;20004:110;20157:1;20133;20137:17;20133:21;:25;;;20129:110;;;20196:35;20187:44;20236:3;20186:53;20129:110;20281:1;20258;20262:16;20258:20;:24;;;20254:109;;;20320:35;20311:44;20360:3;20310:53;20254:109;20405:1;20382;20386:16;20382:20;:24;;;20378:109;;;20444:35;20435:44;20484:3;20434:53;20378:109;20529:1;20506;20510:16;20506:20;:24;;;20502:109;;;20568:35;20559:44;20608:3;20558:53;20502:109;20653:1;20630;20634:16;20630:20;:24;;;20626:109;;;20692:35;20683:44;20732:3;20682:53;20626:109;20776:1;20754;20758:15;20754:19;:23;;;20750:108;;;20815:35;20806:44;20855:3;20805:53;20750:108;20899:1;20877;20881:15;20877:19;:23;;;20873:108;;;20938:35;20929:44;20978:3;20928:53;20873:108;21022:1;21000;21004:15;21000:19;:23;;;20996:108;;;21061:35;21052:44;21101:3;21051:53;20996:108;21145:1;21123;21127:15;21123:19;:23;;;21119:108;;;21184:35;21175:44;21224:3;21174:53;21119:108;21267:1;21246;21250:14;21246:18;:22;;;21242:107;;;21306:35;21297:44;21346:3;21296:53;21242:107;21389:1;21368;21372:14;21368:18;:22;;;21364:107;;;21428:35;21419:44;21468:3;21418:53;21364:107;21511:1;21490;21494:14;21490:18;:22;;;21486:107;;;21550:35;21541:44;21590:3;21540:53;21486:107;21633:1;21612;21616:14;21612:18;:22;;;21608:107;;;21672:35;21663:44;21712:3;21662:53;21608:107;21754:1;21734;21738:13;21734:17;:21;;;21730:106;;;21793:35;21784:44;21833:3;21783:53;21730:106;21875:1;21855;21859:13;21855:17;:21;;;21851:106;;;21914:35;21905:44;21954:3;21904:53;21851:106;21996:1;21976;21980:13;21976:17;:21;;;21972:106;;;22035:35;22026:44;22075:3;22025:53;21972:106;22117:1;22097;22101:13;22097:17;:21;;;22093:106;;;22156:35;22147:44;22196:3;22146:53;22093:106;22237:1;22218;22222:12;22218:16;:20;;;22214:105;;;22276:35;22267:44;22316:3;22266:53;22214:105;22357:1;22338;22342:12;22338:16;:20;;;22334:105;;;22396:35;22387:44;22436:3;22386:53;22334:105;22477:1;22458;22462:12;22458:16;:20;;;22454:105;;;22516:35;22507:44;22556:3;22506:53;22454:105;22597:1;22578;22582:12;22578:16;:20;;;22574:105;;;22636:35;22627:44;22676:3;22626:53;22574:105;22716:1;22698;22702:11;22698:15;:19;;;22694:104;;;22755:35;22746:44;22795:3;22745:53;22694:104;22835:1;22817;22821:11;22817:15;:19;;;22813:104;;;22874:35;22865:44;22914:3;22864:53;22813:104;22954:1;22936;22940:11;22936:15;:19;;;22932:104;;;22993:35;22984:44;23033:3;22983:53;22932:104;23073:1;23055;23059:11;23055:15;:19;;;23051:104;;;23112:35;23103:44;23152:3;23102:53;23051:104;23191:1;23174;23178:10;23174:14;:18;;;23170:103;;;23230:35;23221:44;23270:3;23220:53;23170:103;23309:1;23292;23296:10;23292:14;:18;;;23288:103;;;23348:35;23339:44;23388:3;23338:53;23288:103;23427:1;23410;23414:10;23410:14;:18;;;23406:103;;;23466:35;23457:44;23506:3;23456:53;23406:103;23545:1;23528;23532:10;23528:14;:18;;;23524:103;;;23584:35;23575:44;23624:3;23574:53;23524:103;23662:1;23646;23650:9;23646:13;:17;;;23642:102;;;23701:35;23692:44;23741:3;23691:53;23642:102;23779:1;23763;23767:9;23763:13;:17;;;23759:102;;;23818:35;23809:44;23858:3;23808:53;23759:102;23896:1;23880;23884:9;23880:13;:17;;;23876:102;;;23935:35;23926:44;23975:3;23925:53;23876:102;24013:1;23997;24001:9;23997:13;:17;;;23993:102;;;24052:35;24043:44;24092:3;24042:53;23993:102;24129:1;24114;24118:8;24114:12;:16;;;24110:101;;;24168:35;24159:44;24208:3;24158:53;24110:101;24245:1;24230;24234:8;24230:12;:16;;;24226:101;;;24284:35;24275:44;24324:3;24274:53;24226:101;24361:1;24346;24350:8;24346:12;:16;;;24342:101;;;24400:35;24391:44;24440:3;24390:53;24342:101;24477:1;24462;24466:8;24462:12;:16;;;24458:101;;;24516:35;24507:44;24556:3;24506:53;24458:101;24592:1;24578;24582:7;24578:11;:15;;;24574:100;;;24631:35;24622:44;24671:3;24621:53;24574:100;24707:1;24693;24697:7;24693:11;:15;;;24689:100;;;24746:35;24737:44;24786:3;24736:53;24689:100;24822:1;24808;24812:7;24808:11;:15;;;24804:100;;;24861:35;24852:44;24901:3;24851:53;24804:100;24937:1;24923;24927:7;24923:11;:15;;;24919:100;;;24976:35;24967:44;25016:3;24966:53;24919:100;25051:1;25038;25042:6;25038:10;:14;;;25034:99;;;25090:35;25081:44;25130:3;25080:53;25034:99;25165:1;25152;25156:6;25152:10;:14;;;25148:99;;;25204:35;25195:44;25244:3;25194:53;25148:99;25279:1;25266;25270:6;25266:10;:14;;;25262:99;;;25318:35;25309:44;25358:3;25308:53;25262:99;25393:1;25380;25384:6;25380:10;:14;;;25376:99;;;25432:35;25423:44;25472:3;25422:53;25376:99;25506:1;25494;25498:5;25494:9;:13;;;25490:98;;;25545:35;25536:44;25585:3;25535:53;25490:98;25619:1;25607;25611:5;25607:9;:13;;;25603:98;;;25658:35;25649:44;25698:3;25648:53;25603:98;25732:1;25720;25724:5;25720:9;:13;;;25716:98;;;25771:35;25762:44;25811:3;25761:53;25716:98;25845:1;25833;25837:5;25833:9;:13;;;25829:98;;;25884:35;25875:44;25924:3;25874:53;25829:98;25957:1;25946;25950:4;25946:8;:12;;;25942:97;;;25996:35;25987:44;26036:3;25986:53;25942:97;26069:1;26058;26062:4;26058:8;:12;;;26054:97;;;26108:35;26099:44;26148:3;26098:53;26054:97;26181:1;26170;26174:4;26170:8;:12;;;26166:97;;;26220:35;26211:44;26260:3;26210:53;26166:97;26293:1;26282;26286:4;26282:8;:12;;;26278:97;;;26332:35;26323:44;26372:3;26322:53;26278:97;26404:1;26394;26398:3;26394:7;:11;;;26390:96;;;26443:35;26434:44;26483:3;26433:53;26390:96;26515:1;26505;26509:3;26505:7;:11;;;26501:96;;;26554:35;26545:44;26594:3;26544:53;26501:96;26626:1;26616;26620:3;26616:7;:11;;;26612:96;;;26665:35;26656:44;26705:3;26655:53;26612:96;26737:1;26727;26731:3;26727:7;:11;;;26723:96;;;26776:35;26767:44;26816:3;26766:53;26723:96;26868:7;;;;26873:2;26868:7;26862:2;:14;26855:22;;26836:42;996:34;26901:36;;;26893:45;;;;;7216:665;7274:7;7323:6;7319:20;;-1:-1:-1;7338:1:0;7331:8;;7319:20;7369:1;7364;:6;;;;7356:15;;;;;;7410:9;;;;7445:34;7441:38;;7402:78;;7485:2;7401:86;;7542:3;7537:8;;;7515:31;7577:50;7571:56;;;7563:65;;;;;;7650:2;7643:9;7722:96;;7695:123;;;7669:164;;;;;;7855:7;;7216:665;-1:-1:-1;;;7216:665:0:o;57993:248::-;58164:68;;2705:42:1;2774:15;;;58164:68:0;;;2756:34:1;2826:15;;2806:18;;;2799:43;2858:18;;;2851:34;;;58137:96:0;;58157:5;;58187:27;;2668:18:1;;58164:68:0;2650:241:1;53135:548:0;53219:21;;;53211:65;;;;;;;9146:2:1;53211:65:0;;;9128:21:1;9185:2;9165:18;;;9158:30;9224:33;9204:18;;;9197:61;9275:18;;53211:65:0;9118:181:1;53211:65:0;53367:6;53351:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;53522:18:0;;;:9;:18;;;;;;;;;;;:28;;;;;;53577:37;9450:25:1;;;53577:37:0;;9423:18:1;53577:37:0;;;;;;;53135:548;;:::o;60841:716::-;61265:23;61291:69;61319:4;61291:69;;;;;;;;;;;;;;;;;61299:5;61291:27;;;;:69;;;;;:::i;:::-;61375:17;;61265:95;;-1:-1:-1;61375:21:0;61371:179;;61472:10;61461:30;;;;;;;;;;;;:::i;:::-;61453:85;;;;;;;8329:2:1;61453:85:0;;;8311:21:1;8368:2;8348:18;;;8341:30;8407:34;8387:18;;;8380:62;8478:12;8458:18;;;8451:40;8508:19;;61453:85:0;8301:232:1;35543:229:0;35680:12;35712:52;35734:6;35742:4;35748:1;35751:12;35712:21;:52::i;:::-;35705:59;35543:229;-1:-1:-1;;;;35543:229:0:o;36663:455::-;36833:12;36891:5;36866:21;:30;;36858:81;;;;;;;6351:2:1;36858:81:0;;;6333:21:1;6390:2;6370:18;;;6363:30;6429:34;6409:18;;;6402:62;6500:8;6480:18;;;6473:36;6526:19;;36858:81:0;6323:228:1;36858:81:0;36951:12;36965:23;36992:6;:11;;37011:5;37018:4;36992:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36950:73;;;;37041:69;37068:6;37076:7;37085:10;37097:12;37041:26;:69::i;:::-;37034:76;36663:455;-1:-1:-1;;;;;;;36663:455:0:o;39236:644::-;39421:12;39450:7;39446:427;;;39478:17;;39474:290;;33081:19;;;;39688:60;;;;;;;7971:2:1;39688:60:0;;;7953:21:1;8010:2;7990:18;;;7983:30;8049:31;8029:18;;;8022:59;8098:18;;39688:60:0;7943:179:1;39688:60:0;-1:-1:-1;39785:10:0;39778:17;;39446:427;39828:33;39836:10;39848:12;40583:17;;:21;40579:388;;40815:10;40809:17;40872:15;40859:10;40855:2;40851:19;40844:44;40579:388;40942:12;40935:20;;;;;;;;;;;:::i;14:196:1:-;82:20;;142:42;131:54;;121:65;;111:2;;200:1;197;190:12;111:2;63:147;;;:::o;215:186::-;274:6;327:2;315:9;306:7;302:23;298:32;295:2;;;343:1;340;333:12;295:2;366:29;385:9;366:29;:::i;406:260::-;474:6;482;535:2;523:9;514:7;510:23;506:32;503:2;;;551:1;548;541:12;503:2;574:29;593:9;574:29;:::i;:::-;564:39;;622:38;656:2;645:9;641:18;622:38;:::i;:::-;612:48;;493:173;;;;;:::o;671:328::-;748:6;756;764;817:2;805:9;796:7;792:23;788:32;785:2;;;833:1;830;823:12;785:2;856:29;875:9;856:29;:::i;:::-;846:39;;904:38;938:2;927:9;923:18;904:38;:::i;:::-;894:48;;989:2;978:9;974:18;961:32;951:42;;775:224;;;;;:::o;1004:254::-;1072:6;1080;1133:2;1121:9;1112:7;1108:23;1104:32;1101:2;;;1149:1;1146;1139:12;1101:2;1172:29;1191:9;1172:29;:::i;:::-;1162:39;1248:2;1233:18;;;;1220:32;;-1:-1:-1;;;1091:167:1:o;1263:277::-;1330:6;1383:2;1371:9;1362:7;1358:23;1354:32;1351:2;;;1399:1;1396;1389:12;1351:2;1431:9;1425:16;1484:5;1477:13;1470:21;1463:5;1460:32;1450:2;;1506:1;1503;1496:12;1545:180;1604:6;1657:2;1645:9;1636:7;1632:23;1628:32;1625:2;;;1673:1;1670;1663:12;1625:2;-1:-1:-1;1696:23:1;;1615:110;-1:-1:-1;1615:110:1:o;1730:248::-;1798:6;1806;1859:2;1847:9;1838:7;1834:23;1830:32;1827:2;;;1875:1;1872;1865:12;1827:2;-1:-1:-1;;1898:23:1;;;1968:2;1953:18;;;1940:32;;-1:-1:-1;1817:161:1:o;1983:274::-;2112:3;2150:6;2144:13;2166:53;2212:6;2207:3;2200:4;2192:6;2188:17;2166:53;:::i;:::-;2235:16;;;;;2120:137;-1:-1:-1;;2120:137:1:o;3390:442::-;3539:2;3528:9;3521:21;3502:4;3571:6;3565:13;3614:6;3609:2;3598:9;3594:18;3587:34;3630:66;3689:6;3684:2;3673:9;3669:18;3664:2;3656:6;3652:15;3630:66;:::i;:::-;3748:2;3736:15;3753:66;3732:88;3717:104;;;;3823:2;3713:113;;3511:321;-1:-1:-1;;3511:321:1:o;9675:128::-;9715:3;9746:1;9742:6;9739:1;9736:13;9733:2;;;9752:18;;:::i;:::-;-1:-1:-1;9788:9:1;;9723:80::o;9808:274::-;9848:1;9874;9864:2;;9909:77;9906:1;9899:88;10010:4;10007:1;10000:15;10038:4;10035:1;10028:15;9864:2;-1:-1:-1;10067:9:1;;9854:228::o;10087:::-;10127:7;10253:1;10185:66;10181:74;10178:1;10175:81;10170:1;10163:9;10156:17;10152:105;10149:2;;;10260:18;;:::i;:::-;-1:-1:-1;10300:9:1;;10139:176::o;10320:125::-;10360:4;10388:1;10385;10382:8;10379:2;;;10393:18;;:::i;:::-;-1:-1:-1;10430:9:1;;10369:76::o;10450:258::-;10522:1;10532:113;10546:6;10543:1;10540:13;10532:113;;;10622:11;;;10616:18;10603:11;;;10596:39;10568:2;10561:10;10532:113;;;10663:6;10660:1;10657:13;10654:2;;;-1:-1:-1;;10698:1:1;10680:16;;10673:27;10503:205::o;10713:437::-;10792:1;10788:12;;;;10835;;;10856:2;;10910:4;10902:6;10898:17;10888:27;;10856:2;10963;10955:6;10952:14;10932:18;10929:38;10926:2;;;11000:77;10997:1;10990:88;11101:4;11098:1;11091:15;11129:4;11126:1;11119:15;10926:2;;10768:382;;;:::o;11155:184::-;11207:77;11204:1;11197:88;11304:4;11301:1;11294:15;11328:4;11325:1;11318:15;11344:184;11396:77;11393:1;11386:88;11493:4;11490:1;11483:15;11517:4;11514:1;11507:15

Swarm Source

ipfs://8ee9f364e952dda9098e7abc216259292915971b45c828b40123c1fb0a51283d
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.