S Price: $0.85052 (-1.75%)

Contract

0x3C9FAd8D065B4bb91aa4a433a8a80983BF811875

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Uptown

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion
File 1 of 5 : Uptown.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "forge-std/console.sol";
import "./Quoter.sol";
import "./Qualifier.sol";

interface IRouter {
    function getAmountsOut(
        uint amountIn,
        address[] calldata path
    ) external view returns (uint[] memory amounts);

    function WETH() external pure returns (address);
}

contract Uptown is Initializable {
    uint256 constant ADAY = 1 days;

    uint256 public registrationFeeUSD;
    uint256 public prestigeRegistrationFeeUSD;
    uint256 classicIndex;
    uint256 traversalDept;
    uint256 public prestigeCount;
    uint256 maxLevel;
    address public admin;
    address miningWallet;
    mapping(uint256 => PlanConfig) public planConfigs;
    mapping(uint256 => AvalancheConfig) public avalancheConfigs;
    mapping(uint256 => User) public users;
    mapping(address => uint256[]) public userIds;

    mapping(uint256 => uint256) public userCountAt;
    mapping(uint256 => uint256) public prestigeLevelEarning;
    // @dev holds the total number of global downlines on each day
    uint256[] classicActivationDays;

    Quoter private ROUTER;
    Qualifier private qualifier;

    struct User {
        uint256 id;
        uint256 uplineId;
        uint256 referralCount;
        uint256 availableBalance;
        uint256 lastWithdrawalAt;
        uint256 prestigeLevel;
        uint256 avalancheLevel;
        address wallet;
        uint256 matrixUplineId;
        uint256[] referrals;
        uint256[] activationDays;
        mapping(address => bool) approvedAddresses;
        mapping(uint256 => uint256) recyclingCount;
        mapping(uint256 => uint256) levelEarningsCount;
        mapping(uint256 => uint256) referralCountAt;
        mapping(uint256 => uint256) prestigeLevelEarningsCount;
        mapping(uint256 => PrestigeMatrix) prestigeMatrices;
        mapping(uint256 => AvalancheMatrix) avalancheMatrices;
        mapping(uint256 => uint256) pendingAvalancheEarnings;
    }

    struct PlanConfig {
        uint256 directReferralRequirement;
        uint256 globalReferralRequirement;
        uint256 dailyEarnings;
        uint256 earningDays;
        uint256 maxRecycling;
        uint256 recyclingFee;
    }

    struct AvalancheConfig {
        uint256 price;
        uint256 g1SlotPayout;
        uint256 g2SlotPayout;
        uint256 miningPayout;
    }

    struct PrestigeMatrix {
        bool registered;
        uint256 uplineId;
        uint256 left;
        uint256 right;
    }

    struct AvalancheMatrix {
        bool registered;
        bool g1Paid;
        bool g2Paid;
        uint256 uplineId;
        uint256[] slots;
    }

    event NewUser(uint256 indexed userId, uint256 indexed uplineId);
    event Withdrawal(uint256 indexed userId, uint256 amount);
    event Recycle(uint256 indexed userId, uint256 level);
    event PrestigeLevelEarning(
        uint256 indexed userId,
        uint256 indexed downlineId,
        uint256 level,
        uint256 amount
    );
    event Deposit(uint256 indexed userId, uint256 amount);
    event MatrixPayout(
        uint256 indexed userId,
        uint256 indexed level,
        uint256 earnerId,
        uint256 amount
    );
    event NewLevel(uint256 indexed userId, uint256 level);
    event AvalanchePayout(
        uint256 indexed userId,
        uint256 payerId,
        uint256 level,
        uint256 amount
    );
    event WalletChanged(
        uint256 indexed userId,
        address oldWallet,
        address newWallet
    );

    function initialize(address _miningWallet) public initializer { }

    function configure(address _miningWallet) external  {
        require(admin == address(0), "Already configured");
        admin = msg.sender;
        miningWallet = _miningWallet;

        ROUTER = Quoter(0x60be6dC7052D37d4649503345FE8D0AcE2145c6C);
        qualifier = Qualifier(0x58Ca1A9169Af3a9ffB59166c578548011CC74c1A);
        registrationFeeUSD = 5e6;
        prestigeRegistrationFeeUSD = 5e6;
        traversalDept = 10;

        uint256 userId = 1;
        User storage user = users[userId];
        user.id = userId;
        user.uplineId = 0;
        user.wallet = msg.sender;
        user.prestigeLevel = 20;
        user.avalancheLevel = 20;
        user.lastWithdrawalAt = block.timestamp;
        for (uint256 i = 1; i <= 20; i++) {
            user.prestigeMatrices[i].registered = true;
        }

        for (uint256 i = 1; i <= 20; i++) {
            user.avalancheMatrices[i].registered = true;
        }

        userIds[msg.sender].push(userId);

        userCountAt[today()]++;

        emit NewUser(userId, 0);
        classicIndex = 1;

        configureStaterPlan();
        configurePrestige();
        configureAvalanche();
    }

    modifier onlyAdmin() {
        require(msg.sender == admin, "Only admin can call this function");
        _;
    }

    function totalUsers() public view returns (uint256) {
        return classicIndex;
    }

    function getGlobalReferralCount(
        uint256 userId
    ) public view returns (uint256) {
        return classicIndex - userId;
    }

    function getAccountsCount(address user) public view returns (uint256) {
        return userIds[user].length;
    }

    function getReferrals(
        uint256 userID,
        uint256 startIndex
    ) external view returns (uint256[20] memory) {
        uint256[20] memory ids;
        if (users[userID].referrals.length > startIndex) {
            for (uint256 i = 0; i < 10; i++) {
                if (i + startIndex >= users[userID].referrals.length) {
                    break;
                }
                ids[i] = users[userID].referrals[i + startIndex];
            }
        }
        return ids;
    }

    function getLevelConfig(
        uint256 level
    ) public view returns (PlanConfig memory) {
        return planConfigs[level];
    }

    function getAvalancheConfig(
        uint256 level
    ) public view returns (AvalancheConfig memory) {
        return avalancheConfigs[level];
    }

    function getUSDCToBNBAmount(
        uint256 usdcAmount
    ) public view returns (uint256) {
        return ROUTER.getUSDCToBNBAmount(usdcAmount);
    }

    function getRegistrationBnbAmount() public view returns (uint256) {
        return getUSDCToBNBAmount(registrationFeeUSD);
    }

    function getPrestigeRegistrationBnbAmount() public view returns (uint256) {
        return getUSDCToBNBAmount(prestigeRegistrationFeeUSD);
    }

    function getAvalancheSlotBnbAmount(
        uint256 level
    ) public view returns (uint256) {
        return getUSDCToBNBAmount(avalancheConfigs[level].price);
    }

    function beginOfDay(uint256 timestamp) public pure returns (uint256) {
        return timestamp - (timestamp % ADAY);
    }

    function today() public view returns (uint256) {
        return beginOfDay(block.timestamp);
    }

    function getUserLevelAt(
        uint256 userId,
        uint256 timestamp
    ) public view returns (uint256) {
        uint256 day = beginOfDay(timestamp);

        User storage user = users[userId];

        if (user.referrals.length == 0) {
            return 0;
        }

        uint256 globalIndex = userCountAt[day];
        for (uint256 i = classicActivationDays.length - 1; i >= 0; i--) {
            if (classicActivationDays[i] <= timestamp) {
                globalIndex = classicActivationDays[i];
                break;
            }
        }

        uint256 globalDownline = globalIndex - userId;

        uint256 directDownline = users[userId].referrals.length;
        for (uint256 i = user.activationDays.length - 1; i >= 0; i--) {
            if (user.activationDays[i] <= timestamp) {
                globalDownline = userCountAt[user.activationDays[i]];
                break;
            }
        }

        for (uint256 level = maxLevel; level >= 1; level--) {
            if (planConfigs[level].directReferralRequirement == 0) {
                continue;
            }
            if (
                directDownline >=
                planConfigs[level].directReferralRequirement &&
                globalDownline >= planConfigs[level].globalReferralRequirement
            ) {
                return level;
            }
        }

        return 0;
    }

    function getUserLevel(uint256 userId) public view returns (uint256) {
        return getUserLevelAt(userId, block.timestamp);
    }

    function currentRecycling(uint256 userId) public view returns (uint256) {
        return users[userId].recyclingCount[getUserLevel(userId)];
    }

    function isApprovedAddress(
        uint256 userId,
        address addressToCheck
    ) public view returns (bool) {
        return users[userId].approvedAddresses[addressToCheck];
    }

    function pendingEarnings(
        uint256 userId
    )
        public
        view
        returns (
            uint256 totalAmount,
            uint256[] memory daysInLevel,
            uint256[] memory levels
        )
    {
        User storage user = users[userId];
        totalAmount = user.availableBalance;

        if (beginOfDay(user.lastWithdrawalAt) == today()) {
            return (totalAmount, daysInLevel, levels);
        }

        // First, count how many level changes we'll have
        uint256 levelChanges = 0;
        uint256 lastLevel = 0;

        for (
            uint256 day = beginOfDay(user.lastWithdrawalAt + ADAY);
            day < today();
            day += ADAY
        ) {
            uint256 level = getUserLevelAt(userId, day);
            if (
                level == 0 ||
                user.levelEarningsCount[level] >= planConfigs[level].earningDays
            ) {
                continue;
            }
            if (lastLevel != level) {
                levelChanges++;
                lastLevel = level;
            }
        }

        // Initialize arrays with the correct size
        daysInLevel = new uint256[](levelChanges);
        levels = new uint256[](levelChanges);

        // If no level changes, just calculate total amount and return
        if (levelChanges == 0) {
            uint256 level = getUserLevelAt(userId, today());
            if (
                level > 0 &&
                user.levelEarningsCount[level] < planConfigs[level].earningDays
            ) {
                uint256 daysSinceLastWithdrawal = (today() -
                    beginOfDay(user.lastWithdrawalAt)) / ADAY;
                uint256 daysLeft = planConfigs[level].earningDays -
                    user.levelEarningsCount[level];

                if (daysSinceLastWithdrawal > daysLeft) {
                    daysSinceLastWithdrawal = daysLeft;
                }
                totalAmount +=
                    daysSinceLastWithdrawal *
                    planConfigs[level].dailyEarnings;
            }
            return (totalAmount, daysInLevel, levels);
        }

        // Reset variables for second pass
        uint256 currentLevel;
        uint256 daysCount;
        uint256 arrayIndex;

        for (
            uint256 day = beginOfDay(user.lastWithdrawalAt) + ADAY;
            day <= today();
            day += ADAY
        ) {
            uint256 level = getUserLevelAt(userId, day);

            if (level == 0) {
                continue;
            }

            if (level == currentLevel) {
                if (
                    user.levelEarningsCount[level] + daysCount <
                    planConfigs[level].earningDays
                ) {
                    totalAmount += planConfigs[level].dailyEarnings;
                    daysCount += 1;
                }
            } else {
                if (currentLevel != 0) {
                    daysInLevel[arrayIndex] = daysCount;
                    levels[arrayIndex] = currentLevel;
                    arrayIndex++;
                }
                currentLevel = level;
                daysCount = 0;
                if (
                    user.levelEarningsCount[level] <
                    planConfigs[level].earningDays
                ) {
                    totalAmount += planConfigs[level].dailyEarnings;
                    daysCount += 1;
                }
            }
        }

        // Store the last level's data if we have one
        if (currentLevel != 0 && arrayIndex < levelChanges) {
            daysInLevel[arrayIndex] = daysCount;
            levels[arrayIndex] = currentLevel;
        }

        currentLevel = getUserLevelAt(userId, today());
    }

    function withdrawableEarnings(
        uint256 userId
    ) public view returns (uint256) {
        (
            uint256 balance,
            uint256[] memory daysInLevel,
            uint256[] memory levels
        ) = pendingEarnings(userId);
        uint256 level = getUserLevel(userId);
        User storage user = users[userId];
        uint256 levelEarnings = planConfigs[level].dailyEarnings *
            (user.levelEarningsCount[level] +
                planConfigs[level].earningDays *
                user.recyclingCount[level]);

        for (uint256 i = 0; i < daysInLevel.length; i++) {
            if (levels[i] != level) {
                continue;
            }
            levelEarnings +=
                daysInLevel[i] *
                planConfigs[levels[i]].dailyEarnings;
        }

        if (balance <= levelEarnings) {
            return 0;
        }
        return balance; // - levelEarnings;
    }

    function getCanRecycle(uint256 userId) public view returns (bool) {
        User storage user = users[userId];
        (uint256 balance, , ) = pendingEarnings(userId);
        return
            balance >= planConfigs[getUserLevel(userId)].recyclingFee &&
            user.recyclingCount[getUserLevel(userId)] <
            planConfigs[getUserLevel(userId)].maxRecycling;
    }

    function canWithdraw(uint256 userId) public view returns (bool) {
        User storage user = users[userId];
        uint256 balance = withdrawableEarnings(userId);
        if (balance < 0) {
            return false;
        }

        uint256 level = getUserLevel(userId);

        if (
            level > 1 &&
            user.prestigeLevel > 0 &&
            user.avalancheLevel > 0 &&
            qualifier.canUserWithdraw(userId, level)
        ) {
            return true;
        }
        return false;
    }

    function getPrestigeMatrix(
        uint256 userId,
        uint256 level
    )
        public
        view
        returns (
            uint256 upline,
            uint256 left,
            uint256 leftLevel,
            uint256 right,
            uint256 rightLevel
        )
    {
        upline = users[userId].prestigeMatrices[level].uplineId;
        left = users[userId].prestigeMatrices[level].left;
        right = users[userId].prestigeMatrices[level].right;
        leftLevel = users[left].prestigeLevel;
        rightLevel = users[right].prestigeLevel;
    }

    function getAvalancheMatrix(
        uint256 userId,
        uint256 level
    )
        public
        view
        returns (
            uint256 upline,
            uint256 slot1,
            uint256 slot2,
            uint256 slot3,
            uint256 slot4
        )
    {
        User storage user = users[userId];
        if (!user.avalancheMatrices[level].registered) {
            return (0, 0, 0, 0, 0);
        }
        upline = user.avalancheMatrices[level].uplineId;
        if (user.avalancheMatrices[level].slots.length == 0) {
            return (upline, 0, 0, 0, 0);
        }
        slot1 = user.avalancheMatrices[level].slots[0];
        if (user.avalancheMatrices[level].slots.length == 1) {
            return (upline, slot1, 0, 0, 0);
        }
        slot2 = user.avalancheMatrices[level].slots[1];
        if (user.avalancheMatrices[level].slots.length == 2) {
            return (upline, slot1, slot2, 0, 0);
        }
        slot3 = user.avalancheMatrices[level].slots[2];
        if (user.avalancheMatrices[level].slots.length == 3) {
            return (upline, slot1, slot2, slot3, 0);
        }
        slot4 = user.avalancheMatrices[level].slots[3];

        return (upline, slot1, slot2, slot3, slot4);
    }

    function hasEmptyPrestigeSlot(
        uint256 userId,
        uint256 level
    ) private view returns (bool) {
        return
            users[userId].prestigeMatrices[level].right == 0 ||
            users[userId].prestigeMatrices[level].left == 0;
    }

    function hasEmptyLegs(
        uint256 userId,
        uint256 level
    ) public view returns (bool) {
        return
            users[userId].prestigeMatrices[level].left == 0 ||
            users[userId].prestigeMatrices[level].right == 0;
    }

    function isADownline(
        uint256 uplineId,
        uint256 userId,
        uint256 generation
    ) public view returns (bool) {
        for (uint256 i = 0; i < generation; i++) {
            if (users[userId].uplineId == uplineId) {
                return true;
            }
            userId = users[userId].uplineId;
            if (userId == 0) {
                return false;
            }
        }
        return false;
    }

    function firstPrestigeAncestor(
        uint256 userId,
        uint256 searchDepth
    ) public view returns (uint256) {
        uint256 uplineId = users[userId].uplineId;
        while (uplineId != 0 && searchDepth > 0) {
            if (users[uplineId].prestigeLevel > 0) {
                return uplineId;
            }
            uplineId = users[uplineId].uplineId;
            searchDepth--;
        }
        return 1;
    }

    function getAvailableUplineInMatrix(
        uint256 uplineID,
        uint256 level,
        bool traverseDown,
        uint256 random
    ) public view returns (uint256) {
        require(uplineID > 0, "ZU");
        require(users[uplineID].prestigeMatrices[level].registered, "UNIP");

        if (hasEmptyLegs(uplineID, level)) {
            return uplineID;
        }

        uint256 arraySize = ((2 ** traversalDept) - 1);
        uint256 previousLineSize = ((2 ** (traversalDept - 1)) - 1);
        
        uint256[] memory referrals = new uint256[](arraySize);
        referrals[0] = users[uplineID].prestigeMatrices[level].left;
        referrals[1] = users[uplineID].prestigeMatrices[level].right;

        uint256 referrer;

        for (uint256 i = 0; i < arraySize; i++) {
            if (hasEmptyLegs(referrals[i], level)) {
                referrer = referrals[i];
                break;
            }

            if (i < previousLineSize) {
                referrals[(i + 1) * 2] = users[referrals[i]]
                    .prestigeMatrices[level]
                    .left;
                referrals[(i + 1) * 2 + 1] = users[referrals[i]]
                    .prestigeMatrices[level]
                    .right;
            }
        }

        if (referrer == 0 && traverseDown) {
            if (random < previousLineSize) {
                random = random + previousLineSize;
            }
            if (random > arraySize) {
                random = arraySize % random;
            }
            referrer = getAvailableUplineInMatrix(
                referrals[random],
                level,
                false,
                random
            );

            if (referrer == 0) {
                for (uint256 i = previousLineSize; i < arraySize; i++) {
                    referrer = getAvailableUplineInMatrix(
                        referrals[i],
                        level,
                        false,
                        random
                    );
                    if (referrer != 0) {
                        break;
                    }
                }
                require(referrer > 0, "RNF");
            }
        }

        return referrer;
    }

    function getNextAvailableAvalencheSlot(
        uint256 uplineID,
        uint256 level,
        bool traverseDown,
        uint256 random
    ) internal view returns (uint256) {
        require(uplineID > 0, "ZU");

        if (users[uplineID].avalancheMatrices[level].slots.length < 4) {
            return uplineID;
        }

        uint256 arraySize = ((4 ** 5) - 1) / 3;
        uint256 previousLineSize = ((4 ** (5 - 1)) - 1) / 3;
        uint256[] memory referrals = new uint256[](arraySize);
        referrals[0] = users[uplineID].avalancheMatrices[level].slots[0];
        referrals[1] = users[uplineID].avalancheMatrices[level].slots[1];
        referrals[2] = users[uplineID].avalancheMatrices[level].slots[2];
        referrals[3] = users[uplineID].avalancheMatrices[level].slots[3];

        uint256 referrer;

        for (uint256 i = 0; i < arraySize; i++) {
            if (users[referrals[i]].avalancheMatrices[level].slots.length < 4) {
                referrer = referrals[i];
                break;
            }

            if (i < previousLineSize) {
                referrals[(i + 1) * 4] = users[referrals[i]]
                    .avalancheMatrices[level]
                    .slots[0];
                referrals[(i + 1) * 4 + 1] = users[referrals[i]]
                    .avalancheMatrices[level]
                    .slots[1];
                referrals[(i + 1) * 4 + 2] = users[referrals[i]]
                    .avalancheMatrices[level]
                    .slots[2];
                referrals[(i + 1) * 4 + 3] = users[referrals[i]]
                    .avalancheMatrices[level]
                    .slots[3];
            }
        }

        if (referrer == 0 && traverseDown) {
            if (random < previousLineSize) {
                random = random + previousLineSize;
            }
            if (random > arraySize) {
                random = arraySize % random;
            }
            referrer = getAvailableUplineInMatrix(
                referrals[random],
                level,
                false,
                random
            );

            if (referrer == 0) {
                for (uint256 i = previousLineSize; i < arraySize; i++) {
                    referrer = getAvailableUplineInMatrix(
                        referrals[random],
                        level,
                        false,
                        random
                    );
                    if (referrer != 0) {
                        break;
                    }
                }
                require(referrer > 0, "RNF");
            }
        }

        return referrer;
    }

    function pendingAvalancheEarning(
        uint256 userId,
        uint256 level
    ) public view returns (uint256) {
        return users[userId].pendingAvalancheEarnings[level];
    }

    function setRegistrationFee(
        uint256 _registrationFeeUSD
    ) external onlyAdmin {
        registrationFeeUSD = _registrationFeeUSD;
    }

    function setPrestigeRegistrationFee(
        uint256 _prestigeRegistrationFeeUSD
    ) external onlyAdmin {
        prestigeRegistrationFeeUSD = _prestigeRegistrationFeeUSD;
    }

    function setPrestigeLevelEarning(uint256 level, uint256 earning) internal {
        prestigeLevelEarning[level] = earning;
    }

    function setTraversalDept(uint256 _traversalDept) external onlyAdmin {
        traversalDept = _traversalDept;
    }

    function setAdmin(address newAdmin) external onlyAdmin {
        admin = newAdmin;
    }

    function setMiningWallet(address _miningWallet) external onlyAdmin {
        miningWallet = _miningWallet;
    }

    function setSwapRouter(address _router) external onlyAdmin {
        ROUTER = Quoter(_router);
    }

    function setQualifier(address _qualifier) external onlyAdmin {
        qualifier = Qualifier(_qualifier);
    }

    function setLevelConfig(
        uint256 level,
        uint256 directReferralRequirement,
        uint256 globalReferralRequirement,
        uint256 dailyEarnings,
        uint256 earningDays,
        uint256 maxRecycling,
        uint256 recyclingFee
    ) internal {
        planConfigs[level] = PlanConfig({
            directReferralRequirement: directReferralRequirement,
            globalReferralRequirement: globalReferralRequirement,
            dailyEarnings: dailyEarnings,
            earningDays: earningDays,
            maxRecycling: maxRecycling,
            recyclingFee: recyclingFee
        });
        if (level > maxLevel) {
            maxLevel = level;
        }
    }

    function configureStaterPlan() internal {
        setLevelConfig(1, 4, 40, 25e4, 40, 4, 5e6);
        setLevelConfig(2, 6, 150, 45e4, 40, 3, 0);
        setLevelConfig(3, 8, 1000, 6e5, 40, 3, 0);
        setLevelConfig(4, 10, 5000, 75e4, 40, 3, 0);
        setLevelConfig(5, 12, 15000, 95e4, 40, 3, 0);
        setLevelConfig(6, 14, 35000, 125e4, 40, 3, 0);
        setLevelConfig(7, 16, 55000, 150e4, 40, 3, 0);
        setLevelConfig(8, 18, 100000, 185e4, 40, 3, 0);
        setLevelConfig(9, 20, 500000, 19e5, 40, 3, 0);
        setLevelConfig(10, 22, 750000, 22e5, 40, 3, 0);
        setLevelConfig(11, 24, 1000000, 255e4, 40, 3, 0);
        setLevelConfig(12, 26, 1500000, 285e4, 40, 3, 0);
        setLevelConfig(13, 28, 2500000, 315e4, 40, 3, 0);
        setLevelConfig(14, 30, 3500000, 35e5, 40, 3, 0);
        setLevelConfig(15, 32, 5000000, 399e5, 40, 3, 0);
        setLevelConfig(16, 34, 15000000, 44e5, 40, 3, 0);
        setLevelConfig(17, 36, 50000000, 5e6, 40, 3, 0);
        setLevelConfig(18, 38, 150000000, 65e5, 40, 3, 0);
        setLevelConfig(19, 40, 300000000, 75e5, 40, 3, 0);
        setLevelConfig(20, 42, 500000000, 1e7, 40, 3, 0);
    }

    function configureAvalanche() internal {
        uint256[] memory prices = new uint256[](20);
        prices[0] = 5e6;
        prices[1] = 75e5;
        prices[2] = 1125e4;
        prices[3] = 16875e3;
        prices[4] = 253125e2;
        prices[5] = 3796875e1;
        prices[6] = 56953125;
        prices[7] = 854296875;
        prices[8] = 1281445313;
        prices[9] = 1922167969;
        prices[10] = 288325195;
        prices[11] = 432487793;
        prices[12] = 648731689;
        prices[13] = 973097534;
        prices[14] = 1459646301;
        prices[15] = 2189469452;
        prices[16] = 3284204178;
        prices[17] = 4926306267;
        prices[18] = 7389459400;
        prices[19] = 11084189100;

        for (uint256 i = 0; i < prices.length; i++) {
            avalancheConfigs[i + 1] = AvalancheConfig({
                price: prices[i],
                g1SlotPayout: (prices[i] * 375) / 1000,
                g2SlotPayout: (prices[i] * 375) / 1000,
                miningPayout: (prices[i] * 250) / 1000
            });
        }
    }

    function configurePrestige() internal {
        setPrestigeLevelEarning(1, 25e5);
        setPrestigeLevelEarning(2, 5e6);
        setPrestigeLevelEarning(3, 1e7);
        setPrestigeLevelEarning(4, 2e7);
        setPrestigeLevelEarning(5, 4e7);
        setPrestigeLevelEarning(6, 8e7);
        setPrestigeLevelEarning(7, 16e7);
        setPrestigeLevelEarning(8, 32e7);
        setPrestigeLevelEarning(9, 64e7);
        setPrestigeLevelEarning(10, 128e7);
        setPrestigeLevelEarning(11, 256e7);
        setPrestigeLevelEarning(12, 512e7);
        setPrestigeLevelEarning(13, 1024e7);
        setPrestigeLevelEarning(14, 2048e7);
        setPrestigeLevelEarning(15, 4096e7);
        setPrestigeLevelEarning(16, 8192e7);
        setPrestigeLevelEarning(17, 16384e7);
        setPrestigeLevelEarning(18, 32768e7);
        setPrestigeLevelEarning(19, 65536e7);
        setPrestigeLevelEarning(20, 131072e7);
    }

    function deposit(uint256 userId) external payable {
        require(msg.value > 0, "Invalid amount");
        uint256 amount = getUSDCToBNBAmount(msg.value);
        users[userId].availableBalance += amount;
        emit Deposit(userId, amount);
    }

    function withdrawEarnings(uint256 userId) external {
        require(
            msg.sender == users[userId].wallet ||
                isApprovedAddress(userId, msg.sender),
            "Access denied"
        );
        require(withdrawableEarnings(userId) > 0, "No withdrawable earnings");
        require(canWithdraw(userId), "Cannot withdraw");

        harvestEarnings(userId);
        require(users[userId].availableBalance > 0, "No available balance");
        uint256 amount = users[userId].availableBalance;
        users[userId].availableBalance = 0;
        uint256 ethAmount = getUSDCToBNBAmount(amount);

        payable(msg.sender).transfer(ethAmount);

        emit Withdrawal(userId, amount);
    }

    function registerUser(
        uint256 uplineId,
        uint256 matrixUplineId,
        address addr
    ) public payable {
        require(registrationFeeUSD > 0, "Registration fee not set");

        require(
            matrixUplineId == 0 ||
                (users[matrixUplineId].prestigeLevel > 0 &&
                    users[matrixUplineId].avalancheLevel > 0),
            "Invalid matrix upline ID"
        );

        uint256 price = getUSDCToBNBAmount(registrationFeeUSD);
        require(msg.value >= price, "Invalid registration fee");

        _registerUser(uplineId, matrixUplineId, addr);
        if (msg.value > price) {
            payable(msg.sender).transfer(msg.value - price);
        }
    }

    function _registerUser(
        uint256 uplineId,
        uint256 matrixUplineId,
        address addr
    ) internal {
        require(uplineId > 0 && uplineId <= classicIndex, "Invalid upline ID");

        classicIndex++;
        uint256 userId = classicIndex;

        User storage user = users[userId];
        user.id = userId;
        user.uplineId = uplineId;
        user.matrixUplineId = matrixUplineId;
        user.wallet = addr;
        user.lastWithdrawalAt = block.timestamp;
        userIds[addr].push(userId);

        uint256 _today = today();
        userCountAt[_today] = classicIndex;

        users[uplineId].referrals.push(userId);
        users[uplineId].referralCount++;
        users[uplineId].referralCountAt[_today]++;

        if (users[uplineId].activationDays.length == 0) {
            users[uplineId].activationDays.push(_today);
        } else if (
            users[uplineId].activationDays[
                users[uplineId].activationDays.length - 1
            ] != today()
        ) {
            users[uplineId].activationDays.push(_today);
        }

        if (classicActivationDays.length == 0) {
            classicActivationDays.push(_today);
        } else if (
            classicActivationDays[classicActivationDays.length - 1] != _today
        ) {
            classicActivationDays.push(_today);
        }

        emit NewUser(userId, uplineId);
    }

    function setApprovedAddress(
        uint256 userId,
        address addressToApprove,
        bool approved
    ) public {
        require(msg.sender == users[userId].wallet, "Access denied");
        users[userId].approvedAddresses[addressToApprove] = approved;
    }

    function changeWallet(uint256 userId, address newWallet) external {
        require(
            msg.sender == users[userId].wallet,
            "Only user can change wallet"
        );
        for (uint256 i = 0; i < userIds[users[userId].wallet].length; i++) {
            if (userIds[users[userId].wallet][i] == userId) {
                userIds[users[userId].wallet][i] = userIds[
                    users[userId].wallet
                ][userIds[users[userId].wallet].length - 1];
                userIds[users[userId].wallet].pop();
                break;
            }
        }
        userIds[newWallet].push(userId);
        users[userId].wallet = newWallet;
        emit WalletChanged(userId, msg.sender, newWallet);
    }

    function registerMultipleAccounts(
        uint256 uplineID,
        uint256 matrixUplineId,
        address addr,
        uint256 no
    ) external payable {
        require(no <= 50, "TOO_MANY");
        uint256 price = getUSDCToBNBAmount(registrationFeeUSD);
        require(msg.value >= price * no, "Invalid registration fee");

        for (uint256 i = 0; i < no; i++) {
            _registerUser(uplineID, matrixUplineId, addr);
        }

        if (msg.value > price * no) {
            payable(msg.sender).transfer(msg.value - price * no);
        }
    }

    function recycle(uint256 userId) external {
        require(msg.sender == users[userId].wallet, "Access denied");
        require(getCanRecycle(userId), "Cannot recycle");
        User storage user = users[userId];
        uint256 level = getUserLevel(userId);
        harvestEarnings(userId);
        user.availableBalance -= planConfigs[level].recyclingFee;
        user.recyclingCount[level] += 1;
        user.levelEarningsCount[level] = 0;
        emit Recycle(userId, level);
    }

    function harvestEarnings(uint256 userId) private {
        (
            uint256 totalAmount,
            uint256[] memory daysInLevel,
            uint256[] memory levels
        ) = pendingEarnings(userId);
        if (totalAmount == 0) {
            return;
        }

        users[userId].availableBalance += totalAmount;
        users[userId].lastWithdrawalAt = block.timestamp;

        User storage user = users[userId];
        for (uint256 i = 0; i < levels.length; i++) {
            user.levelEarningsCount[levels[i]] += daysInLevel[i];
        }
    }

    function registerPrestigeUser(
        uint256 userId,
        uint256 uplineId,
        uint256 random
    ) external payable {
        require(
            prestigeRegistrationFeeUSD > 0,
            "Prestige registration fee not set"
        );
        require(userId > 0 && userId <= classicIndex, "Invalid user ID");
        require(uplineId >= 0 && uplineId <= classicIndex, "Invalid upline ID");
        require(uplineId != userId, "Upline cannot be the same as user");

        if (uplineId == 0) {
            uplineId = firstPrestigeAncestor(userId, 10);
        }

        User storage user = users[userId];
        harvestEarnings(userId);
        uint256 priceEth = getUSDCToBNBAmount(prestigeRegistrationFeeUSD);
        require(
            user.availableBalance >= prestigeRegistrationFeeUSD ||
                msg.value >= priceEth,
            "Insufficient balance"
        );

        require(user.prestigeLevel == 0, "User already in prestige plan");

        user.prestigeLevel = 1;
        if (msg.value == 0) {
            user.availableBalance -= prestigeRegistrationFeeUSD;
        }

        uint256 matrixUpline = getAvailableUplineInMatrix(
            uplineId,
            1,
            true,
            random
        );
        user.prestigeMatrices[1].registered = true;
        user.prestigeMatrices[1].uplineId = matrixUpline;
        user.prestigeLevel = 1;

        if (users[matrixUpline].prestigeMatrices[1].left == 0) {
            users[matrixUpline].prestigeMatrices[1].left = userId;
        } else {
            users[matrixUpline].prestigeMatrices[1].right = userId;
        }

        uint256 earnerId = sendMatrixPayout(userId, 1);

        if (hasCompletedLevel(earnerId, 1)) {
            moveToNextLevel(earnerId, random);
        }

        if (msg.value > priceEth) {
            payable(msg.sender).transfer(msg.value - priceEth);
        }

        emit NewLevel(userId, 1);
    }

    function hasCompletedLevel(uint256 userId, uint256 level) internal view returns (bool) {
        return users[userId].prestigeLevelEarningsCount[level] == 4;
    }

    function moveToNextLevel(uint256 userID, uint256 random) internal {
        if (userID == 1) return;
        User storage user = users[userID];
        uint256 newLevel = user.prestigeLevel + 1;
        require(newLevel >= 1, "Invalid level");
        user.prestigeLevel = newLevel;

        uint256 matrixUpline = getAvailableUplineInMatrix(
            user.prestigeMatrices[newLevel - 1].uplineId,
            newLevel,
            true,
            random
        );

        user.prestigeMatrices[newLevel].registered = true;
        user.prestigeMatrices[newLevel].uplineId = matrixUpline;

        if (users[matrixUpline].prestigeMatrices[newLevel].left == 0) {
            users[matrixUpline].prestigeMatrices[newLevel].left = userID;
        } else {
            users[matrixUpline].prestigeMatrices[newLevel].right = userID;
        }

        uint256 earnerId = sendMatrixPayout(userID, newLevel);

        if (hasCompletedLevel(earnerId, newLevel)) {
            moveToNextLevel(earnerId, random);
        }

        emit NewLevel(userID, newLevel);
    }

    function sendMatrixPayout(uint256 userId, uint256 level) internal returns(uint256) {
        uint256 payout = prestigeLevelEarning[level];

        uint256 directUpline = users[userId].prestigeMatrices[level].uplineId;
        if (directUpline == 0) {
            return 0;
        }
        uint256 earnerId = users[directUpline].prestigeMatrices[level].uplineId;
        if (earnerId == 0) {
            return 0;
        }
        User storage earner = users[earnerId];
        if (earner.prestigeLevelEarningsCount[level] >= 3) {
            payable(miningWallet).transfer(getUSDCToBNBAmount(payout));
        } else {
            payable(earner.wallet).transfer(getUSDCToBNBAmount(payout));
        }
        earner.prestigeLevelEarningsCount[level] += 1;

        emit MatrixPayout(userId, level, earnerId, payout);

        return earnerId;
    }

    function addToAvalancheSlot(
        uint256 userId,
        uint256 level,
        uint256 uplineId,
        uint256 random,
        bool isManualPurchase
    ) internal {
        User storage user = users[userId];
        require(
            level == user.avalancheLevel + 1,
            "Account not qualified for this level"
        );

        user.avalancheLevel = level;

        uint256 matrixUpline = getNextAvailableAvalencheSlot(
            uplineId,
            level,
            true,
            random
        );


        user.avalancheMatrices[level].uplineId = matrixUpline;
        user.avalancheMatrices[level].registered = true;

        users[matrixUpline].avalancheMatrices[level].slots.push(userId);
        
        if (level == 1) {
            if (users[matrixUpline].avalancheMatrices[level].registered) {
                sendAvalanchePayout(userId, level, true);
            }
            if (user.avalancheMatrices[level].slots.length > 0) {
                for (
                    uint256 i = 0;
                    i < user.avalancheMatrices[level].slots.length;
                    i++
                ) {
                    sendAvalanchePayout(
                        user.avalancheMatrices[level].slots[i],
                        level,
                        true
                    );
                }
            }
        } else {
            if (isManualPurchase) {
                sendAvalanchePayoutForManualPurchase(userId, level);
            } else {
                sendAvalanchePayout(
                    userId,
                    level,
                    level < 20 ||
                        !users[matrixUpline]
                            .avalancheMatrices[level + 1]
                            .registered
                );
            }
        }

        if (users[matrixUpline].avalancheMatrices[level].slots.length == 4) {
            moveToNextAvalancheLevel(matrixUpline, random);
        }
    }

    function buyAvalancheSlot(
        uint256 userId,
        uint256 level,
        uint256 uplineId,
        uint256 random
    ) external payable {
        require(
            avalancheConfigs[level].price > 0,
            "Avalanche registration fee not set"
        );
        require(userId > 0 && userId <= classicIndex, "Invalid user ID");
        require(
            uplineId == 0 ||
                uplineId == users[userId].uplineId ||
                (users[uplineId].avalancheLevel > 0 &&
                    isADownline(uplineId, userId, 10)),
            "Cannot use this upline ID"
        );

        (uint256 pendingEarningsAmount, , ) = pendingEarnings(userId);
        uint256 price = getUSDCToBNBAmount(avalancheConfigs[level].price);
        require(
            msg.value >= price || pendingEarningsAmount >= price,
            "Invalid registration fee"
        );

        require(level > 0 && level <= 20, "Invalid level");

        User storage user = users[userId];
        require(user.avalancheLevel == level - 1, "Cannot buy this level");

        if (uplineId == 0) {
            uplineId = user.uplineId;
        }

        if (msg.value == 0) {
            harvestEarnings(userId);
            require(
                user.availableBalance >= avalancheConfigs[level].price,
                "Insufficient balance"
            );
            user.availableBalance -= avalancheConfigs[level].price;
        }

        addToAvalancheSlot(userId, level, uplineId, random, level > 1);

        if (msg.value > price) {
            payable(msg.sender).transfer(msg.value - price);
        }
    }

    function sendAvalanchePayout(
        uint256 userId,
        uint256 level,
        bool payG2
    ) public {
        require(
            users[userId].avalancheMatrices[level].registered,
            "User not registered in this level"
        );

        User storage user = users[userId];

        // TODO: if upline already paid, mark g2Paid as true and send payout to upline
        if (
            !user.avalancheMatrices[level].g1Paid &&
            !user.avalancheMatrices[level].g2Paid
        ) {
            payable(miningWallet).transfer(
                getUSDCToBNBAmount(avalancheConfigs[level].miningPayout)
            );
        }

        if (user.avalancheMatrices[level].uplineId == 0) {
            return;
        }
        User storage g1Upline = users[user.avalancheMatrices[level].uplineId];
        if (!user.avalancheMatrices[level].g1Paid) {
            uint256 l1Amount = avalancheConfigs[level].g1SlotPayout;
            if (!payG2 && !user.avalancheMatrices[level].g2Paid) {
                l1Amount += avalancheConfigs[level].g2SlotPayout;
                user.avalancheMatrices[level].g2Paid = true;
            }
            if (g1Upline.avalancheLevel >= level) {
                payable(g1Upline.wallet).transfer(getUSDCToBNBAmount(l1Amount));
            } else {
                g1Upline.pendingAvalancheEarnings[level] += l1Amount;
            }
            user.avalancheMatrices[level].g1Paid = true;
            emit AvalanchePayout(g1Upline.id, userId, level, l1Amount);
        }

        if (g1Upline.avalancheMatrices[level].uplineId == 0) {
            return;
        }
        User storage g2Upline = users[
            g1Upline.avalancheMatrices[level].uplineId
        ];
        if (!user.avalancheMatrices[level].g2Paid && payG2) {
            if (g2Upline.avalancheLevel >= level) {
                payable(g2Upline.wallet).transfer(
                    getUSDCToBNBAmount(avalancheConfigs[level].g2SlotPayout)
                );
            } else {
                g2Upline.pendingAvalancheEarnings[level] += avalancheConfigs[
                    level
                ].g2SlotPayout;
            }
            user.avalancheMatrices[level].g2Paid = true;
            emit AvalanchePayout(
                g2Upline.id,
                userId,
                level,
                avalancheConfigs[level].g2SlotPayout
            );
        }
    }

    function sendAvalanchePayoutForManualPurchase(
        uint256 userId,
        uint256 level
    ) internal {
        require(
            users[userId].avalancheMatrices[level].registered,
            "User not registered in this level"
        );

        require(
            level > 1,
            "Manual purchase is only available for level 2 and above"
        );

        User storage user = users[userId];

        // TODO: if upline already paid, mark g2Paid as true and send payout to upline
        if (
            !user.avalancheMatrices[level].g1Paid &&
            !user.avalancheMatrices[level].g2Paid
        ) {
            payable(miningWallet).transfer(
                getUSDCToBNBAmount(avalancheConfigs[level - 1].miningPayout * 4)
            );
        }

        if (user.avalancheMatrices[level - 1].uplineId == 0) {
            return;
        }

        uint256 leg0UplineEarnings = avalancheConfigs[level - 1].g2SlotPayout *
            4;
        payable(users[user.avalancheMatrices[level - 1].uplineId].wallet)
            .transfer(getUSDCToBNBAmount(leg0UplineEarnings));
    }

    function moveToNextAvalancheLevel(uint256 userID, uint256 random) internal {
        if (userID == 1) return;
        User storage user = users[userID];
        uint256 newLevel = user.avalancheLevel + 1;
        uint256 uplineId = user.avalancheMatrices[1].uplineId;

        if (
            !users[uplineId].avalancheMatrices[newLevel].registered &&
            uplineId != user.uplineId
        ) {
            uplineId = user.uplineId;
        }

        addToAvalancheSlot(userID, newLevel, uplineId, random, false);
    }
}

File 2 of 5 : Initializable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Storage of the initializable contract.
     *
     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
     * when using with upgradeable contracts.
     *
     * @custom:storage-location erc7201:openzeppelin.storage.Initializable
     */
    struct InitializableStorage {
        /**
         * @dev Indicates that the contract has been initialized.
         */
        uint64 _initialized;
        /**
         * @dev Indicates that the contract is in the process of being initialized.
         */
        bool _initializing;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

    /**
     * @dev The contract is already initialized.
     */
    error InvalidInitialization();

    /**
     * @dev The contract is not initializing.
     */
    error NotInitializing();

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint64 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
     * production.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        // Cache values to avoid duplicated sloads
        bool isTopLevelCall = !$._initializing;
        uint64 initialized = $._initialized;

        // Allowed calls:
        // - initialSetup: the contract is not in the initializing state and no previous version was
        //                 initialized
        // - construction: the contract is initialized at version 1 (no reininitialization) and the
        //                 current contract is just being deployed
        bool initialSetup = initialized == 0 && isTopLevelCall;
        bool construction = initialized == 1 && address(this).code.length == 0;

        if (!initialSetup && !construction) {
            revert InvalidInitialization();
        }
        $._initialized = 1;
        if (isTopLevelCall) {
            $._initializing = true;
        }
        _;
        if (isTopLevelCall) {
            $._initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint64 version) {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing || $._initialized >= version) {
            revert InvalidInitialization();
        }
        $._initialized = version;
        $._initializing = true;
        _;
        $._initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        _checkInitializing();
        _;
    }

    /**
     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
     */
    function _checkInitializing() internal view virtual {
        if (!_isInitializing()) {
            revert NotInitializing();
        }
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing) {
            revert InvalidInitialization();
        }
        if ($._initialized != type(uint64).max) {
            $._initialized = type(uint64).max;
            emit Initialized(type(uint64).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint64) {
        return _getInitializableStorage()._initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _getInitializableStorage()._initializing;
    }

    /**
     * @dev Returns a pointer to the storage namespace.
     */
    // solhint-disable-next-line var-name-mixedcase
    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
        assembly {
            $.slot := INITIALIZABLE_STORAGE
        }
    }
}

File 3 of 5 : console.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

library console {
    address constant CONSOLE_ADDRESS =
        0x000000000000000000636F6e736F6c652e6c6f67;

    function _sendLogPayloadImplementation(bytes memory payload) internal view {
        address consoleAddress = CONSOLE_ADDRESS;
        /// @solidity memory-safe-assembly
        assembly {
            pop(
                staticcall(
                    gas(),
                    consoleAddress,
                    add(payload, 32),
                    mload(payload),
                    0,
                    0
                )
            )
        }
    }

    function _castToPure(
      function(bytes memory) internal view fnIn
    ) internal pure returns (function(bytes memory) pure fnOut) {
        assembly {
            fnOut := fnIn
        }
    }

    function _sendLogPayload(bytes memory payload) internal pure {
        _castToPure(_sendLogPayloadImplementation)(payload);
    }

    function log() internal pure {
        _sendLogPayload(abi.encodeWithSignature("log()"));
    }

    function logInt(int256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
    }

    function logUint(uint256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
    }

    function logString(string memory p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
    }

    function logBool(bool p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
    }

    function logAddress(address p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
    }

    function logBytes(bytes memory p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
    }

    function logBytes1(bytes1 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
    }

    function logBytes2(bytes2 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
    }

    function logBytes3(bytes3 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
    }

    function logBytes4(bytes4 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
    }

    function logBytes5(bytes5 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
    }

    function logBytes6(bytes6 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
    }

    function logBytes7(bytes7 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
    }

    function logBytes8(bytes8 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
    }

    function logBytes9(bytes9 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
    }

    function logBytes10(bytes10 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
    }

    function logBytes11(bytes11 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
    }

    function logBytes12(bytes12 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
    }

    function logBytes13(bytes13 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
    }

    function logBytes14(bytes14 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
    }

    function logBytes15(bytes15 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
    }

    function logBytes16(bytes16 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
    }

    function logBytes17(bytes17 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
    }

    function logBytes18(bytes18 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
    }

    function logBytes19(bytes19 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
    }

    function logBytes20(bytes20 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
    }

    function logBytes21(bytes21 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
    }

    function logBytes22(bytes22 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
    }

    function logBytes23(bytes23 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
    }

    function logBytes24(bytes24 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
    }

    function logBytes25(bytes25 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
    }

    function logBytes26(bytes26 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
    }

    function logBytes27(bytes27 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
    }

    function logBytes28(bytes28 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
    }

    function logBytes29(bytes29 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
    }

    function logBytes30(bytes30 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
    }

    function logBytes31(bytes31 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
    }

    function logBytes32(bytes32 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
    }

    function log(uint256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
    }

    function log(int256 p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
    }

    function log(string memory p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string)", p0));
    }

    function log(bool p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
    }

    function log(address p0) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address)", p0));
    }

    function log(uint256 p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
    }

    function log(uint256 p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
    }

    function log(uint256 p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
    }

    function log(uint256 p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
    }

    function log(string memory p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
    }

    function log(string memory p0, int256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1));
    }

    function log(string memory p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
    }

    function log(string memory p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
    }

    function log(string memory p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
    }

    function log(bool p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
    }

    function log(bool p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
    }

    function log(bool p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
    }

    function log(bool p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
    }

    function log(address p0, uint256 p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
    }

    function log(address p0, string memory p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
    }

    function log(address p0, bool p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
    }

    function log(address p0, address p1) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
    }

    function log(uint256 p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
    }

    function log(uint256 p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
    }

    function log(uint256 p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
    }

    function log(uint256 p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
    }

    function log(string memory p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
    }

    function log(string memory p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
    }

    function log(string memory p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
    }

    function log(string memory p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
    }

    function log(string memory p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
    }

    function log(string memory p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
    }

    function log(string memory p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
    }

    function log(bool p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
    }

    function log(bool p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
    }

    function log(bool p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
    }

    function log(bool p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
    }

    function log(bool p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
    }

    function log(bool p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
    }

    function log(bool p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
    }

    function log(bool p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
    }

    function log(bool p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
    }

    function log(bool p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
    }

    function log(address p0, uint256 p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
    }

    function log(address p0, string memory p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
    }

    function log(address p0, string memory p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
    }

    function log(address p0, string memory p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
    }

    function log(address p0, string memory p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
    }

    function log(address p0, bool p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
    }

    function log(address p0, bool p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
    }

    function log(address p0, bool p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
    }

    function log(address p0, bool p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
    }

    function log(address p0, address p1, uint256 p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
    }

    function log(address p0, address p1, string memory p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
    }

    function log(address p0, address p1, bool p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
    }

    function log(address p0, address p1, address p2) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
    }

    function log(uint256 p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
    }

    function log(string memory p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
    }

    function log(bool p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, uint256 p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, string memory p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, bool p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, uint256 p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, string memory p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, bool p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, uint256 p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, string memory p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, bool p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
    }

    function log(address p0, address p1, address p2, address p3) internal pure {
        _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
    }
}

File 4 of 5 : Quoter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

interface IPancakeRouter {
    function WETH() external view returns (address);
    function getAmountsOut(uint256 amountIn, address[] memory path) external view returns (uint256[] memory amounts);
}

contract Quoter {
    IPancakeRouter public pancakeRouter;
    address public usdc;
    address public weth;
    constructor(address _pancakeRouter, address _usdc) {
        pancakeRouter = IPancakeRouter(_pancakeRouter);
        usdc = _usdc;
    }

    function getUSDCToBNBAmount(uint256 usdcAmount) public view returns (uint256) {
        address[] memory path = new address[](2);
        path[0] = usdc;
        path[1] = pancakeRouter.WETH();
        uint256[] memory amounts = pancakeRouter.getAmountsOut(usdcAmount, path);
        return amounts[1];
    }

    function getBNBToUSDCAmount(uint256 bnbAmount) public view returns (uint256) {
        address[] memory path = new address[](2);
        path[0] = pancakeRouter.WETH();
        path[1] = usdc;
        uint256[] memory amounts = pancakeRouter.getAmountsOut(bnbAmount, path);
        return amounts[1];
    }
}

File 5 of 5 : Qualifier.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract Qualifier {
  address public owner;
  // userId => level => blocked
  mapping(uint256 => mapping(uint256 => bool)) public blockedUsers;

  mapping(address => bool) public adminUsers;

  modifier onlyAdmin() {
    require(adminUsers[msg.sender], "Not an admin");
    _;
  }

  modifier onlyOwner() {
    require(msg.sender == owner, "Not an owner");
    _;
  }

  constructor() {
    owner = msg.sender;
    adminUsers[msg.sender] = true;
  }



  function canUserWithdraw(uint256 userId, uint256 level) public view returns (bool)  {
    return blockedUsers[userId][level] == false;
  }

  function blockUser(uint256 userId, uint256 level) public onlyAdmin {
    blockedUsers[userId][level] = true;
  }

  function blockUserForAllLevels(uint256 userId) public onlyAdmin {
    for (uint256 i = 1; i <= 20; i++) {
      blockedUsers[userId][i] = true;
    }
  }

  function unblockUser(uint256 userId, uint256 level) public onlyAdmin {
    blockedUsers[userId][level] = false;
  }

  function unblockUserForAllLevels(uint256 userId) public onlyAdmin {
    for (uint256 i = 1; i <= 20; i++) {
      blockedUsers[userId][i] = false;
    }
  }

  function addAdmin(address admin) public onlyOwner {
    adminUsers[admin] = true;
  }

  function removeAdmin(address admin) public onlyOwner {
    adminUsers[admin] = false;
  }
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "ds-test/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/",
    "solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"userId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"level","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AvalanchePayout","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"userId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"userId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"level","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"earnerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MatrixPayout","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"userId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"level","type":"uint256"}],"name":"NewLevel","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"userId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"uplineId","type":"uint256"}],"name":"NewUser","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"userId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"downlineId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"level","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PrestigeLevelEarning","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"userId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"level","type":"uint256"}],"name":"Recycle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"userId","type":"uint256"},{"indexed":false,"internalType":"address","name":"oldWallet","type":"address"},{"indexed":false,"internalType":"address","name":"newWallet","type":"address"}],"name":"WalletChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"userId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"avalancheConfigs","outputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"g1SlotPayout","type":"uint256"},{"internalType":"uint256","name":"g2SlotPayout","type":"uint256"},{"internalType":"uint256","name":"miningPayout","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"beginOfDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"uint256","name":"uplineId","type":"uint256"},{"internalType":"uint256","name":"random","type":"uint256"}],"name":"buyAvalancheSlot","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"canWithdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"address","name":"newWallet","type":"address"}],"name":"changeWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_miningWallet","type":"address"}],"name":"configure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"currentRecycling","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"searchDepth","type":"uint256"}],"name":"firstPrestigeAncestor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getAccountsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"uplineID","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"bool","name":"traverseDown","type":"bool"},{"internalType":"uint256","name":"random","type":"uint256"}],"name":"getAvailableUplineInMatrix","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"level","type":"uint256"}],"name":"getAvalancheConfig","outputs":[{"components":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"g1SlotPayout","type":"uint256"},{"internalType":"uint256","name":"g2SlotPayout","type":"uint256"},{"internalType":"uint256","name":"miningPayout","type":"uint256"}],"internalType":"struct Uptown.AvalancheConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"}],"name":"getAvalancheMatrix","outputs":[{"internalType":"uint256","name":"upline","type":"uint256"},{"internalType":"uint256","name":"slot1","type":"uint256"},{"internalType":"uint256","name":"slot2","type":"uint256"},{"internalType":"uint256","name":"slot3","type":"uint256"},{"internalType":"uint256","name":"slot4","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"level","type":"uint256"}],"name":"getAvalancheSlotBnbAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"getCanRecycle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"getGlobalReferralCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"level","type":"uint256"}],"name":"getLevelConfig","outputs":[{"components":[{"internalType":"uint256","name":"directReferralRequirement","type":"uint256"},{"internalType":"uint256","name":"globalReferralRequirement","type":"uint256"},{"internalType":"uint256","name":"dailyEarnings","type":"uint256"},{"internalType":"uint256","name":"earningDays","type":"uint256"},{"internalType":"uint256","name":"maxRecycling","type":"uint256"},{"internalType":"uint256","name":"recyclingFee","type":"uint256"}],"internalType":"struct Uptown.PlanConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"}],"name":"getPrestigeMatrix","outputs":[{"internalType":"uint256","name":"upline","type":"uint256"},{"internalType":"uint256","name":"left","type":"uint256"},{"internalType":"uint256","name":"leftLevel","type":"uint256"},{"internalType":"uint256","name":"right","type":"uint256"},{"internalType":"uint256","name":"rightLevel","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrestigeRegistrationBnbAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userID","type":"uint256"},{"internalType":"uint256","name":"startIndex","type":"uint256"}],"name":"getReferrals","outputs":[{"internalType":"uint256[20]","name":"","type":"uint256[20]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegistrationBnbAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdcAmount","type":"uint256"}],"name":"getUSDCToBNBAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"getUserLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getUserLevelAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"}],"name":"hasEmptyLegs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_miningWallet","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"uplineId","type":"uint256"},{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"generation","type":"uint256"}],"name":"isADownline","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"address","name":"addressToCheck","type":"address"}],"name":"isApprovedAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"}],"name":"pendingAvalancheEarning","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"pendingEarnings","outputs":[{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256[]","name":"daysInLevel","type":"uint256[]"},{"internalType":"uint256[]","name":"levels","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"planConfigs","outputs":[{"internalType":"uint256","name":"directReferralRequirement","type":"uint256"},{"internalType":"uint256","name":"globalReferralRequirement","type":"uint256"},{"internalType":"uint256","name":"dailyEarnings","type":"uint256"},{"internalType":"uint256","name":"earningDays","type":"uint256"},{"internalType":"uint256","name":"maxRecycling","type":"uint256"},{"internalType":"uint256","name":"recyclingFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prestigeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"prestigeLevelEarning","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prestigeRegistrationFeeUSD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"recycle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"uplineID","type":"uint256"},{"internalType":"uint256","name":"matrixUplineId","type":"uint256"},{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"no","type":"uint256"}],"name":"registerMultipleAccounts","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"uplineId","type":"uint256"},{"internalType":"uint256","name":"random","type":"uint256"}],"name":"registerPrestigeUser","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"uplineId","type":"uint256"},{"internalType":"uint256","name":"matrixUplineId","type":"uint256"},{"internalType":"address","name":"addr","type":"address"}],"name":"registerUser","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"registrationFeeUSD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"level","type":"uint256"},{"internalType":"bool","name":"payG2","type":"bool"}],"name":"sendAvalanchePayout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"address","name":"addressToApprove","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_miningWallet","type":"address"}],"name":"setMiningWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_prestigeRegistrationFeeUSD","type":"uint256"}],"name":"setPrestigeRegistrationFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_qualifier","type":"address"}],"name":"setQualifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_registrationFeeUSD","type":"uint256"}],"name":"setRegistrationFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"setSwapRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_traversalDept","type":"uint256"}],"name":"setTraversalDept","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"today","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUsers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"userCountAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"users","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"uplineId","type":"uint256"},{"internalType":"uint256","name":"referralCount","type":"uint256"},{"internalType":"uint256","name":"availableBalance","type":"uint256"},{"internalType":"uint256","name":"lastWithdrawalAt","type":"uint256"},{"internalType":"uint256","name":"prestigeLevel","type":"uint256"},{"internalType":"uint256","name":"avalancheLevel","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"},{"internalType":"uint256","name":"matrixUplineId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"withdrawEarnings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"userId","type":"uint256"}],"name":"withdrawableEarnings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

6080604052348015600e575f5ffd5b506158458061001c5f395ff3fe60806040526004361061035b575f3560e01c80638a334636116101bd578063ca5bb8ae116100f2578063ed1ba98111610092578063f851a4401161006d578063f851a44014610b8b578063fbe85f0614610bc2578063fe3265b414610be1578063ffd5224c14610c00575f5ffd5b8063ed1ba98114610b43578063eef1f20b14610b58578063efd6ff9e14610b6c575f5ffd5b8063d5c7362d116100cd578063d5c7362d14610ab1578063d670e92614610adc578063d785960b14610af0578063dd1c35bc14610b24575f5ffd5b8063ca5bb8ae14610a21578063cdc6813d14610a40578063ce99952e14610a92575f5ffd5b8063b6b55f251161015d578063bff1f9e111610138578063bff1f9e1146109b0578063c320c727146109c4578063c4d66de8146109e3578063c69634fb14610a02575f5ffd5b8063b6b55f251461096a578063b74e452b1461097d578063b9f2f79914610991575f5ffd5b8063a538499511610198578063a5384995146108eb578063ae24e5e81461090a578063b033dfaf1461091d578063b5ebe2da14610930575f5ffd5b80638a334636146108815780638b6e665b146108a057806393ca9ab1146108bf575f5ffd5b806341273657116102935780636e70096e1161023357806375cb26721161020e57806375cb2672146108055780637a239680146108245780637ae234a21461084357806382a1ca6f14610862575f5ffd5b80636e70096e146107b4578063704b6c02146107d35780637492d843146107f2575f5ffd5b80634f4dd0841161026e5780634f4dd084146106fc578063569f41b01461071b578063571ca7ae146107815780635767238a146107a0575f5ffd5b806341273657146106435780634d31bc17146106625780634e9c418314610681575f5ffd5b80631fc145bc116102fe57806334ad3b1a116102d957806334ad3b1a14610520578063365b98b21461053f57806338f8fe83146105f95780633c660c6514610618575f5ffd5b80631fc145bc1461048c578063221399b7146104ab57806328796f55146104c0575f5ffd5b8063140c0b4f11610339578063140c0b4f146103f2578063158c784b1461040757806318a3a3021461044e5780631bd5dde11461046d575f5ffd5b8063071b61521461035f5780630cf6ac571461039657806312b9a8c3146103c5575b5f5ffd5b34801561036a575f5ffd5b5061037e610379366004615257565b610c6a565b60405161038d939291906152a8565b60405180910390f35b3480156103a1575f5ffd5b506103b56103b03660046152f7565b61108b565b604051901515815260200161038d565b3480156103d0575f5ffd5b506103e46103df366004615257565b6110ba565b60405190815260200161038d565b610405610400366004615321565b6110e9565b005b348015610412575f5ffd5b50610426610421366004615350565b61142e565b604080519586526020860194909452928401919091526060830152608082015260a00161038d565b348015610459575f5ffd5b506103e4610468366004615370565b6115f4565b348015610478575f5ffd5b50610405610487366004615257565b61161f565b348015610497575f5ffd5b506103e46104a63660046153a8565b61164e565b3480156104b6575f5ffd5b506103e460015481565b3480156104cb575f5ffd5b506105006104da366004615257565b60096020525f908152604090208054600182015460028301546003909301549192909184565b60408051948552602085019390935291830152606082015260800161038d565b34801561052b575f5ffd5b506103e461053a366004615350565b611a3c565b34801561054a575f5ffd5b506105ac610559366004615257565b600a6020525f908152604090208054600182015460028301546003840154600485015460058601546006870154600788015460089098015496979596949593949293919290916001600160a01b03169089565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c08401526001600160a01b031660e08301526101008201526101200161038d565b348015610604575f5ffd5b506103e4610613366004615257565b611c08565b348015610623575f5ffd5b506103e4610632366004615257565b600d6020525f908152604090205481565b34801561064e575f5ffd5b5061040561065d3660046153e4565b611c13565b34801561066d575f5ffd5b506103b561067c3660046153fd565b611c5f565b34801561068c575f5ffd5b506106cf61069b366004615257565b60086020525f9081526040902080546001820154600283015460038401546004850154600590950154939492939192909186565b604080519687526020870195909552938501929092526060840152608083015260a082015260c00161038d565b348015610707575f5ffd5b50610405610716366004615426565b611cc2565b348015610726575f5ffd5b50610426610735366004615350565b5f918252600a6020818152604080852093855260109093018152828420600181015460028201546003909201548287529390925283852060059081015484875294909520909401549094565b34801561078c575f5ffd5b506103b561079b366004615257565b6120b2565b3480156107ab575f5ffd5b506103e4612136565b3480156107bf575f5ffd5b506104056107ce366004615257565b612146565b3480156107de575f5ffd5b506104056107ed3660046153e4565b612316565b6104056108003660046153fd565b612362565b348015610810575f5ffd5b5061040561081f3660046153e4565b61271a565b34801561082f575f5ffd5b506103b561083e366004615350565b612cef565b34801561084e575f5ffd5b506103e461085d366004615257565b612d3a565b34801561086d575f5ffd5b506103e461087c366004615257565b612d49565b34801561088c575f5ffd5b5061040561089b3660046152f7565b612e87565b3480156108ab575f5ffd5b506104056108ba366004615257565b6130d6565b3480156108ca575f5ffd5b506108de6108d9366004615350565b613105565b60405161038d919061545c565b3480156108f6575f5ffd5b506104056109053660046153e4565b6131b3565b61040561091836600461548d565b6131ff565b61040561092b3660046154b7565b6132e4565b34801561093b575f5ffd5b506103e461094a366004615350565b5f918252600a602090815260408084209284526012909201905290205490565b610405610978366004615257565b61342f565b348015610988575f5ffd5b506103e46134d5565b34801561099c575f5ffd5b506103e46109ab366004615257565b6134df565b3480156109bb575f5ffd5b506002546103e4565b3480156109cf575f5ffd5b506104056109de366004615257565b61354a565b3480156109ee575f5ffd5b506104056109fd3660046153e4565b613578565b348015610a0d575f5ffd5b506103e4610a1c366004615350565b61367c565b348015610a2c575f5ffd5b50610405610a3b3660046153e4565b6136eb565b348015610a4b575f5ffd5b50610a5f610a5a366004615257565b613737565b60405161038d91908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b348015610a9d575f5ffd5b50610405610aac3660046154e9565b6137a2565b348015610abc575f5ffd5b506103e4610acb366004615257565b600c6020525f908152604090205481565b348015610ae7575f5ffd5b506103e45f5481565b348015610afb575f5ffd5b506103e4610b0a3660046153e4565b6001600160a01b03165f908152600b602052604090205490565b348015610b2f575f5ffd5b50610405610b3e366004615257565b613812565b348015610b4e575f5ffd5b506103e460045481565b348015610b63575f5ffd5b506103e4613948565b348015610b77575f5ffd5b506103e4610b86366004615257565b613954565b348015610b96575f5ffd5b50600654610baa906001600160a01b031681565b6040516001600160a01b03909116815260200161038d565b348015610bcd575f5ffd5b506103b5610bdc366004615257565b61396c565b348015610bec575f5ffd5b506103e4610bfb366004615257565b613a46565b348015610c0b575f5ffd5b50610c1f610c1a366004615257565b613a5d565b60405161038d91905f60c082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b5f818152600a602052604090206003810154906060908190610c8a6134d5565b610c978260040154613954565b03610ca25750611084565b60048101545f9081908190610cbf90610b8690620151809061552f565b90505b610cca6134d5565b811015610d41575f610cdc8983611a3c565b9050801580610d0857505f81815260086020908152604080832060030154600d89019092529091205410155b15610d135750610d2d565b808314610d2b5783610d2481615542565b9450508092505b505b610d3a620151808261552f565b9050610cc2565b508167ffffffffffffffff811115610d5b57610d5b61555a565b604051908082528060200260200182016040528015610d84578160200160208202803683370190505b5094508167ffffffffffffffff811115610da057610da061555a565b604051908082528060200260200182016040528015610dc9578160200160208202803683370190505b509350815f03610eae575f610de08861053a6134d5565b90505f81118015610e0d57505f81815260086020908152604080832060030154600d880190925290912054105b15610ea5575f62015180610e248660040154613954565b610e2c6134d5565b610e36919061556e565b610e409190615595565b5f838152600d8701602090815260408083205460089092528220600301549293509091610e6d919061556e565b905080821115610e7b578091505b5f83815260086020526040902060020154610e9690836155a8565b610ea0908a61552f565b985050505b50505050611084565b5f5f5f5f62015180610ec38860040154613954565b610ecd919061552f565b90505b610ed86134d5565b811161101d575f610ee98c83611a3c565b9050805f03610ef85750611009565b848103610f5f575f81815260086020908152604080832060030154600d8c0190925290912054610f2990869061552f565b1015610f5a575f81815260086020526040902060020154610f4a908c61552f565b9a50610f5760018561552f565b93505b611007565b8415610fb057838a8481518110610f7857610f786155bf565b60200260200101818152505084898481518110610f9757610f976155bf565b602090810291909101015282610fac81615542565b9350505b5f81815260086020908152604080832060030154600d8c0190925282205492965090945085911015611007575f81815260086020526040902060020154610ff7908c61552f565b9a5061100460018561552f565b93505b505b611016620151808261552f565b9050610ed0565b50821580159061102c57508481105b156110705781888281518110611044576110446155bf565b60200260200101818152505082878281518110611063576110636155bf565b6020026020010181815250505b61107c8a61053a6134d5565b505050505050505b9193909250565b5f828152600a602090815260408083206001600160a01b0385168452600b0190915290205460ff165b92915050565b5f818152600a60205260408120600c01816110d484611c08565b81526020019081526020015f20549050919050565b5f838152600960205260409020546111535760405162461bcd60e51b815260206004820152602260248201527f4176616c616e63686520726567697374726174696f6e20666565206e6f742073604482015261195d60f21b60648201526084015b60405180910390fd5b5f8411801561116457506002548411155b6111a25760405162461bcd60e51b815260206004820152600f60248201526e125b9d985b1a59081d5cd95c881251608a1b604482015260640161114a565b8115806111be57505f848152600a602052604090206001015482145b806111ea57505f828152600a6020526040902060060154158015906111ea57506111ea8285600a611c5f565b6112365760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f742075736520746869732075706c696e6520494400000000000000604482015260640161114a565b5f61124085610c6a565b50505f858152600960205260408120549192509061125d906134df565b9050803410158061126e5750808210155b61128a5760405162461bcd60e51b815260040161114a906155d3565b5f8511801561129a575060148511155b6112d65760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081b195d995b609a1b604482015260640161114a565b5f868152600a602052604090206112ee60018761556e565b8160060154146113385760405162461bcd60e51b815260206004820152601560248201527410d85b9b9bdd08189d5e481d1a1a5cc81b195d995b605a1b604482015260640161114a565b845f0361134757806001015494505b345f036113d85761135787613ae8565b5f86815260096020526040902054600382015410156113af5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b604482015260640161114a565b5f86815260096020526040812054600383018054919290916113d290849061556e565b90915550505b6113e88787878760018b11613bab565b8134111561142557336108fc6113fe843461556e565b6040518115909202915f818181858888f19350505050158015611423573d5f5f3e3d5ffd5b505b50505050505050565b5f828152600a6020908152604080832084845260118101909252822054829182918291829160ff1661146f575f5f5f5f5f95509550955095509550506115ea565b5f8781526011820160205260408120600181015460029091015490975090036114a457505f93508392508291508190506115ea565b5f878152601182016020526040812060020180549091906114c7576114c76155bf565b5f9182526020808320909101548983526011840190915260409091206002015490955060010361150057505f92508291508190506115ea565b5f878152601182016020526040902060020180546001908110611525576115256155bf565b905f5260205f2001549350806011015f8881526020019081526020015f206002018054905060020361155d57505f91508190506115ea565b806011015f8881526020019081526020015f20600201600281548110611585576115856155bf565b5f918252602080832090910154898352601184019091526040909120600201549093506003036115b857505f90506115ea565b5f8781526011820160205260409020600201805460039081106115dd576115dd6155bf565b905f5260205f2001549150505b9295509295909350565b600b602052815f5260405f20818154811061160d575f80fd5b905f5260205f20015f91509150505481565b6006546001600160a01b031633146116495760405162461bcd60e51b815260040161114a9061560a565b600355565b5f5f85116116835760405162461bcd60e51b81526020600482015260026024820152615a5560f01b604482015260640161114a565b5f858152600a6020908152604080832087845260100190915290205460ff166116d75760405162461bcd60e51b815260040161114a906020808252600490820152630554e49560e41b604082015260600190565b6116e18585612cef565b156116ed575083611a34565b5f600160035460026116ff919061572e565b611709919061556e565b90505f60018060035461171c919061556e565b61172790600261572e565b611731919061556e565b90505f8267ffffffffffffffff81111561174d5761174d61555a565b604051908082528060200260200182016040528015611776578160200160208202803683370190505b505f898152600a602090815260408083208b84526010019091528120600201548251929350918391906117ab576117ab6155bf565b6020908102919091018101919091525f898152600a825260408082208a835260100190925220600301548151829060019081106117ea576117ea6155bf565b60209081029190910101525f805b8481101561194f57611823838281518110611815576118156155bf565b60200260200101518a612cef565b156118495782818151811061183a5761183a6155bf565b6020026020010151915061194f565b8381101561194757600a5f848381518110611866576118666155bf565b602002602001015181526020019081526020015f206010015f8a81526020019081526020015f20600201548382600161189f919061552f565b6118aa9060026155a8565b815181106118ba576118ba6155bf565b602002602001018181525050600a5f8483815181106118db576118db6155bf565b602002602001015181526020019081526020015f206010015f8a81526020019081526020015f206003015483826001611914919061552f565b61191f9060026155a8565b61192a90600161552f565b8151811061193a5761193a6155bf565b6020026020010181815250505b6001016117f8565b508015801561195b5750865b15611a2e578286101561197557611972838761552f565b95505b8386111561198a576119878685615739565b95505b6119af82878151811061199f5761199f6155bf565b6020026020010151895f8961164e565b9050805f03611a2e57825b848110156119f8576119e78382815181106119d7576119d76155bf565b60200260200101518a5f8a61164e565b9150815f036119f8576001016119ba565b505f8111611a2e5760405162461bcd60e51b815260206004820152600360248201526229272360e91b604482015260640161114a565b93505050505b949350505050565b5f5f611a4783613954565b5f858152600a602052604081206009810154929350919003611a6d575f925050506110b4565b5f828152600c6020526040812054600e54909190611a8d9060019061556e565b90505b85600e8281548110611aa457611aa46155bf565b905f5260205f20015411611ad557600e8181548110611ac557611ac56155bf565b905f5260205f2001549150611ae7565b80611adf8161574c565b915050611a90565b505f611af3878361556e565b5f888152600a602081905260408220600901549086015492935091611b1a9060019061556e565b90505b8785600a018281548110611b3357611b336155bf565b905f5260205f20015411611b7757600c5f86600a018381548110611b5957611b596155bf565b905f5260205f20015481526020019081526020015f20549250611b89565b80611b818161574c565b915050611b1d565b506005545b60018110611bfa575f8181526008602052604090205415611be8575f818152600860205260409020548210801590611bd657505f818152600860205260409020600101548310155b15611be85795506110b4945050505050565b80611bf28161574c565b915050611b8e565b505f98975050505050505050565b5f6110b48242611a3c565b6006546001600160a01b03163314611c3d5760405162461bcd60e51b815260040161114a9061560a565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b5f805b82811015611cb6575f848152600a6020526040902060010154859003611c8c576001915050611cbb565b5f938452600a602052604084206001015493849003611cae575f915050611cbb565b600101611c62565b505f90505b9392505050565b5f838152600a6020908152604080832085845260110190915290205460ff16611cfd5760405162461bcd60e51b815260040161114a90615761565b5f838152600a602090815260408083208584526011810190925290912054610100900460ff16158015611d4657505f83815260118201602052604090205462010000900460ff16155b15611d9f576007545f848152600960205260409020600301546001600160a01b03909116906108fc90611d78906134df565b6040518115909202915f818181858888f19350505050158015611d9d573d5f5f3e3d5ffd5b505b5f8381526011820160205260408120600101549003611dbe5750505050565b5f838152601182016020818152604080842060018101548552600a83529084209387905291905254610100900460ff16611f3f575f8481526009602052604090206001015483158015611e2757505f85815260118401602052604090205462010000900460ff16155b15611e68575f85815260096020526040902060020154611e47908261552f565b5f8681526011850160205260409020805462ff000019166201000017905590505b84826006015410611eb85760078201546001600160a01b03166108fc611e8d836134df565b6040518115909202915f818181858888f19350505050158015611eb2573d5f5f3e3d5ffd5b50611edd565b5f85815260128301602052604081208054839290611ed790849061552f565b90915550505b5f858152601184016020908152604091829020805461ff001916610100179055835482518981529182018890529181018390527f5fc385b29a62693f017f59cb50d2c3e8495ba1b8b01c0c26c19f87153ef3d4d49060600160405180910390a2505b5f8481526011820160205260408120600101549003611f5f575050505050565b5f848152601182810160209081526040808420600101548452600a82528084208885529286019091529091205462010000900460ff16158015611f9f5750835b156120aa57848160060154106120095760078101545f868152600960205260409020600201546001600160a01b03909116906108fc90611fde906134df565b6040518115909202915f818181858888f19350505050158015612003573d5f5f3e3d5ffd5b5061203d565b5f8581526009602090815260408083206002015460128501909252822080549192909161203790849061552f565b90915550505b5f8581526011840160209081526040808320805462ff0000191662010000179055835460098352928190206002015481518a8152928301899052908201527f5fc385b29a62693f017f59cb50d2c3e8495ba1b8b01c0c26c19f87153ef3d4d4906060015b60405180910390a25b505050505050565b5f818152600a60205260408120816120c984610c6a565b5050905060085f6120d986611c08565b81526020019081526020015f20600501548110158015611a34575060085f61210086611c08565b81526020019081526020015f206004015482600c015f61211f87611c08565b81526020019081526020015f205410949350505050565b5f6121415f546134df565b905090565b5f818152600a60205260409020600701546001600160a01b03163314806121725750612172813361108b565b61218e5760405162461bcd60e51b815260040161114a906157a2565b5f61219882612d49565b116121e55760405162461bcd60e51b815260206004820152601860248201527f4e6f20776974686472617761626c65206561726e696e67730000000000000000604482015260640161114a565b6121ee8161396c565b61222c5760405162461bcd60e51b815260206004820152600f60248201526e43616e6e6f7420776974686472617760881b604482015260640161114a565b61223581613ae8565b5f818152600a60205260409020600301546122895760405162461bcd60e51b81526020600482015260146024820152734e6f20617661696c61626c652062616c616e636560601b604482015260640161114a565b5f818152600a60205260408120600301805490829055906122a9826134df565b604051909150339082156108fc029083905f818181858888f193505050501580156122d6573d5f5f3e3d5ffd5b50827fbf2ed60bd5b5965d685680c01195c9514e4382e28e3a5a2d2d5244bf59411b938360405161230991815260200190565b60405180910390a2505050565b6006546001600160a01b031633146123405760405162461bcd60e51b815260040161114a9061560a565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b5f600154116123bd5760405162461bcd60e51b815260206004820152602160248201527f507265737469676520726567697374726174696f6e20666565206e6f742073656044820152601d60fa1b606482015260840161114a565b5f831180156123ce57506002548311155b61240c5760405162461bcd60e51b815260206004820152600f60248201526e125b9d985b1a59081d5cd95c881251608a1b604482015260640161114a565b6002548211156124525760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d5c1b1a5b99481251607a1b604482015260640161114a565b8282036124ab5760405162461bcd60e51b815260206004820152602160248201527f55706c696e652063616e6e6f74206265207468652073616d65206173207573656044820152603960f91b606482015260840161114a565b815f036124c0576124bd83600a61367c565b91505b5f838152600a602052604090206124d684613ae8565b5f6124e26001546134df565b905060015482600301541015806124f95750803410155b61253c5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b604482015260640161114a565b60058201541561258e5760405162461bcd60e51b815260206004820152601d60248201527f5573657220616c726561647920696e20707265737469676520706c616e000000604482015260640161114a565b60016005830155345f036125b757600154826003015f8282546125b1919061556e565b90915550505b5f6125c5856001808761164e565b60015f818152601080870160209081526040808420805460ff191686178155850186905560058901859055858452600a82528084209484529390910190529081206002015491925003612639575f818152600a6020908152604080832060018452601001909152902060020186905561265c565b5f818152600a602090815260408083206001845260100190915290206003018690555b5f612668876001613dc1565b5f818152600a6020908152604080832060018452600f01909152902054909150600403612699576126998186613f43565b823411156126d657336108fc6126af853461556e565b6040518115909202915f818181858888f193505050501580156126d4573d5f5f3e3d5ffd5b505b867f16d15f32051bc9628b984a7b677e93ad6c5c3caffcbca5c97855e392d11f92cd600160405161270991815260200190565b60405180910390a250505050505050565b6006546001600160a01b0316156127685760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e4818dbdb999a59dd5c995960721b604482015260640161114a565b600680546001600160a01b031990811633908117909255600780546001600160a01b038516908316179055600f805482167360be6dc7052d37d4649503345fe8d0ace2145c6c1790556010805482167358ca1a9169af3a9ffb59166c578548011cc74c1a179055624c4b405f8181556001918255600a60038190558282526020527fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bc78281557fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bc8919091557fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bce805490931690931790915560147fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bcc8190557fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bcd55427fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bcb5590815b60148111612900575f8181526010830160205260409020805460ff19166001179055806128f881615542565b9150506128cc565b5060015b60148111612938575f8181526011830160205260409020805460ff191660011790558061293081615542565b915050612904565b50335f908152600b602090815260408220805460018101825590835290822001839055600c906129666134d5565b81526020019081526020015f205f81548092919061298390615542565b90915550506040515f9083907f296b61d41a33e6ea94875300e90a38cc34bf24ede90c106e6479fe3fc26ce38e908390a360016002556129c16140e0565b612ce2600d602052622625a07ffd54ff1ed53f34a900b24c5ba64f85761163b5d82d98a47b9bd80e45466993c555624c4b407f10a81eed9d63d16face5e76357905348e6253d3394086026bb2bf2145d7cc24955629896807f26b4a10d0f0b04925c23bd4480ee147c916e5e87a7d68206a533dad160ac81e2556301312d007fafafe8948a4ed9d478b1e9a5780b119b5edd00ea7d07bc35bef7c814824eb94b556302625a007fa5049387d9cb649c59f4bda666105ba636c2a103d8e2b232ba4d125737cd2149556304c4b4007fa48544818c2c710afa9849c61ec9c60e8acdb3eaa2885f33b37e118cc8fd04ac5563098968007fb91432bedff11256dbe14161d3606a2657bc9dacf8742f6b817d871dd53fb97655631312d0007f0b705463cf5f7356780ee6e96132d37412c1b5816a4d207b8dcd42c34976745755632625a0007f7b6f1ece0cbe5122a575776770f0494c2d57ed2a50e36c2ba0d811d70ee03b6455634c4b40007fba9d637f252776d5e1b3534bbd7554a1265a4ef0539d9ca50abe118598a6973c5563989680007f52c2086a203f40e709b1346663401f6c737b2fce5878601fcf875b047fed5fb6556401312d00007fe399baa2fabbab2a0309615b124a802277bab50ec0ca3452a00889e216c4b902556402625a00007fe0af3347aa7e5af384208c9d29458f902f0ceddbc90963608afa77235658b360556404c4b400007f154ef5b709dcdc8b49a2af6408b8a1af209c39b5fa796f03680257c97692546e556409896800007f52fb6a28cb3c239105f8f829bc7376f939b6bfb040c470bdc2bda0af2e784b9455641312d000007f01a49be1e7ea084651fd665847100d28826db0b17160863a99534933cbbd2dce55642625a000007f6fbf3b49b523bc27464b7dbfa6311951351b1d3efd07aa2ee4d1ce319801a0ce55644c4b4000007f0a206051e911305809ddd48cf2baa7ead2c7fb038e505e1d02f9e6c2ce72930c556498968000007f1341e158d1184a2eb4edb96b016176e1c5ad075baae6651557fb93ae3925007a5560145f526501312d0000007fdd2af3330d298808a303a10bc360333536e7697099bb3fe7200b0c272de6655855565b612cea6142d2565b505050565b5f828152600a602090815260408083208484526010019091528120600201541580611cbb5750505f918252600a60209081526040808420928452601090920190529020600301541590565b5f816002546110b4919061556e565b5f5f5f5f612d5685610c6a565b9250925092505f612d6686611c08565b5f878152600a60209081526040808320848452600c810183528184205460089093529083206003015493945092612d9d91906155a8565b5f848152600d84016020526040902054612db7919061552f565b5f84815260086020526040902060020154612dd291906155a8565b90505f5b8551811015612e665783858281518110612df257612df26155bf565b602002602001015103612e5e5760085f868381518110612e1457612e146155bf565b602002602001015181526020019081526020015f2060020154868281518110612e3f57612e3f6155bf565b6020026020010151612e5191906155a8565b612e5b908361552f565b91505b600101612dd6565b50808611612e7b57505f979650505050505050565b50939695505050505050565b5f828152600a60205260409020600701546001600160a01b03163314612eef5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c7920757365722063616e206368616e67652077616c6c65740000000000604482015260640161114a565b5f5b5f838152600a60209081526040808320600701546001600160a01b03168352600b90915290205481101561304d575f838152600a60209081526040808320600701546001600160a01b03168352600b9091529020805484919083908110612f5a57612f5a6155bf565b905f5260205f20015403613045575f838152600a60209081526040808320600701546001600160a01b03168352600b90915290208054612f9c9060019061556e565b81548110612fac57612fac6155bf565b5f918252602080832090910154858352600a82526040808420600701546001600160a01b03168452600b9092529120805483908110612fed57612fed6155bf565b5f918252602080832090910192909255848152600a82526040808220600701546001600160a01b03168252600b9092522080548061302d5761302d6157c9565b600190038181905f5260205f20015f9055905561304d565b600101612ef1565b506001600160a01b0381165f818152600b60209081526040808320805460018101825590845282842001869055858352600a82529182902060070180546001600160a01b0319168417905581513381529081019290925283917f774cac233d75821d2683f89e643ea7031de8674eea3722260820dc5ad445282191015b60405180910390a25050565b6006546001600160a01b031633146131005760405162461bcd60e51b815260040161114a9061560a565b600155565b61310d615238565b613115615238565b5f848152600a6020526040902060090154831015611cbb575f5b600a8110156131ab575f858152600a6020526040902060090154613153858361552f565b10156131ab575f858152600a60205260409020600901613173858361552f565b81548110613183576131836155bf565b905f5260205f20015482826014811061319e5761319e6155bf565b602002015260010161312f565b509392505050565b6006546001600160a01b031633146131dd5760405162461bcd60e51b815260040161114a9061560a565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b603281111561323b5760405162461bcd60e51b8152602060048201526008602482015267544f4f5f4d414e5960c01b604482015260640161114a565b5f6132465f546134df565b905061325282826155a8565b3410156132715760405162461bcd60e51b815260040161114a906155d3565b5f5b8281101561328e576132868686866146f0565b600101613273565b5061329982826155a8565b3411156132dd57336108fc6132ae84846155a8565b6132b8903461556e565b6040518115909202915f818181858888f193505050501580156120aa573d5f5f3e3d5ffd5b5050505050565b5f5f54116133345760405162461bcd60e51b815260206004820152601860248201527f526567697374726174696f6e20666565206e6f74207365740000000000000000604482015260640161114a565b81158061336a57505f828152600a60205260409020600501541580159061336a57505f828152600a602052604090206006015415155b6133b65760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964206d61747269782075706c696e652049440000000000000000604482015260640161114a565b5f6133c15f546134df565b9050803410156133e35760405162461bcd60e51b815260040161114a906155d3565b6133ee8484846146f0565b8034111561342957336108fc613404833461556e565b6040518115909202915f818181858888f193505050501580156132dd573d5f5f3e3d5ffd5b50505050565b5f341161346f5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b604482015260640161114a565b5f613479346134df565b905080600a5f8481526020019081526020015f206003015f82825461349e919061552f565b909155505060405181815282907fa3af609bf46297028ce551832669030f9effef2b02606d02cbbcc40fe6b47c55906020016130ca565b5f61214142613954565b600f5460405163b9f2f79960e01b8152600481018390525f916001600160a01b03169063b9f2f79990602401602060405180830381865afa158015613526573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110b491906157dd565b6006546001600160a01b031633146135745760405162461bcd60e51b815260040161114a9061560a565b5f55565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f811580156135bd5750825b90505f8267ffffffffffffffff1660011480156135d95750303b155b9050811580156135e7575080155b156136055760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561362f57845460ff60401b1916600160401b1785555b83156120aa57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a1505050505050565b5f828152600a60205260408120600101545b801580159061369c57505f83115b156136e1575f818152600a6020526040902060050154156136be5790506110b4565b5f908152600a6020526040902060010154826136d98161574c565b93505061368e565b5060019392505050565b6006546001600160a01b031633146137155760405162461bcd60e51b815260040161114a9061560a565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b61375e60405180608001604052805f81526020015f81526020015f81526020015f81525090565b505f90815260096020908152604091829020825160808101845281548152600182015492810192909252600281015492820192909252600390910154606082015290565b5f838152600a60205260409020600701546001600160a01b031633146137da5760405162461bcd60e51b815260040161114a906157a2565b5f928352600a602090815260408085206001600160a01b03949094168552600b90930190529120805460ff1916911515919091179055565b5f818152600a60205260409020600701546001600160a01b0316331461384a5760405162461bcd60e51b815260040161114a906157a2565b613853816120b2565b6138905760405162461bcd60e51b815260206004820152600e60248201526d43616e6e6f742072656379636c6560901b604482015260640161114a565b5f818152600a60205260408120906138a783611c08565b90506138b283613ae8565b5f81815260086020526040812060050154600384018054919290916138d890849061556e565b90915550505f818152600c8301602052604081208054600192906138fd90849061552f565b90915550505f818152600d83016020526040808220919091555183907f87f4b7ea340c6b16973214300a3cbbb5afaf6c92389d1e81f95ffe0c07edcfb6906123099084815260200190565b5f6121416001546134df565b5f6139626201518083615739565b6110b4908361556e565b5f818152600a602052604081208161398384612d49565b90505f61398f85611c08565b90506001811180156139a457505f8360050154115b80156139b357505f8360060154115b8015613a2c5750601054604051636470be4f60e11b815260048101879052602481018390526001600160a01b039091169063c8e17c9e90604401602060405180830381865afa158015613a08573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a2c91906157f4565b15613a3c57506001949350505050565b505f949350505050565b5f818152600960205260408120546110b4906134df565b613a906040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b505f90815260086020908152604091829020825160c08101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260059091015460a082015290565b5f5f5f613af484610c6a565b925092509250825f03613b075750505050565b5f848152600a602052604081206003018054859290613b2790849061552f565b90915550505f848152600a60205260408120426004820155905b82518110156120aa57838181518110613b5c57613b5c6155bf565b602002602001015182600d015f858481518110613b7b57613b7b6155bf565b602002602001015181526020019081526020015f205f828254613b9e919061552f565b9091555050600101613b41565b5f858152600a602052604090206006810154613bc890600161552f565b8514613c225760405162461bcd60e51b8152602060048201526024808201527f4163636f756e74206e6f74207175616c696669656420666f722074686973206c604482015263195d995b60e21b606482015260840161114a565b600681018590555f613c3785876001876149c5565b5f8781526011808501602090815260408084206001808201879055815460ff19168117909155858552600a83528185208c865290930182528320600201805480840182559084529220909101899055909150869003613d3d575f818152600a6020908152604080832089845260110190915290205460ff1615613cc057613cc087876001611cc2565b5f86815260118301602052604090206002015415613d38575f5b5f878152601184016020526040902060020154811015613d36575f87815260118401602052604090206002018054613d2e919083908110613d1d57613d1d6155bf565b905f5260205f200154886001611cc2565b600101613cda565b505b613d91565b8215613d4d57613d388787614f1b565b613d918787601489108061071657505f848152600a6020526040812060110190613d788b600161552f565b815260208101919091526040015f205460ff1615611cc2565b5f818152600a60209081526040808320898452601101909152902060020154600403611425576114258185615134565b5f818152600d6020908152604080832054858452600a8352818420858552601001909252822060010154808303613dfc575f925050506110b4565b5f818152600a6020908152604080832087845260100190915281206001015490819003613e2e575f93505050506110b4565b5f818152600a60209081526040808320888452600f810190925290912054600311613e96576007546001600160a01b03166108fc613e6b866134df565b6040518115909202915f818181858888f19350505050158015613e90573d5f5f3e3d5ffd5b50613ed7565b60078101546001600160a01b03166108fc613eb0866134df565b6040518115909202915f818181858888f19350505050158015613ed5573d5f5f3e3d5ffd5b505b5f868152600f820160205260408120805460019290613ef790849061552f565b90915550506040805183815260208101869052879189917fcf56eb5ea07378aaafa39ea8fe77392671f231a384af4485a303b12f9738f372910160405180910390a35095945050505050565b81600103613f4f575050565b5f828152600a602052604081206005810154909190613f6f90600161552f565b90506001811015613fb25760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081b195d995b609a1b604482015260640161114a565b600582018190555f613fe76010840182613fcd60018661556e565b81526020019081526020015f20600101548360018761164e565b5f838152601080860160209081526040808420805460ff19166001908117825501859055848452600a8252808420878552909201905281206002015491925003614051575f818152600a602090815260408083208584526010019091529020600201859055614073565b5f818152600a6020908152604080832085845260100190915290206003018590555b5f61407e8684613dc1565b5f818152600a60209081526040808320878452600f019091529020549091506004036140ae576140ae8186613f43565b857f16d15f32051bc9628b984a7b677e93ad6c5c3caffcbca5c97855e392d11f92cd846040516120a191815260200190565b6140fa6001600460286203d09060286004624c4b406151c0565b6141116002600660966206ddd0602860035f6151c0565b614129600360086103e8620927c0602860035f6151c0565b6141416004600a611388620b71b0602860035f6151c0565b6141596005600c613a98620e7ef0602860035f6151c0565b6141716006600e6188b8621312d0602860035f6151c0565b6141896007601061d6d86216e360602860035f6151c0565b6141a260086012620186a0621c3a90602860035f6151c0565b6141bb600960146207a120621cfde0602860035f6151c0565b6141d4600a6016620b71b0622191c0602860035f6151c0565b6141ed600b6018620f42406226e8f0602860035f6151c0565b614206600c601a6216e360622b7cd0602860035f6151c0565b61421f600d601c622625a0623010b0602860035f6151c0565b614235600e601e623567e080602860035f6151c0565b61424f600f6020624c4b40630260d360602860035f6151c0565b6142686010602262e4e1c062432380602860035f6151c0565b614282601160246302faf080624c4b40602860035f6151c0565b61429c601260266308f0d18062632ea0602860035f6151c0565b6142b6601360286311e1a300627270e0602860035f6151c0565b6142d06014602a631dcd650062989680602860035f6151c0565b565b6040805160148082526102a082019092525f916020820161028080368337019050509050624c4b40815f8151811061430c5761430c6155bf565b602002602001018181525050627270e08160018151811061432f5761432f6155bf565b60200260200101818152505062aba95081600281518110614352576143526155bf565b6020026020010181815250506301017df881600381518110614376576143766155bf565b6020026020010181815250506301823cf48160048151811061439a5761439a6155bf565b6020026020010181815250506302435b6e816005815181106143be576143be6155bf565b6020026020010181815250506303650925816006815181106143e2576143e26155bf565b6020026020010181815250506332eb892b81600781518110614406576144066155bf565b602002602001018181525050634c614dc18160088151811061442a5761442a6155bf565b602002602001018181525050637291f4a18160098151811061444e5761444e6155bf565b60200260200101818152505063112f7e4b81600a81518110614472576144726155bf565b6020026020010181815250506319c73d7181600b81518110614496576144966155bf565b6020026020010181815250506326aadc2981600c815181106144ba576144ba6155bf565b602002602001018181525050633a004a3e81600d815181106144de576144de6155bf565b6020026020010181815250506357006f5d81600e81518110614502576145026155bf565b602002602001018181525050638280a70c81600f81518110614526576145266155bf565b60200260200101818152505063c3c0fa928160108151811061454a5761454a6155bf565b602002602001018181525050640125a177db8160118151811061456f5761456f6155bf565b6020026020010181815250506401b87233c881601281518110614594576145946155bf565b602002602001018181525050640294ab4dac816013815181106145b9576145b96155bf565b60209081029190910101525f5b81518110156146ec5760405180608001604052808383815181106145ec576145ec6155bf565b602002602001015181526020016103e884848151811061460e5761460e6155bf565b602002602001015161017761462391906155a8565b61462d9190615595565b81526020016103e8848481518110614647576146476155bf565b602002602001015161017761465c91906155a8565b6146669190615595565b81526020016103e8848481518110614680576146806155bf565b602002602001015160fa61469491906155a8565b61469e9190615595565b905260095f6146ae84600161552f565b815260208082019290925260409081015f208351815591830151600180840191909155908301516002830155606090920151600390910155016145c6565b5050565b5f8311801561470157506002548311155b6147415760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d5c1b1a5b99481251607a1b604482015260640161114a565b60028054905f61475083615542565b90915550506002545f818152600a602090815260408083208481556001808201899055600882018890556007820180546001600160a01b0319166001600160a01b0389169081179091554260048401558552600b845291842080549283018155845291832001839055906147c26134d5565b600280545f838152600c60209081526040808320939093558a8252600a8152918120600981018054600181018255908352928220909201879055898152910180549293509061481083615542565b90915550505f868152600a60209081526040808320848452600e01909152812080549161483c83615542565b90915550505f868152600a60208190526040822001549003614880575f868152600a60208181526040832090910180546001810182559083529120018190556148e9565b6148886134d5565b5f878152600a602081905260409091200180546148a79060019061556e565b815481106148b7576148b76155bf565b905f5260205f200154146148e9575f868152600a60208181526040832090910180546001810182559083529120018190555b600e545f0361492b57600e80546001810182555f919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01819055614991565b600e805482919061493e9060019061556e565b8154811061494e5761494e6155bf565b905f5260205f2001541461499157600e80546001810182555f919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd018190555b604051869084907f296b61d41a33e6ea94875300e90a38cc34bf24ede90c106e6479fe3fc26ce38e905f90a3505050505050565b5f5f85116149fa5760405162461bcd60e51b81526020600482015260026024820152615a5560f01b604482015260640161114a565b5f858152600a6020908152604080832087845260110190915290206002015460041115614a28575083611a34565b60408051610155808252612ac082019092526055905f908360208201612aa0803683375050505f898152600a602090815260408083208b84526011019091528120600201805492935091614a7e57614a7e6155bf565b905f5260205f200154815f81518110614a9957614a996155bf565b6020908102919091018101919091525f898152600a825260408082208a83526011019092522060020180546001908110614ad557614ad56155bf565b905f5260205f20015481600181518110614af157614af16155bf565b6020908102919091018101919091525f898152600a825260408082208a835260110190925220600290810180549091908110614b2f57614b2f6155bf565b905f5260205f20015481600281518110614b4b57614b4b6155bf565b6020908102919091018101919091525f898152600a825260408082208a83526011019092522060020180546003908110614b8757614b876155bf565b905f5260205f20015481600381518110614ba357614ba36155bf565b60209081029190910101525f805b84811015614e92576004600a5f858481518110614bd057614bd06155bf565b602002602001015181526020019081526020015f206011015f8b81526020019081526020015f20600201805490501015614c2557828181518110614c1657614c166155bf565b60200260200101519150614e92565b83811015614e8a57600a5f848381518110614c4257614c426155bf565b602002602001015181526020019081526020015f206011015f8a81526020019081526020015f206002015f81548110614c7d57614c7d6155bf565b905f5260205f20015483826001614c94919061552f565b614c9f9060046155a8565b81518110614caf57614caf6155bf565b602002602001018181525050600a5f848381518110614cd057614cd06155bf565b602002602001015181526020019081526020015f206011015f8a81526020019081526020015f20600201600181548110614d0c57614d0c6155bf565b905f5260205f20015483826001614d23919061552f565b614d2e9060046155a8565b614d3990600161552f565b81518110614d4957614d496155bf565b602002602001018181525050600a5f848381518110614d6a57614d6a6155bf565b602002602001015181526020019081526020015f206011015f8a81526020019081526020015f20600201600281548110614da657614da66155bf565b905f5260205f20015483826001614dbd919061552f565b614dc89060046155a8565b614dd390600261552f565b81518110614de357614de36155bf565b602002602001018181525050600a5f848381518110614e0457614e046155bf565b602002602001015181526020019081526020015f206011015f8a81526020019081526020015f20600201600381548110614e4057614e406155bf565b905f5260205f20015483826001614e57919061552f565b614e629060046155a8565b614e6d90600361552f565b81518110614e7d57614e7d6155bf565b6020026020010181815250505b600101614bb1565b5080158015614e9e5750865b15611a2e5782861015614eb857614eb5838761552f565b95505b83861115614ecd57614eca8685615739565b95505b614ee282878151811061199f5761199f6155bf565b9050805f03611a2e57825b848110156119f857614f0a8388815181106119d7576119d76155bf565b9150815f036119f857600101614eed565b5f828152600a6020908152604080832084845260110190915290205460ff16614f565760405162461bcd60e51b815260040161114a90615761565b60018111614fcc5760405162461bcd60e51b815260206004820152603760248201527f4d616e75616c207075726368617365206973206f6e6c7920617661696c61626c60448201527f6520666f72206c6576656c203220616e642061626f7665000000000000000000606482015260840161114a565b5f828152600a602090815260408083208484526011810190925290912054610100900460ff1615801561501557505f82815260118201602052604090205462010000900460ff16155b1561507e576007546001600160a01b03166108fc61505760095f61503a60018861556e565b81526020019081526020015f206003015460046109ab91906155a8565b6040518115909202915f818181858888f1935050505015801561507c573d5f5f3e3d5ffd5b505b601181015f61508e60018561556e565b81526020019081526020015f20600101545f036150aa57505050565b5f6009816150b960018661556e565b81526020019081526020015f206002015460046150d691906155a8565b9050600a5f60118401816150eb60018861556e565b81526020019081526020015f206001015481526020019081526020015f206007015f9054906101000a90046001600160a01b03166001600160a01b03166108fc613404836134df565b81600103615140575050565b5f828152600a60205260408120600681015490919061516090600161552f565b60015f81815260118086016020908152604080842090940154808452600a82528484208685529092019052919020549192509060ff161580156151a7575082600101548114155b156151b3575060018201545b6132dd858383875f613bab565b6040805160c0810182528781526020808201888152828401888152606084018881526080850188815260a086018881525f8f8152600890965296909420945185559151600185015551600284015551600383015551600482015590516005918201555487111561142557600587905550505050505050565b6040518061028001604052806014906020820280368337509192915050565b5f60208284031215615267575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b8281101561529e578151865260209586019590910190600101615280565b5093949350505050565b838152606060208201525f6152c0606083018561526e565b82810360408401526152d2818561526e565b9695505050505050565b80356001600160a01b03811681146152f2575f5ffd5b919050565b5f5f60408385031215615308575f5ffd5b82359150615318602084016152dc565b90509250929050565b5f5f5f5f60808587031215615334575f5ffd5b5050823594602084013594506040840135936060013592509050565b5f5f60408385031215615361575f5ffd5b50508035926020909101359150565b5f5f60408385031215615381575f5ffd5b61538a836152dc565b946020939093013593505050565b80151581146153a5575f5ffd5b50565b5f5f5f5f608085870312156153bb575f5ffd5b843593506020850135925060408501356153d481615398565b9396929550929360600135925050565b5f602082840312156153f4575f5ffd5b611cbb826152dc565b5f5f5f6060848603121561540f575f5ffd5b505081359360208301359350604090920135919050565b5f5f5f60608486031215615438575f5ffd5b8335925060208401359150604084013561545181615398565b809150509250925092565b610280810181835f5b6014811015615484578151835260209283019290910190600101615465565b50505092915050565b5f5f5f5f608085870312156154a0575f5ffd5b84359350602085013592506153d4604086016152dc565b5f5f5f606084860312156154c9575f5ffd5b83359250602084013591506154e0604085016152dc565b90509250925092565b5f5f5f606084860312156154fb575f5ffd5b8335925061550b602085016152dc565b9150604084013561545181615398565b634e487b7160e01b5f52601160045260245ffd5b808201808211156110b4576110b461551b565b5f600182016155535761555361551b565b5060010190565b634e487b7160e01b5f52604160045260245ffd5b818103818111156110b4576110b461551b565b634e487b7160e01b5f52601260045260245ffd5b5f826155a3576155a3615581565b500490565b80820281158282048414176110b4576110b461551b565b634e487b7160e01b5f52603260045260245ffd5b60208082526018908201527f496e76616c696420726567697374726174696f6e206665650000000000000000604082015260600190565b60208082526021908201527f4f6e6c792061646d696e2063616e2063616c6c20746869732066756e6374696f6040820152603760f91b606082015260800190565b6001815b60018411156156865780850481111561566a5761566a61551b565b600184161561567857908102905b60019390931c92800261564f565b935093915050565b5f8261569c575060016110b4565b816156a857505f6110b4565b81600181146156be57600281146156c8576156e4565b60019150506110b4565b60ff8411156156d9576156d961551b565b50506001821b6110b4565b5060208310610133831016604e8410600b8410161715615707575081810a6110b4565b6157135f19848461564b565b805f19048211156157265761572661551b565b029392505050565b5f611cbb838361568e565b5f8261574757615747615581565b500690565b5f8161575a5761575a61551b565b505f190190565b60208082526021908201527f55736572206e6f74207265676973746572656420696e2074686973206c6576656040820152601b60fa1b606082015260800190565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b634e487b7160e01b5f52603160045260245ffd5b5f602082840312156157ed575f5ffd5b5051919050565b5f60208284031215615804575f5ffd5b8151611cbb8161539856fea264697066735822122061c305d0ea882757e0c91f85ab198c1f83e4128ba0541c3df95e2dfc1ddf832b64736f6c634300081c0033

Deployed Bytecode

0x60806040526004361061035b575f3560e01c80638a334636116101bd578063ca5bb8ae116100f2578063ed1ba98111610092578063f851a4401161006d578063f851a44014610b8b578063fbe85f0614610bc2578063fe3265b414610be1578063ffd5224c14610c00575f5ffd5b8063ed1ba98114610b43578063eef1f20b14610b58578063efd6ff9e14610b6c575f5ffd5b8063d5c7362d116100cd578063d5c7362d14610ab1578063d670e92614610adc578063d785960b14610af0578063dd1c35bc14610b24575f5ffd5b8063ca5bb8ae14610a21578063cdc6813d14610a40578063ce99952e14610a92575f5ffd5b8063b6b55f251161015d578063bff1f9e111610138578063bff1f9e1146109b0578063c320c727146109c4578063c4d66de8146109e3578063c69634fb14610a02575f5ffd5b8063b6b55f251461096a578063b74e452b1461097d578063b9f2f79914610991575f5ffd5b8063a538499511610198578063a5384995146108eb578063ae24e5e81461090a578063b033dfaf1461091d578063b5ebe2da14610930575f5ffd5b80638a334636146108815780638b6e665b146108a057806393ca9ab1146108bf575f5ffd5b806341273657116102935780636e70096e1161023357806375cb26721161020e57806375cb2672146108055780637a239680146108245780637ae234a21461084357806382a1ca6f14610862575f5ffd5b80636e70096e146107b4578063704b6c02146107d35780637492d843146107f2575f5ffd5b80634f4dd0841161026e5780634f4dd084146106fc578063569f41b01461071b578063571ca7ae146107815780635767238a146107a0575f5ffd5b806341273657146106435780634d31bc17146106625780634e9c418314610681575f5ffd5b80631fc145bc116102fe57806334ad3b1a116102d957806334ad3b1a14610520578063365b98b21461053f57806338f8fe83146105f95780633c660c6514610618575f5ffd5b80631fc145bc1461048c578063221399b7146104ab57806328796f55146104c0575f5ffd5b8063140c0b4f11610339578063140c0b4f146103f2578063158c784b1461040757806318a3a3021461044e5780631bd5dde11461046d575f5ffd5b8063071b61521461035f5780630cf6ac571461039657806312b9a8c3146103c5575b5f5ffd5b34801561036a575f5ffd5b5061037e610379366004615257565b610c6a565b60405161038d939291906152a8565b60405180910390f35b3480156103a1575f5ffd5b506103b56103b03660046152f7565b61108b565b604051901515815260200161038d565b3480156103d0575f5ffd5b506103e46103df366004615257565b6110ba565b60405190815260200161038d565b610405610400366004615321565b6110e9565b005b348015610412575f5ffd5b50610426610421366004615350565b61142e565b604080519586526020860194909452928401919091526060830152608082015260a00161038d565b348015610459575f5ffd5b506103e4610468366004615370565b6115f4565b348015610478575f5ffd5b50610405610487366004615257565b61161f565b348015610497575f5ffd5b506103e46104a63660046153a8565b61164e565b3480156104b6575f5ffd5b506103e460015481565b3480156104cb575f5ffd5b506105006104da366004615257565b60096020525f908152604090208054600182015460028301546003909301549192909184565b60408051948552602085019390935291830152606082015260800161038d565b34801561052b575f5ffd5b506103e461053a366004615350565b611a3c565b34801561054a575f5ffd5b506105ac610559366004615257565b600a6020525f908152604090208054600182015460028301546003840154600485015460058601546006870154600788015460089098015496979596949593949293919290916001600160a01b03169089565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c08401526001600160a01b031660e08301526101008201526101200161038d565b348015610604575f5ffd5b506103e4610613366004615257565b611c08565b348015610623575f5ffd5b506103e4610632366004615257565b600d6020525f908152604090205481565b34801561064e575f5ffd5b5061040561065d3660046153e4565b611c13565b34801561066d575f5ffd5b506103b561067c3660046153fd565b611c5f565b34801561068c575f5ffd5b506106cf61069b366004615257565b60086020525f9081526040902080546001820154600283015460038401546004850154600590950154939492939192909186565b604080519687526020870195909552938501929092526060840152608083015260a082015260c00161038d565b348015610707575f5ffd5b50610405610716366004615426565b611cc2565b348015610726575f5ffd5b50610426610735366004615350565b5f918252600a6020818152604080852093855260109093018152828420600181015460028201546003909201548287529390925283852060059081015484875294909520909401549094565b34801561078c575f5ffd5b506103b561079b366004615257565b6120b2565b3480156107ab575f5ffd5b506103e4612136565b3480156107bf575f5ffd5b506104056107ce366004615257565b612146565b3480156107de575f5ffd5b506104056107ed3660046153e4565b612316565b6104056108003660046153fd565b612362565b348015610810575f5ffd5b5061040561081f3660046153e4565b61271a565b34801561082f575f5ffd5b506103b561083e366004615350565b612cef565b34801561084e575f5ffd5b506103e461085d366004615257565b612d3a565b34801561086d575f5ffd5b506103e461087c366004615257565b612d49565b34801561088c575f5ffd5b5061040561089b3660046152f7565b612e87565b3480156108ab575f5ffd5b506104056108ba366004615257565b6130d6565b3480156108ca575f5ffd5b506108de6108d9366004615350565b613105565b60405161038d919061545c565b3480156108f6575f5ffd5b506104056109053660046153e4565b6131b3565b61040561091836600461548d565b6131ff565b61040561092b3660046154b7565b6132e4565b34801561093b575f5ffd5b506103e461094a366004615350565b5f918252600a602090815260408084209284526012909201905290205490565b610405610978366004615257565b61342f565b348015610988575f5ffd5b506103e46134d5565b34801561099c575f5ffd5b506103e46109ab366004615257565b6134df565b3480156109bb575f5ffd5b506002546103e4565b3480156109cf575f5ffd5b506104056109de366004615257565b61354a565b3480156109ee575f5ffd5b506104056109fd3660046153e4565b613578565b348015610a0d575f5ffd5b506103e4610a1c366004615350565b61367c565b348015610a2c575f5ffd5b50610405610a3b3660046153e4565b6136eb565b348015610a4b575f5ffd5b50610a5f610a5a366004615257565b613737565b60405161038d91908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b348015610a9d575f5ffd5b50610405610aac3660046154e9565b6137a2565b348015610abc575f5ffd5b506103e4610acb366004615257565b600c6020525f908152604090205481565b348015610ae7575f5ffd5b506103e45f5481565b348015610afb575f5ffd5b506103e4610b0a3660046153e4565b6001600160a01b03165f908152600b602052604090205490565b348015610b2f575f5ffd5b50610405610b3e366004615257565b613812565b348015610b4e575f5ffd5b506103e460045481565b348015610b63575f5ffd5b506103e4613948565b348015610b77575f5ffd5b506103e4610b86366004615257565b613954565b348015610b96575f5ffd5b50600654610baa906001600160a01b031681565b6040516001600160a01b03909116815260200161038d565b348015610bcd575f5ffd5b506103b5610bdc366004615257565b61396c565b348015610bec575f5ffd5b506103e4610bfb366004615257565b613a46565b348015610c0b575f5ffd5b50610c1f610c1a366004615257565b613a5d565b60405161038d91905f60c082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b5f818152600a602052604090206003810154906060908190610c8a6134d5565b610c978260040154613954565b03610ca25750611084565b60048101545f9081908190610cbf90610b8690620151809061552f565b90505b610cca6134d5565b811015610d41575f610cdc8983611a3c565b9050801580610d0857505f81815260086020908152604080832060030154600d89019092529091205410155b15610d135750610d2d565b808314610d2b5783610d2481615542565b9450508092505b505b610d3a620151808261552f565b9050610cc2565b508167ffffffffffffffff811115610d5b57610d5b61555a565b604051908082528060200260200182016040528015610d84578160200160208202803683370190505b5094508167ffffffffffffffff811115610da057610da061555a565b604051908082528060200260200182016040528015610dc9578160200160208202803683370190505b509350815f03610eae575f610de08861053a6134d5565b90505f81118015610e0d57505f81815260086020908152604080832060030154600d880190925290912054105b15610ea5575f62015180610e248660040154613954565b610e2c6134d5565b610e36919061556e565b610e409190615595565b5f838152600d8701602090815260408083205460089092528220600301549293509091610e6d919061556e565b905080821115610e7b578091505b5f83815260086020526040902060020154610e9690836155a8565b610ea0908a61552f565b985050505b50505050611084565b5f5f5f5f62015180610ec38860040154613954565b610ecd919061552f565b90505b610ed86134d5565b811161101d575f610ee98c83611a3c565b9050805f03610ef85750611009565b848103610f5f575f81815260086020908152604080832060030154600d8c0190925290912054610f2990869061552f565b1015610f5a575f81815260086020526040902060020154610f4a908c61552f565b9a50610f5760018561552f565b93505b611007565b8415610fb057838a8481518110610f7857610f786155bf565b60200260200101818152505084898481518110610f9757610f976155bf565b602090810291909101015282610fac81615542565b9350505b5f81815260086020908152604080832060030154600d8c0190925282205492965090945085911015611007575f81815260086020526040902060020154610ff7908c61552f565b9a5061100460018561552f565b93505b505b611016620151808261552f565b9050610ed0565b50821580159061102c57508481105b156110705781888281518110611044576110446155bf565b60200260200101818152505082878281518110611063576110636155bf565b6020026020010181815250505b61107c8a61053a6134d5565b505050505050505b9193909250565b5f828152600a602090815260408083206001600160a01b0385168452600b0190915290205460ff165b92915050565b5f818152600a60205260408120600c01816110d484611c08565b81526020019081526020015f20549050919050565b5f838152600960205260409020546111535760405162461bcd60e51b815260206004820152602260248201527f4176616c616e63686520726567697374726174696f6e20666565206e6f742073604482015261195d60f21b60648201526084015b60405180910390fd5b5f8411801561116457506002548411155b6111a25760405162461bcd60e51b815260206004820152600f60248201526e125b9d985b1a59081d5cd95c881251608a1b604482015260640161114a565b8115806111be57505f848152600a602052604090206001015482145b806111ea57505f828152600a6020526040902060060154158015906111ea57506111ea8285600a611c5f565b6112365760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f742075736520746869732075706c696e6520494400000000000000604482015260640161114a565b5f61124085610c6a565b50505f858152600960205260408120549192509061125d906134df565b9050803410158061126e5750808210155b61128a5760405162461bcd60e51b815260040161114a906155d3565b5f8511801561129a575060148511155b6112d65760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081b195d995b609a1b604482015260640161114a565b5f868152600a602052604090206112ee60018761556e565b8160060154146113385760405162461bcd60e51b815260206004820152601560248201527410d85b9b9bdd08189d5e481d1a1a5cc81b195d995b605a1b604482015260640161114a565b845f0361134757806001015494505b345f036113d85761135787613ae8565b5f86815260096020526040902054600382015410156113af5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b604482015260640161114a565b5f86815260096020526040812054600383018054919290916113d290849061556e565b90915550505b6113e88787878760018b11613bab565b8134111561142557336108fc6113fe843461556e565b6040518115909202915f818181858888f19350505050158015611423573d5f5f3e3d5ffd5b505b50505050505050565b5f828152600a6020908152604080832084845260118101909252822054829182918291829160ff1661146f575f5f5f5f5f95509550955095509550506115ea565b5f8781526011820160205260408120600181015460029091015490975090036114a457505f93508392508291508190506115ea565b5f878152601182016020526040812060020180549091906114c7576114c76155bf565b5f9182526020808320909101548983526011840190915260409091206002015490955060010361150057505f92508291508190506115ea565b5f878152601182016020526040902060020180546001908110611525576115256155bf565b905f5260205f2001549350806011015f8881526020019081526020015f206002018054905060020361155d57505f91508190506115ea565b806011015f8881526020019081526020015f20600201600281548110611585576115856155bf565b5f918252602080832090910154898352601184019091526040909120600201549093506003036115b857505f90506115ea565b5f8781526011820160205260409020600201805460039081106115dd576115dd6155bf565b905f5260205f2001549150505b9295509295909350565b600b602052815f5260405f20818154811061160d575f80fd5b905f5260205f20015f91509150505481565b6006546001600160a01b031633146116495760405162461bcd60e51b815260040161114a9061560a565b600355565b5f5f85116116835760405162461bcd60e51b81526020600482015260026024820152615a5560f01b604482015260640161114a565b5f858152600a6020908152604080832087845260100190915290205460ff166116d75760405162461bcd60e51b815260040161114a906020808252600490820152630554e49560e41b604082015260600190565b6116e18585612cef565b156116ed575083611a34565b5f600160035460026116ff919061572e565b611709919061556e565b90505f60018060035461171c919061556e565b61172790600261572e565b611731919061556e565b90505f8267ffffffffffffffff81111561174d5761174d61555a565b604051908082528060200260200182016040528015611776578160200160208202803683370190505b505f898152600a602090815260408083208b84526010019091528120600201548251929350918391906117ab576117ab6155bf565b6020908102919091018101919091525f898152600a825260408082208a835260100190925220600301548151829060019081106117ea576117ea6155bf565b60209081029190910101525f805b8481101561194f57611823838281518110611815576118156155bf565b60200260200101518a612cef565b156118495782818151811061183a5761183a6155bf565b6020026020010151915061194f565b8381101561194757600a5f848381518110611866576118666155bf565b602002602001015181526020019081526020015f206010015f8a81526020019081526020015f20600201548382600161189f919061552f565b6118aa9060026155a8565b815181106118ba576118ba6155bf565b602002602001018181525050600a5f8483815181106118db576118db6155bf565b602002602001015181526020019081526020015f206010015f8a81526020019081526020015f206003015483826001611914919061552f565b61191f9060026155a8565b61192a90600161552f565b8151811061193a5761193a6155bf565b6020026020010181815250505b6001016117f8565b508015801561195b5750865b15611a2e578286101561197557611972838761552f565b95505b8386111561198a576119878685615739565b95505b6119af82878151811061199f5761199f6155bf565b6020026020010151895f8961164e565b9050805f03611a2e57825b848110156119f8576119e78382815181106119d7576119d76155bf565b60200260200101518a5f8a61164e565b9150815f036119f8576001016119ba565b505f8111611a2e5760405162461bcd60e51b815260206004820152600360248201526229272360e91b604482015260640161114a565b93505050505b949350505050565b5f5f611a4783613954565b5f858152600a602052604081206009810154929350919003611a6d575f925050506110b4565b5f828152600c6020526040812054600e54909190611a8d9060019061556e565b90505b85600e8281548110611aa457611aa46155bf565b905f5260205f20015411611ad557600e8181548110611ac557611ac56155bf565b905f5260205f2001549150611ae7565b80611adf8161574c565b915050611a90565b505f611af3878361556e565b5f888152600a602081905260408220600901549086015492935091611b1a9060019061556e565b90505b8785600a018281548110611b3357611b336155bf565b905f5260205f20015411611b7757600c5f86600a018381548110611b5957611b596155bf565b905f5260205f20015481526020019081526020015f20549250611b89565b80611b818161574c565b915050611b1d565b506005545b60018110611bfa575f8181526008602052604090205415611be8575f818152600860205260409020548210801590611bd657505f818152600860205260409020600101548310155b15611be85795506110b4945050505050565b80611bf28161574c565b915050611b8e565b505f98975050505050505050565b5f6110b48242611a3c565b6006546001600160a01b03163314611c3d5760405162461bcd60e51b815260040161114a9061560a565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b5f805b82811015611cb6575f848152600a6020526040902060010154859003611c8c576001915050611cbb565b5f938452600a602052604084206001015493849003611cae575f915050611cbb565b600101611c62565b505f90505b9392505050565b5f838152600a6020908152604080832085845260110190915290205460ff16611cfd5760405162461bcd60e51b815260040161114a90615761565b5f838152600a602090815260408083208584526011810190925290912054610100900460ff16158015611d4657505f83815260118201602052604090205462010000900460ff16155b15611d9f576007545f848152600960205260409020600301546001600160a01b03909116906108fc90611d78906134df565b6040518115909202915f818181858888f19350505050158015611d9d573d5f5f3e3d5ffd5b505b5f8381526011820160205260408120600101549003611dbe5750505050565b5f838152601182016020818152604080842060018101548552600a83529084209387905291905254610100900460ff16611f3f575f8481526009602052604090206001015483158015611e2757505f85815260118401602052604090205462010000900460ff16155b15611e68575f85815260096020526040902060020154611e47908261552f565b5f8681526011850160205260409020805462ff000019166201000017905590505b84826006015410611eb85760078201546001600160a01b03166108fc611e8d836134df565b6040518115909202915f818181858888f19350505050158015611eb2573d5f5f3e3d5ffd5b50611edd565b5f85815260128301602052604081208054839290611ed790849061552f565b90915550505b5f858152601184016020908152604091829020805461ff001916610100179055835482518981529182018890529181018390527f5fc385b29a62693f017f59cb50d2c3e8495ba1b8b01c0c26c19f87153ef3d4d49060600160405180910390a2505b5f8481526011820160205260408120600101549003611f5f575050505050565b5f848152601182810160209081526040808420600101548452600a82528084208885529286019091529091205462010000900460ff16158015611f9f5750835b156120aa57848160060154106120095760078101545f868152600960205260409020600201546001600160a01b03909116906108fc90611fde906134df565b6040518115909202915f818181858888f19350505050158015612003573d5f5f3e3d5ffd5b5061203d565b5f8581526009602090815260408083206002015460128501909252822080549192909161203790849061552f565b90915550505b5f8581526011840160209081526040808320805462ff0000191662010000179055835460098352928190206002015481518a8152928301899052908201527f5fc385b29a62693f017f59cb50d2c3e8495ba1b8b01c0c26c19f87153ef3d4d4906060015b60405180910390a25b505050505050565b5f818152600a60205260408120816120c984610c6a565b5050905060085f6120d986611c08565b81526020019081526020015f20600501548110158015611a34575060085f61210086611c08565b81526020019081526020015f206004015482600c015f61211f87611c08565b81526020019081526020015f205410949350505050565b5f6121415f546134df565b905090565b5f818152600a60205260409020600701546001600160a01b03163314806121725750612172813361108b565b61218e5760405162461bcd60e51b815260040161114a906157a2565b5f61219882612d49565b116121e55760405162461bcd60e51b815260206004820152601860248201527f4e6f20776974686472617761626c65206561726e696e67730000000000000000604482015260640161114a565b6121ee8161396c565b61222c5760405162461bcd60e51b815260206004820152600f60248201526e43616e6e6f7420776974686472617760881b604482015260640161114a565b61223581613ae8565b5f818152600a60205260409020600301546122895760405162461bcd60e51b81526020600482015260146024820152734e6f20617661696c61626c652062616c616e636560601b604482015260640161114a565b5f818152600a60205260408120600301805490829055906122a9826134df565b604051909150339082156108fc029083905f818181858888f193505050501580156122d6573d5f5f3e3d5ffd5b50827fbf2ed60bd5b5965d685680c01195c9514e4382e28e3a5a2d2d5244bf59411b938360405161230991815260200190565b60405180910390a2505050565b6006546001600160a01b031633146123405760405162461bcd60e51b815260040161114a9061560a565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b5f600154116123bd5760405162461bcd60e51b815260206004820152602160248201527f507265737469676520726567697374726174696f6e20666565206e6f742073656044820152601d60fa1b606482015260840161114a565b5f831180156123ce57506002548311155b61240c5760405162461bcd60e51b815260206004820152600f60248201526e125b9d985b1a59081d5cd95c881251608a1b604482015260640161114a565b6002548211156124525760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d5c1b1a5b99481251607a1b604482015260640161114a565b8282036124ab5760405162461bcd60e51b815260206004820152602160248201527f55706c696e652063616e6e6f74206265207468652073616d65206173207573656044820152603960f91b606482015260840161114a565b815f036124c0576124bd83600a61367c565b91505b5f838152600a602052604090206124d684613ae8565b5f6124e26001546134df565b905060015482600301541015806124f95750803410155b61253c5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b604482015260640161114a565b60058201541561258e5760405162461bcd60e51b815260206004820152601d60248201527f5573657220616c726561647920696e20707265737469676520706c616e000000604482015260640161114a565b60016005830155345f036125b757600154826003015f8282546125b1919061556e565b90915550505b5f6125c5856001808761164e565b60015f818152601080870160209081526040808420805460ff191686178155850186905560058901859055858452600a82528084209484529390910190529081206002015491925003612639575f818152600a6020908152604080832060018452601001909152902060020186905561265c565b5f818152600a602090815260408083206001845260100190915290206003018690555b5f612668876001613dc1565b5f818152600a6020908152604080832060018452600f01909152902054909150600403612699576126998186613f43565b823411156126d657336108fc6126af853461556e565b6040518115909202915f818181858888f193505050501580156126d4573d5f5f3e3d5ffd5b505b867f16d15f32051bc9628b984a7b677e93ad6c5c3caffcbca5c97855e392d11f92cd600160405161270991815260200190565b60405180910390a250505050505050565b6006546001600160a01b0316156127685760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e4818dbdb999a59dd5c995960721b604482015260640161114a565b600680546001600160a01b031990811633908117909255600780546001600160a01b038516908316179055600f805482167360be6dc7052d37d4649503345fe8d0ace2145c6c1790556010805482167358ca1a9169af3a9ffb59166c578548011cc74c1a179055624c4b405f8181556001918255600a60038190558282526020527fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bc78281557fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bc8919091557fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bce805490931690931790915560147fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bcc8190557fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bcd55427fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bcb5590815b60148111612900575f8181526010830160205260409020805460ff19166001179055806128f881615542565b9150506128cc565b5060015b60148111612938575f8181526011830160205260409020805460ff191660011790558061293081615542565b915050612904565b50335f908152600b602090815260408220805460018101825590835290822001839055600c906129666134d5565b81526020019081526020015f205f81548092919061298390615542565b90915550506040515f9083907f296b61d41a33e6ea94875300e90a38cc34bf24ede90c106e6479fe3fc26ce38e908390a360016002556129c16140e0565b612ce2600d602052622625a07ffd54ff1ed53f34a900b24c5ba64f85761163b5d82d98a47b9bd80e45466993c555624c4b407f10a81eed9d63d16face5e76357905348e6253d3394086026bb2bf2145d7cc24955629896807f26b4a10d0f0b04925c23bd4480ee147c916e5e87a7d68206a533dad160ac81e2556301312d007fafafe8948a4ed9d478b1e9a5780b119b5edd00ea7d07bc35bef7c814824eb94b556302625a007fa5049387d9cb649c59f4bda666105ba636c2a103d8e2b232ba4d125737cd2149556304c4b4007fa48544818c2c710afa9849c61ec9c60e8acdb3eaa2885f33b37e118cc8fd04ac5563098968007fb91432bedff11256dbe14161d3606a2657bc9dacf8742f6b817d871dd53fb97655631312d0007f0b705463cf5f7356780ee6e96132d37412c1b5816a4d207b8dcd42c34976745755632625a0007f7b6f1ece0cbe5122a575776770f0494c2d57ed2a50e36c2ba0d811d70ee03b6455634c4b40007fba9d637f252776d5e1b3534bbd7554a1265a4ef0539d9ca50abe118598a6973c5563989680007f52c2086a203f40e709b1346663401f6c737b2fce5878601fcf875b047fed5fb6556401312d00007fe399baa2fabbab2a0309615b124a802277bab50ec0ca3452a00889e216c4b902556402625a00007fe0af3347aa7e5af384208c9d29458f902f0ceddbc90963608afa77235658b360556404c4b400007f154ef5b709dcdc8b49a2af6408b8a1af209c39b5fa796f03680257c97692546e556409896800007f52fb6a28cb3c239105f8f829bc7376f939b6bfb040c470bdc2bda0af2e784b9455641312d000007f01a49be1e7ea084651fd665847100d28826db0b17160863a99534933cbbd2dce55642625a000007f6fbf3b49b523bc27464b7dbfa6311951351b1d3efd07aa2ee4d1ce319801a0ce55644c4b4000007f0a206051e911305809ddd48cf2baa7ead2c7fb038e505e1d02f9e6c2ce72930c556498968000007f1341e158d1184a2eb4edb96b016176e1c5ad075baae6651557fb93ae3925007a5560145f526501312d0000007fdd2af3330d298808a303a10bc360333536e7697099bb3fe7200b0c272de6655855565b612cea6142d2565b505050565b5f828152600a602090815260408083208484526010019091528120600201541580611cbb5750505f918252600a60209081526040808420928452601090920190529020600301541590565b5f816002546110b4919061556e565b5f5f5f5f612d5685610c6a565b9250925092505f612d6686611c08565b5f878152600a60209081526040808320848452600c810183528184205460089093529083206003015493945092612d9d91906155a8565b5f848152600d84016020526040902054612db7919061552f565b5f84815260086020526040902060020154612dd291906155a8565b90505f5b8551811015612e665783858281518110612df257612df26155bf565b602002602001015103612e5e5760085f868381518110612e1457612e146155bf565b602002602001015181526020019081526020015f2060020154868281518110612e3f57612e3f6155bf565b6020026020010151612e5191906155a8565b612e5b908361552f565b91505b600101612dd6565b50808611612e7b57505f979650505050505050565b50939695505050505050565b5f828152600a60205260409020600701546001600160a01b03163314612eef5760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c7920757365722063616e206368616e67652077616c6c65740000000000604482015260640161114a565b5f5b5f838152600a60209081526040808320600701546001600160a01b03168352600b90915290205481101561304d575f838152600a60209081526040808320600701546001600160a01b03168352600b9091529020805484919083908110612f5a57612f5a6155bf565b905f5260205f20015403613045575f838152600a60209081526040808320600701546001600160a01b03168352600b90915290208054612f9c9060019061556e565b81548110612fac57612fac6155bf565b5f918252602080832090910154858352600a82526040808420600701546001600160a01b03168452600b9092529120805483908110612fed57612fed6155bf565b5f918252602080832090910192909255848152600a82526040808220600701546001600160a01b03168252600b9092522080548061302d5761302d6157c9565b600190038181905f5260205f20015f9055905561304d565b600101612ef1565b506001600160a01b0381165f818152600b60209081526040808320805460018101825590845282842001869055858352600a82529182902060070180546001600160a01b0319168417905581513381529081019290925283917f774cac233d75821d2683f89e643ea7031de8674eea3722260820dc5ad445282191015b60405180910390a25050565b6006546001600160a01b031633146131005760405162461bcd60e51b815260040161114a9061560a565b600155565b61310d615238565b613115615238565b5f848152600a6020526040902060090154831015611cbb575f5b600a8110156131ab575f858152600a6020526040902060090154613153858361552f565b10156131ab575f858152600a60205260409020600901613173858361552f565b81548110613183576131836155bf565b905f5260205f20015482826014811061319e5761319e6155bf565b602002015260010161312f565b509392505050565b6006546001600160a01b031633146131dd5760405162461bcd60e51b815260040161114a9061560a565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b603281111561323b5760405162461bcd60e51b8152602060048201526008602482015267544f4f5f4d414e5960c01b604482015260640161114a565b5f6132465f546134df565b905061325282826155a8565b3410156132715760405162461bcd60e51b815260040161114a906155d3565b5f5b8281101561328e576132868686866146f0565b600101613273565b5061329982826155a8565b3411156132dd57336108fc6132ae84846155a8565b6132b8903461556e565b6040518115909202915f818181858888f193505050501580156120aa573d5f5f3e3d5ffd5b5050505050565b5f5f54116133345760405162461bcd60e51b815260206004820152601860248201527f526567697374726174696f6e20666565206e6f74207365740000000000000000604482015260640161114a565b81158061336a57505f828152600a60205260409020600501541580159061336a57505f828152600a602052604090206006015415155b6133b65760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964206d61747269782075706c696e652049440000000000000000604482015260640161114a565b5f6133c15f546134df565b9050803410156133e35760405162461bcd60e51b815260040161114a906155d3565b6133ee8484846146f0565b8034111561342957336108fc613404833461556e565b6040518115909202915f818181858888f193505050501580156132dd573d5f5f3e3d5ffd5b50505050565b5f341161346f5760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b604482015260640161114a565b5f613479346134df565b905080600a5f8481526020019081526020015f206003015f82825461349e919061552f565b909155505060405181815282907fa3af609bf46297028ce551832669030f9effef2b02606d02cbbcc40fe6b47c55906020016130ca565b5f61214142613954565b600f5460405163b9f2f79960e01b8152600481018390525f916001600160a01b03169063b9f2f79990602401602060405180830381865afa158015613526573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110b491906157dd565b6006546001600160a01b031633146135745760405162461bcd60e51b815260040161114a9061560a565b5f55565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f811580156135bd5750825b90505f8267ffffffffffffffff1660011480156135d95750303b155b9050811580156135e7575080155b156136055760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561362f57845460ff60401b1916600160401b1785555b83156120aa57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a1505050505050565b5f828152600a60205260408120600101545b801580159061369c57505f83115b156136e1575f818152600a6020526040902060050154156136be5790506110b4565b5f908152600a6020526040902060010154826136d98161574c565b93505061368e565b5060019392505050565b6006546001600160a01b031633146137155760405162461bcd60e51b815260040161114a9061560a565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b61375e60405180608001604052805f81526020015f81526020015f81526020015f81525090565b505f90815260096020908152604091829020825160808101845281548152600182015492810192909252600281015492820192909252600390910154606082015290565b5f838152600a60205260409020600701546001600160a01b031633146137da5760405162461bcd60e51b815260040161114a906157a2565b5f928352600a602090815260408085206001600160a01b03949094168552600b90930190529120805460ff1916911515919091179055565b5f818152600a60205260409020600701546001600160a01b0316331461384a5760405162461bcd60e51b815260040161114a906157a2565b613853816120b2565b6138905760405162461bcd60e51b815260206004820152600e60248201526d43616e6e6f742072656379636c6560901b604482015260640161114a565b5f818152600a60205260408120906138a783611c08565b90506138b283613ae8565b5f81815260086020526040812060050154600384018054919290916138d890849061556e565b90915550505f818152600c8301602052604081208054600192906138fd90849061552f565b90915550505f818152600d83016020526040808220919091555183907f87f4b7ea340c6b16973214300a3cbbb5afaf6c92389d1e81f95ffe0c07edcfb6906123099084815260200190565b5f6121416001546134df565b5f6139626201518083615739565b6110b4908361556e565b5f818152600a602052604081208161398384612d49565b90505f61398f85611c08565b90506001811180156139a457505f8360050154115b80156139b357505f8360060154115b8015613a2c5750601054604051636470be4f60e11b815260048101879052602481018390526001600160a01b039091169063c8e17c9e90604401602060405180830381865afa158015613a08573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a2c91906157f4565b15613a3c57506001949350505050565b505f949350505050565b5f818152600960205260408120546110b4906134df565b613a906040518060c001604052805f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b505f90815260086020908152604091829020825160c08101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260059091015460a082015290565b5f5f5f613af484610c6a565b925092509250825f03613b075750505050565b5f848152600a602052604081206003018054859290613b2790849061552f565b90915550505f848152600a60205260408120426004820155905b82518110156120aa57838181518110613b5c57613b5c6155bf565b602002602001015182600d015f858481518110613b7b57613b7b6155bf565b602002602001015181526020019081526020015f205f828254613b9e919061552f565b9091555050600101613b41565b5f858152600a602052604090206006810154613bc890600161552f565b8514613c225760405162461bcd60e51b8152602060048201526024808201527f4163636f756e74206e6f74207175616c696669656420666f722074686973206c604482015263195d995b60e21b606482015260840161114a565b600681018590555f613c3785876001876149c5565b5f8781526011808501602090815260408084206001808201879055815460ff19168117909155858552600a83528185208c865290930182528320600201805480840182559084529220909101899055909150869003613d3d575f818152600a6020908152604080832089845260110190915290205460ff1615613cc057613cc087876001611cc2565b5f86815260118301602052604090206002015415613d38575f5b5f878152601184016020526040902060020154811015613d36575f87815260118401602052604090206002018054613d2e919083908110613d1d57613d1d6155bf565b905f5260205f200154886001611cc2565b600101613cda565b505b613d91565b8215613d4d57613d388787614f1b565b613d918787601489108061071657505f848152600a6020526040812060110190613d788b600161552f565b815260208101919091526040015f205460ff1615611cc2565b5f818152600a60209081526040808320898452601101909152902060020154600403611425576114258185615134565b5f818152600d6020908152604080832054858452600a8352818420858552601001909252822060010154808303613dfc575f925050506110b4565b5f818152600a6020908152604080832087845260100190915281206001015490819003613e2e575f93505050506110b4565b5f818152600a60209081526040808320888452600f810190925290912054600311613e96576007546001600160a01b03166108fc613e6b866134df565b6040518115909202915f818181858888f19350505050158015613e90573d5f5f3e3d5ffd5b50613ed7565b60078101546001600160a01b03166108fc613eb0866134df565b6040518115909202915f818181858888f19350505050158015613ed5573d5f5f3e3d5ffd5b505b5f868152600f820160205260408120805460019290613ef790849061552f565b90915550506040805183815260208101869052879189917fcf56eb5ea07378aaafa39ea8fe77392671f231a384af4485a303b12f9738f372910160405180910390a35095945050505050565b81600103613f4f575050565b5f828152600a602052604081206005810154909190613f6f90600161552f565b90506001811015613fb25760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081b195d995b609a1b604482015260640161114a565b600582018190555f613fe76010840182613fcd60018661556e565b81526020019081526020015f20600101548360018761164e565b5f838152601080860160209081526040808420805460ff19166001908117825501859055848452600a8252808420878552909201905281206002015491925003614051575f818152600a602090815260408083208584526010019091529020600201859055614073565b5f818152600a6020908152604080832085845260100190915290206003018590555b5f61407e8684613dc1565b5f818152600a60209081526040808320878452600f019091529020549091506004036140ae576140ae8186613f43565b857f16d15f32051bc9628b984a7b677e93ad6c5c3caffcbca5c97855e392d11f92cd846040516120a191815260200190565b6140fa6001600460286203d09060286004624c4b406151c0565b6141116002600660966206ddd0602860035f6151c0565b614129600360086103e8620927c0602860035f6151c0565b6141416004600a611388620b71b0602860035f6151c0565b6141596005600c613a98620e7ef0602860035f6151c0565b6141716006600e6188b8621312d0602860035f6151c0565b6141896007601061d6d86216e360602860035f6151c0565b6141a260086012620186a0621c3a90602860035f6151c0565b6141bb600960146207a120621cfde0602860035f6151c0565b6141d4600a6016620b71b0622191c0602860035f6151c0565b6141ed600b6018620f42406226e8f0602860035f6151c0565b614206600c601a6216e360622b7cd0602860035f6151c0565b61421f600d601c622625a0623010b0602860035f6151c0565b614235600e601e623567e080602860035f6151c0565b61424f600f6020624c4b40630260d360602860035f6151c0565b6142686010602262e4e1c062432380602860035f6151c0565b614282601160246302faf080624c4b40602860035f6151c0565b61429c601260266308f0d18062632ea0602860035f6151c0565b6142b6601360286311e1a300627270e0602860035f6151c0565b6142d06014602a631dcd650062989680602860035f6151c0565b565b6040805160148082526102a082019092525f916020820161028080368337019050509050624c4b40815f8151811061430c5761430c6155bf565b602002602001018181525050627270e08160018151811061432f5761432f6155bf565b60200260200101818152505062aba95081600281518110614352576143526155bf565b6020026020010181815250506301017df881600381518110614376576143766155bf565b6020026020010181815250506301823cf48160048151811061439a5761439a6155bf565b6020026020010181815250506302435b6e816005815181106143be576143be6155bf565b6020026020010181815250506303650925816006815181106143e2576143e26155bf565b6020026020010181815250506332eb892b81600781518110614406576144066155bf565b602002602001018181525050634c614dc18160088151811061442a5761442a6155bf565b602002602001018181525050637291f4a18160098151811061444e5761444e6155bf565b60200260200101818152505063112f7e4b81600a81518110614472576144726155bf565b6020026020010181815250506319c73d7181600b81518110614496576144966155bf565b6020026020010181815250506326aadc2981600c815181106144ba576144ba6155bf565b602002602001018181525050633a004a3e81600d815181106144de576144de6155bf565b6020026020010181815250506357006f5d81600e81518110614502576145026155bf565b602002602001018181525050638280a70c81600f81518110614526576145266155bf565b60200260200101818152505063c3c0fa928160108151811061454a5761454a6155bf565b602002602001018181525050640125a177db8160118151811061456f5761456f6155bf565b6020026020010181815250506401b87233c881601281518110614594576145946155bf565b602002602001018181525050640294ab4dac816013815181106145b9576145b96155bf565b60209081029190910101525f5b81518110156146ec5760405180608001604052808383815181106145ec576145ec6155bf565b602002602001015181526020016103e884848151811061460e5761460e6155bf565b602002602001015161017761462391906155a8565b61462d9190615595565b81526020016103e8848481518110614647576146476155bf565b602002602001015161017761465c91906155a8565b6146669190615595565b81526020016103e8848481518110614680576146806155bf565b602002602001015160fa61469491906155a8565b61469e9190615595565b905260095f6146ae84600161552f565b815260208082019290925260409081015f208351815591830151600180840191909155908301516002830155606090920151600390910155016145c6565b5050565b5f8311801561470157506002548311155b6147415760405162461bcd60e51b8152602060048201526011602482015270125b9d985b1a59081d5c1b1a5b99481251607a1b604482015260640161114a565b60028054905f61475083615542565b90915550506002545f818152600a602090815260408083208481556001808201899055600882018890556007820180546001600160a01b0319166001600160a01b0389169081179091554260048401558552600b845291842080549283018155845291832001839055906147c26134d5565b600280545f838152600c60209081526040808320939093558a8252600a8152918120600981018054600181018255908352928220909201879055898152910180549293509061481083615542565b90915550505f868152600a60209081526040808320848452600e01909152812080549161483c83615542565b90915550505f868152600a60208190526040822001549003614880575f868152600a60208181526040832090910180546001810182559083529120018190556148e9565b6148886134d5565b5f878152600a602081905260409091200180546148a79060019061556e565b815481106148b7576148b76155bf565b905f5260205f200154146148e9575f868152600a60208181526040832090910180546001810182559083529120018190555b600e545f0361492b57600e80546001810182555f919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01819055614991565b600e805482919061493e9060019061556e565b8154811061494e5761494e6155bf565b905f5260205f2001541461499157600e80546001810182555f919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd018190555b604051869084907f296b61d41a33e6ea94875300e90a38cc34bf24ede90c106e6479fe3fc26ce38e905f90a3505050505050565b5f5f85116149fa5760405162461bcd60e51b81526020600482015260026024820152615a5560f01b604482015260640161114a565b5f858152600a6020908152604080832087845260110190915290206002015460041115614a28575083611a34565b60408051610155808252612ac082019092526055905f908360208201612aa0803683375050505f898152600a602090815260408083208b84526011019091528120600201805492935091614a7e57614a7e6155bf565b905f5260205f200154815f81518110614a9957614a996155bf565b6020908102919091018101919091525f898152600a825260408082208a83526011019092522060020180546001908110614ad557614ad56155bf565b905f5260205f20015481600181518110614af157614af16155bf565b6020908102919091018101919091525f898152600a825260408082208a835260110190925220600290810180549091908110614b2f57614b2f6155bf565b905f5260205f20015481600281518110614b4b57614b4b6155bf565b6020908102919091018101919091525f898152600a825260408082208a83526011019092522060020180546003908110614b8757614b876155bf565b905f5260205f20015481600381518110614ba357614ba36155bf565b60209081029190910101525f805b84811015614e92576004600a5f858481518110614bd057614bd06155bf565b602002602001015181526020019081526020015f206011015f8b81526020019081526020015f20600201805490501015614c2557828181518110614c1657614c166155bf565b60200260200101519150614e92565b83811015614e8a57600a5f848381518110614c4257614c426155bf565b602002602001015181526020019081526020015f206011015f8a81526020019081526020015f206002015f81548110614c7d57614c7d6155bf565b905f5260205f20015483826001614c94919061552f565b614c9f9060046155a8565b81518110614caf57614caf6155bf565b602002602001018181525050600a5f848381518110614cd057614cd06155bf565b602002602001015181526020019081526020015f206011015f8a81526020019081526020015f20600201600181548110614d0c57614d0c6155bf565b905f5260205f20015483826001614d23919061552f565b614d2e9060046155a8565b614d3990600161552f565b81518110614d4957614d496155bf565b602002602001018181525050600a5f848381518110614d6a57614d6a6155bf565b602002602001015181526020019081526020015f206011015f8a81526020019081526020015f20600201600281548110614da657614da66155bf565b905f5260205f20015483826001614dbd919061552f565b614dc89060046155a8565b614dd390600261552f565b81518110614de357614de36155bf565b602002602001018181525050600a5f848381518110614e0457614e046155bf565b602002602001015181526020019081526020015f206011015f8a81526020019081526020015f20600201600381548110614e4057614e406155bf565b905f5260205f20015483826001614e57919061552f565b614e629060046155a8565b614e6d90600361552f565b81518110614e7d57614e7d6155bf565b6020026020010181815250505b600101614bb1565b5080158015614e9e5750865b15611a2e5782861015614eb857614eb5838761552f565b95505b83861115614ecd57614eca8685615739565b95505b614ee282878151811061199f5761199f6155bf565b9050805f03611a2e57825b848110156119f857614f0a8388815181106119d7576119d76155bf565b9150815f036119f857600101614eed565b5f828152600a6020908152604080832084845260110190915290205460ff16614f565760405162461bcd60e51b815260040161114a90615761565b60018111614fcc5760405162461bcd60e51b815260206004820152603760248201527f4d616e75616c207075726368617365206973206f6e6c7920617661696c61626c60448201527f6520666f72206c6576656c203220616e642061626f7665000000000000000000606482015260840161114a565b5f828152600a602090815260408083208484526011810190925290912054610100900460ff1615801561501557505f82815260118201602052604090205462010000900460ff16155b1561507e576007546001600160a01b03166108fc61505760095f61503a60018861556e565b81526020019081526020015f206003015460046109ab91906155a8565b6040518115909202915f818181858888f1935050505015801561507c573d5f5f3e3d5ffd5b505b601181015f61508e60018561556e565b81526020019081526020015f20600101545f036150aa57505050565b5f6009816150b960018661556e565b81526020019081526020015f206002015460046150d691906155a8565b9050600a5f60118401816150eb60018861556e565b81526020019081526020015f206001015481526020019081526020015f206007015f9054906101000a90046001600160a01b03166001600160a01b03166108fc613404836134df565b81600103615140575050565b5f828152600a60205260408120600681015490919061516090600161552f565b60015f81815260118086016020908152604080842090940154808452600a82528484208685529092019052919020549192509060ff161580156151a7575082600101548114155b156151b3575060018201545b6132dd858383875f613bab565b6040805160c0810182528781526020808201888152828401888152606084018881526080850188815260a086018881525f8f8152600890965296909420945185559151600185015551600284015551600383015551600482015590516005918201555487111561142557600587905550505050505050565b6040518061028001604052806014906020820280368337509192915050565b5f60208284031215615267575f5ffd5b5035919050565b5f8151808452602084019350602083015f5b8281101561529e578151865260209586019590910190600101615280565b5093949350505050565b838152606060208201525f6152c0606083018561526e565b82810360408401526152d2818561526e565b9695505050505050565b80356001600160a01b03811681146152f2575f5ffd5b919050565b5f5f60408385031215615308575f5ffd5b82359150615318602084016152dc565b90509250929050565b5f5f5f5f60808587031215615334575f5ffd5b5050823594602084013594506040840135936060013592509050565b5f5f60408385031215615361575f5ffd5b50508035926020909101359150565b5f5f60408385031215615381575f5ffd5b61538a836152dc565b946020939093013593505050565b80151581146153a5575f5ffd5b50565b5f5f5f5f608085870312156153bb575f5ffd5b843593506020850135925060408501356153d481615398565b9396929550929360600135925050565b5f602082840312156153f4575f5ffd5b611cbb826152dc565b5f5f5f6060848603121561540f575f5ffd5b505081359360208301359350604090920135919050565b5f5f5f60608486031215615438575f5ffd5b8335925060208401359150604084013561545181615398565b809150509250925092565b610280810181835f5b6014811015615484578151835260209283019290910190600101615465565b50505092915050565b5f5f5f5f608085870312156154a0575f5ffd5b84359350602085013592506153d4604086016152dc565b5f5f5f606084860312156154c9575f5ffd5b83359250602084013591506154e0604085016152dc565b90509250925092565b5f5f5f606084860312156154fb575f5ffd5b8335925061550b602085016152dc565b9150604084013561545181615398565b634e487b7160e01b5f52601160045260245ffd5b808201808211156110b4576110b461551b565b5f600182016155535761555361551b565b5060010190565b634e487b7160e01b5f52604160045260245ffd5b818103818111156110b4576110b461551b565b634e487b7160e01b5f52601260045260245ffd5b5f826155a3576155a3615581565b500490565b80820281158282048414176110b4576110b461551b565b634e487b7160e01b5f52603260045260245ffd5b60208082526018908201527f496e76616c696420726567697374726174696f6e206665650000000000000000604082015260600190565b60208082526021908201527f4f6e6c792061646d696e2063616e2063616c6c20746869732066756e6374696f6040820152603760f91b606082015260800190565b6001815b60018411156156865780850481111561566a5761566a61551b565b600184161561567857908102905b60019390931c92800261564f565b935093915050565b5f8261569c575060016110b4565b816156a857505f6110b4565b81600181146156be57600281146156c8576156e4565b60019150506110b4565b60ff8411156156d9576156d961551b565b50506001821b6110b4565b5060208310610133831016604e8410600b8410161715615707575081810a6110b4565b6157135f19848461564b565b805f19048211156157265761572661551b565b029392505050565b5f611cbb838361568e565b5f8261574757615747615581565b500690565b5f8161575a5761575a61551b565b505f190190565b60208082526021908201527f55736572206e6f74207265676973746572656420696e2074686973206c6576656040820152601b60fa1b606082015260800190565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b634e487b7160e01b5f52603160045260245ffd5b5f602082840312156157ed575f5ffd5b5051919050565b5f60208284031215615804575f5ffd5b8151611cbb8161539856fea264697066735822122061c305d0ea882757e0c91f85ab198c1f83e4128ba0541c3df95e2dfc1ddf832b64736f6c634300081c0033

Block Transaction Gas Used Reward
view all blocks produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.