BNB Price: $628.11 (-0.54%)
 

Overview

BNB Balance

BNB Smart Chain LogoBNB Smart Chain LogoBNB Smart Chain Logo0 BNB

BNB Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Compound Rewards949593342026-04-27 10:01:403 mins ago1777284100IN
0xc90E5785...90541A76D
0 BNB0.000082470.05
Deposit949590542026-04-27 9:59:345 mins ago1777283974IN
0xc90E5785...90541A76D
0 BNB0.000063260.05
Register949590312026-04-27 9:59:245 mins ago1777283964IN
0xc90E5785...90541A76D
0 BNB0.000010530.05
Deposit949527932026-04-27 9:12:3552 mins ago1777281155IN
0xc90E5785...90541A76D
0 BNB0.000124490.125
Compound Rewards949526072026-04-27 9:11:1154 mins ago1777281071IN
0xc90E5785...90541A76D
0 BNB0.000074580.05
Deposit949517112026-04-27 9:04:271 hr ago1777280667IN
0xc90E5785...90541A76D
0 BNB0.000174550.125
Register949516362026-04-27 9:03:531 hr ago1777280633IN
0xc90E5785...90541A76D
0 BNB0.000026130.125
Compound Rewards949512292026-04-27 9:00:501 hr ago1777280450IN
0xc90E5785...90541A76D
0 BNB0.000085980.05
Deposit949507612026-04-27 8:57:191 hr ago1777280239IN
0xc90E5785...90541A76D
0 BNB0.000175150.125
Register949506912026-04-27 8:56:481 hr ago1777280208IN
0xc90E5785...90541A76D
0 BNB0.000026130.125
Deposit949503072026-04-27 8:53:551 hr ago1777280035IN
0xc90E5785...90541A76D
0 BNB0.000064520.05
Register949502842026-04-27 8:53:441 hr ago1777280024IN
0xc90E5785...90541A76D
0 BNB0.000010470.05
Compound Rewards949498502026-04-27 8:50:291 hr ago1777279829IN
0xc90E5785...90541A76D
0 BNB0.000075780.05
Compound Rewards949484722026-04-27 8:40:081 hr ago1777279208IN
0xc90E5785...90541A76D
0 BNB0.000073390.05
Compound Rewards949470932026-04-27 8:29:471 hr ago1777278587IN
0xc90E5785...90541A76D
0 BNB0.000081280.05
Deposit949452102026-04-27 8:15:391 hr ago1777277739IN
0xc90E5785...90541A76D
0 BNB0.000191170.125
Register949451492026-04-27 8:15:111 hr ago1777277711IN
0xc90E5785...90541A76D
0 BNB0.000026240.125
Compound Rewards949430412026-04-27 7:59:222 hrs ago1777276762IN
0xc90E5785...90541A76D
0 BNB0.000074580.05
Compound Rewards949416632026-04-27 7:49:012 hrs ago1777276141IN
0xc90E5785...90541A76D
0 BNB0.000086490.05
Deposit949409412026-04-27 7:43:352 hrs ago1777275815IN
0xc90E5785...90541A76D
0 BNB0.000066070.05
Register949409182026-04-27 7:43:252 hrs ago1777275805IN
0xc90E5785...90541A76D
0 BNB0.000010530.05
Compound Rewards949402842026-04-27 7:38:392 hrs ago1777275519IN
0xc90E5785...90541A76D
0 BNB0.000080090.05
Compound Rewards949389062026-04-27 7:28:182 hrs ago1777274898IN
0xc90E5785...90541A76D
0 BNB0.000079080.05
Compound Rewards949375282026-04-27 7:17:582 hrs ago1777274278IN
0xc90E5785...90541A76D
0 BNB0.0000850.05
Compound Rewards949361482026-04-27 7:07:362 hrs ago1777273656IN
0xc90E5785...90541A76D
0 BNB0.000090940.05
View all transactions

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

Contract Source Code Verified (Exact Match)

Contract Name:
TURBOLOOP

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 8 : TURBOLOOP.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

error NotOwner();
error NotLaunched();
error AlreadyRegistered();
error InvalidUsername();
error UsernameTaken();
error ReferrerNotFound();
error CannotSelfRefer();
error ReferrerNotQualified();
error MustRegisterFirst();
error BelowMinimum();
error MaxPositions();
error NotRegistered();
error NoRewards();
error InsufficientBalance();
error TransferFailed();
error InvalidPlan();
error DepositNotMatured();
error InvalidAddress();
error UserAlreadyRegistered();
error UplineNotRegistered();
error ArrayMismatch();
error EmptyBatch();
error NoActiveDeposits();

interface INonfungiblePositionManager {
    struct IncreaseLiquidityParams {
        uint256 tokenId;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }
    
    struct DecreaseLiquidityParams {
        uint256 tokenId;
        uint128 liquidity;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }
    
    struct CollectParams {
        uint256 tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }
    
    function increaseLiquidity(IncreaseLiquidityParams calldata params) external payable returns (uint128 liquidity, uint256 amount0, uint256 amount1);
    function decreaseLiquidity(DecreaseLiquidityParams calldata params) external payable returns (uint256 amount0, uint256 amount1);
    function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1);
    function positions(uint256 tokenId) external view returns (
        uint96 nonce,
        address operator,
        address token0,
        address token1,
        uint24 fee,
        int24 tickLower,
        int24 tickUpper,
        uint128 liquidity,
        uint256 feeGrowthInside0LastX128,
        uint256 feeGrowthInside1LastX128,
        uint128 tokensOwed0,
        uint128 tokensOwed1
    );
}

abstract contract Ownable {
    address private _owner;

    event OwnershipRenounced(address indexed previousOwner);
    
    constructor() {
        _owner = msg.sender;
    }
    
    function owner() public view returns (address) {
        return _owner;
    }
    
    modifier onlyOwner() {
        if(_owner != msg.sender) revert NotOwner();
        _;
    }
    
    function renounceOwnership() public onlyOwner {
        emit OwnershipRenounced(_owner);
        _owner = address(0);
    }
}

contract TURBOLOOP is ReentrancyGuard, Ownable {
    using SafeERC20 for IERC20;
    
    IERC20 private immutable USDT;
    INonfungiblePositionManager private immutable positionManager;
    
    uint256 private immutable lpPositionId;
    bool public immutable usdtIsToken0;
    
    uint256 public launchDate;
    
    uint256 private constant MINIMUM_DEPOSIT = 1 ether; 
    uint256 private constant MINIMUM_WITHDRAW = 1 ether; 
    uint256 private constant MINIMUM_COMPOUND = 1 ether; 
    uint256 private constant REFERRAL_QUALIFICATION = 25 ether;
    uint16 private constant MAX_POSITIONS = 400;
    uint256 private constant SERVICE_FEE_PCT = 600;
    uint256 private constant PERCENTS_DIVIDER = 10000;
    uint256 public constant TIME_STEP = 1 days;
    
    uint8 private constant MAX_UPLINE_DEPTH = 100;
    uint8 private constant REFERRAL_DEPTH = 20;
    uint256 private constant MAX_LEADERSHIP_PCT = 1000; 
    
    uint256 private constant USDT_TO_LIQUIDITY_RATE = 21556434736483412668;
    
    struct PlanConfig {
        uint256 duration;
        uint256 totalROI;
    }
    
    PlanConfig[4] public plans;
    
    uint256[20] private REFERRAL_REWARDS = [
        1200, 800, 500, 400, 300, 200, 200, 200, 150, 150, 
        100, 100, 100, 100, 100, 100, 100, 100, 100, 100
    ];
    
    struct LevelRequirement {
        uint8 minDirects;
        uint256 minSelfAUM;
    }
    
    mapping(uint8 => LevelRequirement) public levelRequirements;
    
    struct RankConfig {
        uint256 rewardPct;
        uint32 teamCountNeeded;
        uint256 teamActiveDepositNeeded;
    }
    
    RankConfig[7] public ranks;
    
    struct Deposit {
        uint256 amount;
        uint256 startTime;
        uint256 lastRewardCalculation;
        uint256 calculatedROI;
        uint8 planId;
        bool claimed;
    }
    
    struct User {
        address referrer;
        string username;
        bool registered;
        uint256 userId;
        uint256 totalActiveDeposit;
        uint256 teamActiveDeposit;
        uint256 teamTotalDeposit;
        uint256 teamTotalCompound;
        uint256 totalDeposited;
        uint256 totalWithdrawn;
        uint256 totalCompounded;
        Deposit[] deposits;
    }
    
    struct UserExtra {
        uint256 networkRewardAvailable;
        uint256 dailyRewardReserve;
        uint256 totalReferralReward;
        uint256 totalROIEarned;
        uint256 totalLeadershipReward;
        uint32 teamCount;
        uint32 directsCount;
        uint32 qualifiedDirects; 
        uint8 currentRank;
        uint256 lastCalculationTime;
    }
    
    mapping(address => User) public users;
    mapping(address => UserExtra) public usersExtra;
    mapping(string => address) public usernameToAddress;
    mapping(string => bool) public usernameExists;
    mapping(uint256 => address) public userIdToAddress;
    mapping(uint256 => bool) public dailyRewardDayCompleted;
    mapping(uint256 => uint256) public dailyRewardUsersProcessed;
    mapping(uint256 => uint256) public dailyRewardTotalROI;
    mapping(address => mapping(uint8 => uint32)) public levelDownlineCount;
    mapping(address => mapping(uint8 => uint256)) public levelReferralEarned;
    
    uint256 public totalRegisteredUsers;
    uint256 public totalActiveUsers;
    uint256 private totalDeposited;
    uint256 private totalWithdrawn;
    uint256 public nextUserId;
    uint256 public dailyRewardCurrentDay;
    uint256 public dailyRewardLastProcessedUserId;

    address public constant SERVICE_FEE_WALLET = 0xC8D2701882A9A629e9a9332950Fef78EE4FFD9A9;
    

    event Registration(address indexed user, string username, address indexed referrer, string uplineUsername, uint256 timestamp);
    event Deposited(address indexed user, uint256 amount, uint8 planId, uint256 timestamp);
    event Claimed(address indexed user, uint256 amount, uint256 timestamp);
    event Compounded(address indexed user, uint256 amount, uint8 planId, uint256 timestamp);
    event ReferralReward(address indexed upline, address indexed downline, uint8 level, uint256 amount, uint256 timestamp);
    event LeadershipReward(address indexed upline, address indexed downline, uint8 rank, uint256 amount, uint256 timestamp);
    event RankUpgraded(address indexed user, uint8 newRank, uint256 timestamp);
    event DailyCalculationExecuted(address indexed user, uint256 referralReward, uint256 leadershipReward, uint256 timestamp);
    event DailyRewardsBatchProcessed(uint256 indexed day);
    
    constructor(uint256 _lpPositionId) {
        USDT = IERC20(0x55d398326f99059fF775485246999027B3197955);
        positionManager = INonfungiblePositionManager(0x46A15B0b27311cedF172AB29E4f4766fbE7F4364);
        
        lpPositionId = _lpPositionId;
        usdtIsToken0 = true;

        plans[0] = PlanConfig(7, 300);
        plans[1] = PlanConfig(14, 1000);
        plans[2] = PlanConfig(30, 2400);
        plans[3] = PlanConfig(60, 5400);
        
        levelRequirements[0] = LevelRequirement(1, 100 ether);
        levelRequirements[1] = LevelRequirement(2, 100 ether);
        levelRequirements[2] = LevelRequirement(3, 100 ether);
        levelRequirements[3] = LevelRequirement(3, 100 ether);
        levelRequirements[4] = LevelRequirement(3, 150 ether);
        levelRequirements[5] = LevelRequirement(3, 150 ether);
        levelRequirements[6] = LevelRequirement(3, 200 ether);
        levelRequirements[7] = LevelRequirement(5, 200 ether);
        levelRequirements[8] = LevelRequirement(5, 250 ether);
        levelRequirements[9] = LevelRequirement(5, 250 ether); 
        levelRequirements[10] = LevelRequirement(7, 300 ether);
        levelRequirements[11] = LevelRequirement(7, 300 ether);
        levelRequirements[12] = LevelRequirement(7, 350 ether);
        levelRequirements[13] = LevelRequirement(7, 350 ether);
        levelRequirements[14] = LevelRequirement(7, 400 ether);
        levelRequirements[15] = LevelRequirement(7, 400 ether);
        levelRequirements[16] = LevelRequirement(7, 450 ether);
        levelRequirements[17] = LevelRequirement(7, 450 ether);
        levelRequirements[18] = LevelRequirement(7, 500 ether);
        levelRequirements[19] = LevelRequirement(7, 500 ether);
        
        ranks[0] = RankConfig(100, 250, 10000 ether);   
        ranks[1] = RankConfig(200, 500, 25000 ether);   
        ranks[2] = RankConfig(300, 1000, 50000 ether);
        ranks[3] = RankConfig(400, 2500, 100000 ether);
        ranks[4] = RankConfig(600, 5000, 200000 ether);
        ranks[5] = RankConfig(800, 7500, 500000 ether);
        ranks[6] = RankConfig(1000, 10000, 1000000 ether);

        launchDate = 1773147600; // March 10, 2026 1:00 PM UTC

        nextUserId = 1;
        string memory ownerUsername = "TurboLoop";
        User storage ownerUser = users[SERVICE_FEE_WALLET];
        ownerUser.username = ownerUsername;
        ownerUser.referrer = address(0);
        ownerUser.registered = true;
        ownerUser.userId = nextUserId;
        
        userIdToAddress[nextUserId] = SERVICE_FEE_WALLET;
        nextUserId++;
        
        usernameToAddress[ownerUsername] = SERVICE_FEE_WALLET;
        usernameExists[ownerUsername] = true;
        
        totalRegisteredUsers++;
    }
    
    
    function register(string memory username, string memory referrerUsername) external nonReentrant {
        if(launchDate == 0 || block.timestamp < launchDate) revert NotLaunched();
        if(users[msg.sender].registered) revert AlreadyRegistered();
        if(!_isValidUsername(username)) revert InvalidUsername();
        if(usernameExists[username]) revert UsernameTaken();
        
        address referrerAddr = usernameToAddress[referrerUsername];
        
        if(referrerAddr != SERVICE_FEE_WALLET) {
            if(referrerAddr == address(0)) revert ReferrerNotFound();
            if(referrerAddr == msg.sender) revert CannotSelfRefer();
            if(!users[referrerAddr].registered) revert ReferrerNotQualified();
            if(_getQualificationDeposit(referrerAddr) < REFERRAL_QUALIFICATION) revert ReferrerNotQualified();
        }
        
        User storage user = users[msg.sender];
        user.username = username;
        user.referrer = referrerAddr;
        user.registered = true;
        user.userId = nextUserId;
        
        userIdToAddress[nextUserId] = msg.sender;
        nextUserId++;
        
        usernameToAddress[username] = msg.sender;
        usernameExists[username] = true;
        
        totalRegisteredUsers++;
        
        emit Registration(msg.sender, username, referrerAddr, referrerUsername, block.timestamp);
    }
    
    function deposit(uint256 amount, uint8 planId) external nonReentrant {
        if(launchDate == 0 || block.timestamp < launchDate) revert NotLaunched();
        if(amount < MINIMUM_DEPOSIT) revert BelowMinimum();
        if(planId >= 4) revert InvalidPlan();
        
        User storage user = users[msg.sender];
        if(!user.registered) revert MustRegisterFirst();
        if(user.deposits.length >= MAX_POSITIONS) revert MaxPositions();
        
        bool isFirstDeposit = (user.totalDeposited == 0);
        
        USDT.safeTransferFrom(msg.sender, address(this), amount);
        
        uint256 actualUsed = _addLiquidityToPool(amount);
        
        uint256 serviceFee = (actualUsed * SERVICE_FEE_PCT) / PERCENTS_DIVIDER;
        _withdrawFromPool(serviceFee, SERVICE_FEE_WALLET);

        user.deposits.push(Deposit({
            amount: actualUsed,
            startTime: block.timestamp,
            lastRewardCalculation: block.timestamp,
            calculatedROI: 0,
            planId: planId,
            claimed: false
        }));
        
        user.totalDeposited += actualUsed;
        user.totalActiveDeposit += actualUsed;
        
        totalDeposited += actualUsed;
        
        _updateTeamActiveDeposit(msg.sender, actualUsed, true, false);
        
        if(isFirstDeposit) {
            _updateTeamCounters(msg.sender);
            totalActiveUsers++;
        }
        
        emit Deposited(msg.sender, actualUsed, planId, block.timestamp);
    }
    
    function claimRewards(uint256 amount) external nonReentrant {
        if(launchDate == 0 || block.timestamp < launchDate) revert NotLaunched();
        
        User storage user = users[msg.sender];
        UserExtra storage userExtra = usersExtra[msg.sender];
        if(!user.registered) revert NotRegistered();
        
        _calculateAndProcessDailyRewards(msg.sender);
        
        uint256 dailyAvailable = userExtra.dailyRewardReserve;
        uint256 networkAvailable = userExtra.networkRewardAvailable;
        uint256 totalAvailable = dailyAvailable + networkAvailable;
        
        if(totalAvailable == 0) revert NoRewards();
        
        if(amount == 0) {
            amount = totalAvailable;
        }
        
        if(amount > totalAvailable) revert InsufficientBalance();
        if(amount < MINIMUM_WITHDRAW) revert BelowMinimum();
        
        uint256 remaining = amount;
        
        if(dailyAvailable > 0 && remaining > 0) {
            if(remaining >= dailyAvailable) {
                remaining -= dailyAvailable;
                userExtra.dailyRewardReserve = 0;
            } else {
                userExtra.dailyRewardReserve -= remaining;
                remaining = 0;
            }
        }
        
        if(networkAvailable > 0 && remaining > 0) {
            if(remaining >= networkAvailable) {
                userExtra.networkRewardAvailable = 0;
            } else {
                userExtra.networkRewardAvailable -= remaining;
            }
            remaining = 0;
        }
        
        _withdrawFromPool(amount, msg.sender);
        
        user.totalWithdrawn += amount;
        totalWithdrawn += amount;
        
        emit Claimed(msg.sender, amount, block.timestamp);
    }
    
    function compoundRewards(uint256 amount, uint8 planId) external nonReentrant {
        if(launchDate == 0 || block.timestamp < launchDate) revert NotLaunched();
        if(planId >= 4) revert InvalidPlan();
        
        User storage user = users[msg.sender];
        UserExtra storage userExtra = usersExtra[msg.sender];
        if(!user.registered) revert NotRegistered();
        if(user.deposits.length >= MAX_POSITIONS) revert MaxPositions();

        _calculateAndProcessDailyRewards(msg.sender);
        
        uint256 dailyAvailable = userExtra.dailyRewardReserve;
        uint256 networkAvailable = userExtra.networkRewardAvailable;
        uint256 totalAvailable = dailyAvailable + networkAvailable;
        
        if(totalAvailable == 0) revert NoRewards();
        
        if(amount == 0) {
            amount = totalAvailable;
        }
        
        if(amount > totalAvailable) revert InsufficientBalance();
        if(amount < MINIMUM_COMPOUND) revert BelowMinimum();
        
        uint256 remaining = amount;
        
        if(dailyAvailable > 0 && remaining > 0) {
            if(remaining >= dailyAvailable) {
                remaining -= dailyAvailable;
                userExtra.dailyRewardReserve = 0;
            } else {
                userExtra.dailyRewardReserve -= remaining;
                remaining = 0;
            }
        }
        
        if(networkAvailable > 0 && remaining > 0) {
            if(remaining >= networkAvailable) {
                userExtra.networkRewardAvailable = 0;
            } else {
                userExtra.networkRewardAvailable -= remaining;
            }
            remaining = 0;
        }

        uint256 serviceFee = (amount * SERVICE_FEE_PCT) / PERCENTS_DIVIDER;
        _withdrawFromPool(serviceFee, SERVICE_FEE_WALLET);
        
        user.deposits.push(Deposit({
            amount: amount,
            startTime: block.timestamp,
            lastRewardCalculation: block.timestamp,
            calculatedROI: 0,
            planId: planId,
            claimed: false
        }));
        
        user.totalCompounded += amount;
        user.totalActiveDeposit += amount;
        
        _updateTeamActiveDeposit(msg.sender, amount, true, true);
        
        emit Compounded(msg.sender, amount, planId, block.timestamp);
    }
    
    function calculateDailyRewards(uint256 length) external nonReentrant {
        if(launchDate == 0 || block.timestamp < launchDate) revert NotLaunched();
        require(length > 0, "Length must be greater than 0");
        
        uint256 currentDay = (block.timestamp - launchDate) / TIME_STEP;
        if(currentDay == 0) return;
        
        if(dailyRewardCurrentDay == 0 || dailyRewardDayCompleted[dailyRewardCurrentDay]) {
            for(uint256 day = dailyRewardCurrentDay; day < currentDay; day++) {
                if(!dailyRewardDayCompleted[day]) {
                    dailyRewardCurrentDay = day;
                    dailyRewardLastProcessedUserId = 0;
                    break;
                }
            }
        }
        
        if(dailyRewardDayCompleted[dailyRewardCurrentDay]) {
            return;
        }
        
        uint256 processed = 0;
        uint256 startUserId = dailyRewardLastProcessedUserId == 0 ? 1 : dailyRewardLastProcessedUserId;
        uint256 processingDay = dailyRewardCurrentDay;
        
        uint256 dayEndTime = launchDate + ((processingDay + 1) * TIME_STEP);
        if(dayEndTime > block.timestamp) dayEndTime = block.timestamp;
        
        for(uint256 userId = startUserId; userId < nextUserId && processed < length; userId++) {
            address userAddr = userIdToAddress[userId];
            User storage user = users[userAddr];
            UserExtra storage userExtra = usersExtra[userAddr];
            
            if(!user.registered) {
                processed++;
                continue;
            }
            
            if(userExtra.lastCalculationTime >= dayEndTime) {
                processed++;
                continue;
            }
            
            uint256 userTotalROI = 0;
            
            for(uint256 i = 0; i < user.deposits.length; i++) {
                if(!user.deposits[i].claimed) {
                    uint256 planDuration = plans[user.deposits[i].planId].duration;
                    uint256 endTime = user.deposits[i].startTime + (planDuration * TIME_STEP);
                    uint256 lastCheckpoint = user.deposits[i].lastRewardCalculation;
                    
                    if(lastCheckpoint < endTime) {
                        uint256 calcUntil = dayEndTime < endTime ? dayEndTime : endTime;

                        if(calcUntil <= lastCheckpoint) continue;

                        uint256 timeElapsed = calcUntil - lastCheckpoint;
                        
                        if(timeElapsed > 0) {
                            uint256 roiEarned = (user.deposits[i].amount * plans[user.deposits[i].planId].totalROI * timeElapsed) / (PERCENTS_DIVIDER * planDuration * TIME_STEP);
                            userTotalROI += roiEarned;
                            
                            user.deposits[i].lastRewardCalculation = calcUntil;
                            user.deposits[i].calculatedROI += roiEarned;
                        }
                    }
                }
            }
            
            if(userTotalROI > 0) {
                _processReferralRewards(userAddr, userTotalROI);
                _processLeadershipRewards(userAddr, userTotalROI);
                dailyRewardTotalROI[processingDay] += userTotalROI;
            }
            
            userExtra.lastCalculationTime = dayEndTime;
            processed++;
            dailyRewardUsersProcessed[processingDay]++;
            
            emit DailyCalculationExecuted(userAddr, userTotalROI, 0, block.timestamp);
        }
        
        dailyRewardLastProcessedUserId = startUserId + processed;
        
        if(dailyRewardLastProcessedUserId >= nextUserId) {
            dailyRewardDayCompleted[processingDay] = true;
            if(dailyRewardTotalROI[processingDay] > 0) {
                uint256 serviceFee = (dailyRewardTotalROI[processingDay] * SERVICE_FEE_PCT) / PERCENTS_DIVIDER;
                _withdrawFromPool(serviceFee, SERVICE_FEE_WALLET);
            }
            dailyRewardLastProcessedUserId = 0;
        }
        
        emit DailyRewardsBatchProcessed(processingDay);
    }
    
    function processMyDailyRewards() external nonReentrant {
        if(launchDate == 0 || block.timestamp < launchDate) revert NotLaunched();
        if(!users[msg.sender].registered) revert NotRegistered();
        
        UserExtra storage userExtra = usersExtra[msg.sender];

        if(userExtra.lastCalculationTime >= block.timestamp) return;
        
        uint256 currentDay = (block.timestamp - launchDate) / TIME_STEP;
        uint256 startDay = userExtra.lastCalculationTime == 0
            ? 0
            : (userExtra.lastCalculationTime - launchDate) / TIME_STEP;
        
        uint256 totalAllDaysROI = 0;
        
        for(uint256 day = startDay; day <= currentDay; day++) {
            uint256 dayEndTime = launchDate + ((day + 1) * TIME_STEP);
            if(dayEndTime > block.timestamp) dayEndTime = block.timestamp;
            
            if(userExtra.lastCalculationTime >= dayEndTime) continue;
            
            uint256 dayROI = _processUserDayRewards(msg.sender, dayEndTime);
            totalAllDaysROI += dayROI;
            
            userExtra.lastCalculationTime = dayEndTime;
            emit DailyCalculationExecuted(msg.sender, dayROI, 0, block.timestamp);
        }
        
        if(totalAllDaysROI > 0) {
            _processReferralRewards(msg.sender, totalAllDaysROI);
            _processLeadershipRewards(msg.sender, totalAllDaysROI);        

            uint256 serviceFee = (totalAllDaysROI * SERVICE_FEE_PCT) / PERCENTS_DIVIDER;
            _withdrawFromPool(serviceFee, SERVICE_FEE_WALLET);
        }
    }
    
    function _processUserDayRewards(address userAddr, uint256 dayEndTime) internal returns (uint256 totalROI) {
        User storage user = users[userAddr];
        
        for(uint256 i = 0; i < user.deposits.length; i++) {
            if(!user.deposits[i].claimed) {
                uint256 duration = plans[user.deposits[i].planId].duration;
                uint256 endTime = user.deposits[i].startTime + (duration * TIME_STEP);
                
                if(user.deposits[i].lastRewardCalculation < endTime) {
                    uint256 calcUntil = dayEndTime < endTime ? dayEndTime : endTime;

                    if(calcUntil <= user.deposits[i].lastRewardCalculation) continue;

                    uint256 elapsed = calcUntil - user.deposits[i].lastRewardCalculation;
                    
                    if(elapsed > 0) {
                        uint256 roi = (user.deposits[i].amount * plans[user.deposits[i].planId].totalROI * elapsed) / (PERCENTS_DIVIDER * duration * TIME_STEP);
                        totalROI += roi;
                        user.deposits[i].lastRewardCalculation = calcUntil;
                        user.deposits[i].calculatedROI += roi;
                    }
                }
                
                if(dayEndTime >= endTime) {
                    uint256 expected = (user.deposits[i].amount * plans[user.deposits[i].planId].totalROI) / PERCENTS_DIVIDER;
                    if(user.deposits[i].calculatedROI < expected) {
                        uint256 remaining = expected - user.deposits[i].calculatedROI;
                        totalROI += remaining;
                        user.deposits[i].calculatedROI = expected;
                    }
                }
            }
        }
    }
    
    function _calculateAndProcessDailyRewards(address userAddr) internal returns (uint256 totalProfit) {
        User storage user = users[userAddr];
        UserExtra storage userExtra = usersExtra[userAddr];
        uint256 totalExpiredAmount = 0;
        uint256 remainDailyROI = 0;
        totalProfit = 0;
        
        for(uint256 i = 0; i < user.deposits.length; i++) {
            if(!user.deposits[i].claimed) {
                uint256 endTime = user.deposits[i].startTime + (plans[user.deposits[i].planId].duration * TIME_STEP);
                if(block.timestamp >= endTime) {
                    uint256 profit = user.deposits[i].amount + ((user.deposits[i].amount * plans[user.deposits[i].planId].totalROI) / PERCENTS_DIVIDER);
                    
                    uint256 totalROI = (user.deposits[i].amount * plans[user.deposits[i].planId].totalROI) / PERCENTS_DIVIDER;
                    if(totalROI > user.deposits[i].calculatedROI){
                        remainDailyROI += (totalROI - user.deposits[i].calculatedROI);
                    }

                    
                    
                    user.deposits[i].claimed = true;
                    
                    if(user.totalActiveDeposit >= user.deposits[i].amount) {
                        user.totalActiveDeposit -= user.deposits[i].amount;
                        totalExpiredAmount += user.deposits[i].amount;
                    }

                    userExtra.totalROIEarned += totalROI;
                    userExtra.dailyRewardReserve += profit;
                    totalProfit += profit;
                }
            }
        }

        if (totalExpiredAmount > 0) {
            _updateTeamActiveDeposit(userAddr, totalExpiredAmount, false, false);
        }
        if(remainDailyROI > 0){
            _processReferralRewards(userAddr, remainDailyROI);
            _processLeadershipRewards(userAddr, remainDailyROI);

            uint256 serviceFee = (remainDailyROI * SERVICE_FEE_PCT) / PERCENTS_DIVIDER;
            _withdrawFromPool(serviceFee, SERVICE_FEE_WALLET);
        }
        
        return totalProfit;
    }
    
    function _getAvailableROI(address userAddr) internal view returns (uint256 total) {
        User storage user = users[userAddr];
        UserExtra storage userExtra = usersExtra[userAddr];
        
        total = userExtra.dailyRewardReserve;
        
        for(uint256 i = 0; i < user.deposits.length; i++) {
            if(!user.deposits[i].claimed) {
                uint256 endTime = user.deposits[i].startTime + (plans[user.deposits[i].planId].duration * TIME_STEP);
                if(block.timestamp >= endTime) {
                    total += user.deposits[i].amount + ((user.deposits[i].amount * plans[user.deposits[i].planId].totalROI) / PERCENTS_DIVIDER);
                }
            }
        }
        
        return total;
    }
    
    function _processReferralRewards(address userAddr, uint256 dailyROI) internal {
        address current = users[userAddr].referrer;
        
        for(uint8 level = 0; level < REFERRAL_DEPTH && current != address(0); level++) {
            UserExtra storage uplineExtra = usersExtra[current];
            
            if(_isLevelUnlocked(current, level)) {
                uint256 reward = (dailyROI * REFERRAL_REWARDS[level]) / PERCENTS_DIVIDER;
                uplineExtra.networkRewardAvailable += reward;
                uplineExtra.totalReferralReward += reward;
                levelReferralEarned[current][level] += reward;
                
                emit ReferralReward(current, userAddr, level + 1, reward, block.timestamp);
            }
            
            current = users[current].referrer;
        }
    }
    
    function _processLeadershipRewards(address userAddr, uint256 dailyROI) internal {
        address current = users[userAddr].referrer;
        uint256 highestPctPaid = 0;
        
        for(uint8 depth = 0; depth < MAX_UPLINE_DEPTH && current != address(0); depth++) {
            User storage upline = users[current];
            UserExtra storage uplineExtra = usersExtra[current];
            
            uint8 currentRank = uplineExtra.currentRank;
            uint256 rankPct = 0;
            

            if(uplineExtra.teamCount >= ranks[currentRank].teamCountNeeded &&
               upline.teamActiveDeposit >= ranks[currentRank].teamActiveDepositNeeded) {
                rankPct = ranks[currentRank].rewardPct;
            }
            
            if(rankPct > highestPctPaid) {
                uint256 diff = rankPct - highestPctPaid;
                uint256 reward = (dailyROI * diff) / PERCENTS_DIVIDER;
                
                uplineExtra.networkRewardAvailable += reward;
                uplineExtra.totalLeadershipReward += reward;
                
                emit LeadershipReward(current, userAddr, currentRank, reward, block.timestamp);
                
                highestPctPaid = rankPct;
            }
            
            if(highestPctPaid >= MAX_LEADERSHIP_PCT) break;
            
            current = upline.referrer;
        }
    }
    
    function _isLevelUnlocked(address userAddr, uint8 level) internal view returns (bool) {
        if(level >= REFERRAL_DEPTH) return false;
        
        UserExtra storage userExtra = usersExtra[userAddr];
        LevelRequirement memory req = levelRequirements[level];
        
        return (userExtra.qualifiedDirects >= req.minDirects && 
                _getQualificationDeposit(userAddr) >= req.minSelfAUM);
    }
    
    function _updateTeamCounters(address userAddr) internal {
        address current = users[userAddr].referrer;
        
        if(current != address(0)) {
            usersExtra[current].directsCount++;
        }
        
        uint8 depth = 0;
        while(current != address(0) && depth < MAX_UPLINE_DEPTH) {
            usersExtra[current].teamCount++;
            
            if(depth < REFERRAL_DEPTH) {
                levelDownlineCount[current][depth]++;
            }
            
            _updateRank(current);
            
            current = users[current].referrer;
            depth++;
        }
    }
    
    function _updateTeamActiveDeposit(address userAddr, uint256 amount, bool isAdding, bool isCompound) internal {
        address current = users[userAddr].referrer;
        
        if(current != address(0)) {
            UserExtra storage sponsorExtra = usersExtra[current];
            uint256 userActive = users[userAddr].totalActiveDeposit;
            
            if(isAdding) {
                if(userActive >= REFERRAL_QUALIFICATION && 
                   userActive - amount < REFERRAL_QUALIFICATION) {
                    sponsorExtra.qualifiedDirects++;
                }
            } else {
                if(userActive < REFERRAL_QUALIFICATION && 
                   userActive + amount >= REFERRAL_QUALIFICATION) {
                    if(sponsorExtra.qualifiedDirects > 0) {
                        sponsorExtra.qualifiedDirects--;
                    }
                }
            }
        }
        
        uint8 depth = 0;
        while(current != address(0) && depth < MAX_UPLINE_DEPTH) {
            if(isAdding) {
                users[current].teamActiveDeposit += amount;
                if(isCompound) {
                    users[current].teamTotalCompound += amount;
                }else{
                    users[current].teamTotalDeposit += amount;
                }
            } else {
                if(users[current].teamActiveDeposit >= amount) {
                    users[current].teamActiveDeposit -= amount;
                } else {
                    users[current].teamActiveDeposit = 0;
                }
            }
            
            _updateRank(current);
            
            current = users[current].referrer;
            depth++;
        }
    }
    
    function _updateRank(address userAddr) internal {
        User storage user = users[userAddr];
        UserExtra storage userExtra = usersExtra[userAddr];
        uint8 newRank = userExtra.currentRank;
        
        for (uint8 i = 6; ; i--) {
            if (userExtra.teamCount >= ranks[i].teamCountNeeded &&
                user.teamActiveDeposit >= ranks[i].teamActiveDepositNeeded) {
                newRank = i;
                break;
            }
            if (i == 0) break;
        }
        
        if (newRank != userExtra.currentRank) {
            userExtra.currentRank = newRank;
            emit RankUpgraded(userAddr, newRank, block.timestamp);
        }
    }
    
    function _addLiquidityToPool(uint256 usdtAmount) internal returns (uint256 actualUsed) {
        if(usdtAmount == 0) return 0;
        
        USDT.forceApprove(address(positionManager), usdtAmount);
        
        uint256 amount0Desired = usdtIsToken0 ? usdtAmount : 0;
        uint256 amount1Desired = usdtIsToken0 ? 0 : usdtAmount;
        
        uint256 amount0Min = (amount0Desired * 99) / 100;
        uint256 amount1Min = (amount1Desired * 99) / 100;
        
        (, uint256 amount0Used, uint256 amount1Used) = positionManager.increaseLiquidity(
            INonfungiblePositionManager.IncreaseLiquidityParams({
                tokenId: lpPositionId,
                amount0Desired: amount0Desired,
                amount1Desired: amount1Desired,
                amount0Min: amount0Min,
                amount1Min: amount1Min,
                deadline: block.timestamp + 300
            })
        );
        
        actualUsed = usdtIsToken0 ? amount0Used : amount1Used;
        
        if(usdtAmount > actualUsed) {
            uint256 refund = usdtAmount - actualUsed;
            USDT.safeTransfer(msg.sender, refund);
        }
        
        return actualUsed;
    }
    
    function _withdrawFromPool(uint256 amountNeeded, address recipient) internal {
        if(amountNeeded == 0) return;
        
        (,,,,,,,uint128 liquidity,,,uint128 tokensOwed0, uint128 tokensOwed1) = positionManager.positions(lpPositionId);
        
        uint128 usdtOwed = usdtIsToken0 ? tokensOwed0 : tokensOwed1;
        
        if(usdtOwed < amountNeeded) {
            uint256 deficit = amountNeeded - usdtOwed;
            uint256 liquidityNeeded = (deficit * USDT_TO_LIQUIDITY_RATE) / 1 ether;
            uint128 liquidityToRemove = uint128(liquidityNeeded);
            
            if(liquidityToRemove == 0) liquidityToRemove = 1;
            require(liquidityToRemove <= liquidity, "Insufficient LP liquidity");
            
            positionManager.decreaseLiquidity(
                INonfungiblePositionManager.DecreaseLiquidityParams({
                    tokenId: lpPositionId,
                    liquidity: liquidityToRemove,
                    amount0Min: 0,
                    amount1Min: 0,
                    deadline: block.timestamp + 300
                })
            );
        }
        
        positionManager.collect(
            INonfungiblePositionManager.CollectParams({
                tokenId: lpPositionId,
                recipient: recipient,
                amount0Max: type(uint128).max,
                amount1Max: type(uint128).max
            })
        );
    }
    
    function _getQualificationDeposit(address userAddr) internal view returns (uint256) {
        User storage user = users[userAddr];
        return user.deposits.length >= MAX_POSITIONS ? user.totalDeposited : user.totalActiveDeposit;
    }
    
    function _isValidUsername(string memory username) internal pure returns (bool) {
        bytes memory b = bytes(username);
        if(b.length < 3 || b.length > 20) return false;
        
        for(uint256 i = 0; i < b.length; i++) {
            bytes1 char = b[i];
            if(!(char >= 0x30 && char <= 0x39) &&  // 0-9
               !(char >= 0x41 && char <= 0x5A) &&  // A-Z
               !(char >= 0x61 && char <= 0x7A))    // a-z
            {
                return false;
            }
        }
        return true;
    }
    
    // View functions
    
    function getUserInfoExtra(address userAddr) external view returns (uint256 realActiveDeposit, uint256 activeDepositsCount, uint8 rank) {
        User storage user = users[userAddr];
        UserExtra storage userExtra = usersExtra[userAddr];
        Deposit[] storage deposits = user.deposits;
        for(uint256 i = 0; i < deposits.length; i++) {
            if(deposits[i].claimed) continue;
            uint256 endTime = deposits[i].startTime + (plans[deposits[i].planId].duration * TIME_STEP);
            if(block.timestamp >= endTime) continue;
            realActiveDeposit += deposits[i].amount;
            activeDepositsCount++;
        }
        return (realActiveDeposit, activeDepositsCount, userExtra.currentRank);
    }
    
    function getUserInfo(address userAddr) external view returns (
        string memory username,
        address referrer,
        bool registered,
        uint256 _totalActiveDeposit,
        uint256 _totalDeposited,
        uint256 _totalWithdrawn,
        uint256 _totalCompounded
    ) {
        User storage user = users[userAddr];
        
        return (
            user.username,
            user.referrer,
            user.registered,
            user.totalActiveDeposit,
            user.totalDeposited,
            user.totalWithdrawn,
            user.totalCompounded
        );
    }
    
    function getUserTeamInfo(address userAddr) external view returns (
        uint256 teamActiveDeposit,
        uint256 teamTotalDeposit,
        uint32 teamCount,
        uint32 directsCount,
        uint32 qualifiedDirects,
        uint8 currentRank
    ) {
        User storage user = users[userAddr];
        UserExtra storage userExtra = usersExtra[userAddr];
        
        return (
            user.teamActiveDeposit,
            user.teamTotalDeposit,
            userExtra.teamCount,
            userExtra.directsCount,
            userExtra.qualifiedDirects,
            userExtra.currentRank
        );
    }
    
    function getDepositInfo(address userAddr, uint256 index) external view returns (
        uint256 amount,
        uint256 startTime,
        uint256 endTime,
        uint8 planId,
        bool claimed,
        bool isMatured,
        uint256 expectedROI,
        uint256 generatedROI
    ) {
        User storage user = users[userAddr];
        require(index < user.deposits.length, "Invalid index");
        
        Deposit storage dep = user.deposits[index];
        uint256 planDuration = plans[dep.planId].duration;
        uint256 _endTime = dep.startTime + (planDuration * TIME_STEP);
        uint256 roi = (dep.amount * plans[dep.planId].totalROI) / PERCENTS_DIVIDER;
        
        uint256 calcUntil = block.timestamp > _endTime ? _endTime : block.timestamp;
        uint256 timeElapsed = calcUntil > dep.startTime ? calcUntil - dep.startTime : 0;
        uint256 _generatedROI = timeElapsed > 0 ? (dep.amount * plans[dep.planId].totalROI * timeElapsed) / (PERCENTS_DIVIDER * planDuration * TIME_STEP) : 0;
        
        return (
            dep.amount,
            dep.startTime,
            _endTime,
            dep.planId,
            dep.claimed,
            block.timestamp >= _endTime,
            roi,
            _generatedROI
        );
    }
    
    function getLevelDownlines(address userAddr) external view returns (uint32[20] memory downlines) {
        for(uint8 i = 0; i < 20; i++) {
            downlines[i] = levelDownlineCount[userAddr][i];
        }
        return downlines;
    }
    
    function getLevelEarnings(address userAddr) external view returns (uint256[20] memory earnings) {
        for(uint8 i = 0; i < 20; i++) {
            earnings[i] = levelReferralEarned[userAddr][i];
        }
        return earnings;
    }
    
    function getAvailableRewards(address userAddr) external view returns (
        uint256 totalAvailable,
        uint256 dailyROIAvailable,
        uint256 dailyReserve,
        uint256 networkAvailable,
        uint256 totalReferral,
        uint256 totalLeadership
    ) {
        UserExtra storage userExtra = usersExtra[userAddr];
        uint256 dailyAvailable = _getAvailableROI(userAddr);
        uint256 netAvailable = userExtra.networkRewardAvailable;
        
        return (
            dailyAvailable + netAvailable,
            dailyAvailable,
            userExtra.dailyRewardReserve,
            userExtra.networkRewardAvailable,
            userExtra.totalReferralReward,
            userExtra.totalLeadershipReward
        );
    }
    
    function getDepositCount(address userAddr) external view returns (uint256) {
        return users[userAddr].deposits.length;
    }
    
    function getPlanInfo(uint8 planId) external view returns (uint256 duration, uint256 totalROI) {
        require(planId < 4, "Invalid plan");
        return (plans[planId].duration, plans[planId].totalROI);
    }
    
    function getRankInfo(uint8 rankIndex) external view returns (
        uint256 rewardPct,
        uint32 teamCountNeeded,
        uint256 teamActiveDepositNeeded
    ) {
        require(rankIndex < 7, "Invalid rank");
        RankConfig memory rank = ranks[rankIndex];
        return (rank.rewardPct, rank.teamCountNeeded, rank.teamActiveDepositNeeded);
    }
    
    function isValidUsername(string memory username) external view returns (bool) {
        if(!_isValidUsername(username)) return false;
        if(usernameExists[username]) return false;
        return true;
    }
    
    function getDailyRewardStatus() external view returns (
        uint256 currentDay,
        uint256 processingDay,
        uint256 lastProcessedUserId,
        uint256 totalUsers,
        uint256 remainingUsers
    ) {
        currentDay = (block.timestamp - launchDate) / TIME_STEP;
        processingDay = dailyRewardCurrentDay;
        lastProcessedUserId = dailyRewardLastProcessedUserId;
        totalUsers = nextUserId > 0 ? nextUserId - 1 : 0;
        uint256 firstUserId = lastProcessedUserId == 0 ? 1 : lastProcessedUserId;
        remainingUsers = nextUserId > firstUserId ? nextUserId - firstUserId : 0;
        
        return (currentDay, processingDay, lastProcessedUserId, totalUsers, remainingUsers);
    }
    
    function needsDailyRewardCalculation() external view returns (bool needCall, uint256 remainingUsers) {
        if(launchDate == 0 || block.timestamp < launchDate) return (false, 0);
        
        uint256 currentDay = (block.timestamp - launchDate) / TIME_STEP;
        if(currentDay == 0) return (false, 0);
        
        uint256 processingDay = dailyRewardCurrentDay;
        uint256 lastProcessed = dailyRewardLastProcessedUserId;
        
        if(processingDay == 0 || dailyRewardDayCompleted[processingDay]) {
            for(uint256 day = processingDay; day < currentDay; day++) {
                if(!dailyRewardDayCompleted[day]) {
                    processingDay = day;
                    lastProcessed = 0;
                    break;
                }
            }
        }
        
        if(dailyRewardDayCompleted[processingDay]) return (false, 0);
        
        uint256 firstUserId = lastProcessed == 0 ? 1 : lastProcessed;
        remainingUsers = nextUserId > firstUserId ? nextUserId - firstUserId : 0;
        return (remainingUsers > 0, remainingUsers);
    }
    
    function getDayInfo(uint256 day) external view returns (
        bool completed,
        uint256 usersProcessed,
        uint256 totalROI
    ) {
        return (
            dailyRewardDayCompleted[day],
            dailyRewardUsersProcessed[day],
            dailyRewardTotalROI[day]
        );
    }
    
    function isValidReferrer(string memory referrerUsername, address userAddr) external view returns (bool) {
        address referrerAddr = usernameToAddress[referrerUsername];
        
        if(referrerAddr == SERVICE_FEE_WALLET) return true;
        if(referrerAddr == address(0)) return false;
        if(referrerAddr == userAddr) return false;
        if(!users[referrerAddr].registered) return false;
        if(_getQualificationDeposit(referrerAddr) < REFERRAL_QUALIFICATION) return false;
        
        return true;
    }
    
    function getContractStats() external view returns (
        uint256 _totalRegisteredUsers,
        uint256 _totalActiveUsers,
        uint256 _launchDate
    ) {
        return (
            totalRegisteredUsers,
            totalActiveUsers,
            launchDate
        );
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.5.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC-20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    /**
     * @dev An operation with an ERC-20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        if (!_safeTransfer(token, to, value, true)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        if (!_safeTransferFrom(token, from, to, value, true)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
     */
    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
        return _safeTransfer(token, to, value, false);
    }

    /**
     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
     */
    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
        return _safeTransferFrom(token, from, to, value, false);
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     *
     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
     * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     *
     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
     * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     *
     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
     * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
     * set here.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        if (!_safeApprove(token, spender, value, false)) {
            if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));
            if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
     * code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when
     * targeting contracts.
     *
     * Reverts if the returned value is other than `true`.
     */
    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
        if (to.code.length == 0) {
            safeTransfer(token, to, value);
        } else if (!token.transferAndCall(to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
     * has no code. This can be used to implement an {ERC721}-like safe transfer that relies on {ERC1363} checks when
     * targeting contracts.
     *
     * Reverts if the returned value is other than `true`.
     */
    function transferFromAndCallRelaxed(
        IERC1363 token,
        address from,
        address to,
        uint256 value,
        bytes memory data
    ) internal {
        if (to.code.length == 0) {
            safeTransferFrom(token, from, to, value);
        } else if (!token.transferFromAndCall(from, to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
     * Oppositely, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
     * once without retrying, and relies on the returned value to be true.
     *
     * Reverts if the returned value is other than `true`.
     */
    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
        if (to.code.length == 0) {
            forceApprove(token, to, value);
        } else if (!token.approveAndCall(to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity `token.transfer(to, value)` call, relaxing the requirement on the return value: the
     * return value is optional (but if data is returned, it must not be false).
     *
     * @param token The token targeted by the call.
     * @param to The recipient of the tokens
     * @param value The amount of token to transfer
     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
     */
    function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {
        bytes4 selector = IERC20.transfer.selector;

        assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(0x00, selector)
            mstore(0x04, and(to, shr(96, not(0))))
            mstore(0x24, value)
            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
            // if call success and return is true, all is good.
            // otherwise (not success or return is not true), we need to perform further checks
            if iszero(and(success, eq(mload(0x00), 1))) {
                // if the call was a failure and bubble is enabled, bubble the error
                if and(iszero(success), bubble) {
                    returndatacopy(fmp, 0x00, returndatasize())
                    revert(fmp, returndatasize())
                }
                // if the return value is not true, then the call is only successful if:
                // - the token address has code
                // - the returndata is empty
                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
            }
            mstore(0x40, fmp)
        }
    }

    /**
     * @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, relaxing the requirement on the return
     * value: the return value is optional (but if data is returned, it must not be false).
     *
     * @param token The token targeted by the call.
     * @param from The sender of the tokens
     * @param to The recipient of the tokens
     * @param value The amount of token to transfer
     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
     */
    function _safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value,
        bool bubble
    ) private returns (bool success) {
        bytes4 selector = IERC20.transferFrom.selector;

        assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(0x00, selector)
            mstore(0x04, and(from, shr(96, not(0))))
            mstore(0x24, and(to, shr(96, not(0))))
            mstore(0x44, value)
            success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)
            // if call success and return is true, all is good.
            // otherwise (not success or return is not true), we need to perform further checks
            if iszero(and(success, eq(mload(0x00), 1))) {
                // if the call was a failure and bubble is enabled, bubble the error
                if and(iszero(success), bubble) {
                    returndatacopy(fmp, 0x00, returndatasize())
                    revert(fmp, returndatasize())
                }
                // if the return value is not true, then the call is only successful if:
                // - the token address has code
                // - the returndata is empty
                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
            }
            mstore(0x40, fmp)
            mstore(0x60, 0)
        }
    }

    /**
     * @dev Imitates a Solidity `token.approve(spender, value)` call, relaxing the requirement on the return value:
     * the return value is optional (but if data is returned, it must not be false).
     *
     * @param token The token targeted by the call.
     * @param spender The spender of the tokens
     * @param value The amount of token to transfer
     * @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
     */
    function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {
        bytes4 selector = IERC20.approve.selector;

        assembly ("memory-safe") {
            let fmp := mload(0x40)
            mstore(0x00, selector)
            mstore(0x04, and(spender, shr(96, not(0))))
            mstore(0x24, value)
            success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
            // if call success and return is true, all is good.
            // otherwise (not success or return is not true), we need to perform further checks
            if iszero(and(success, eq(mload(0x00), 1))) {
                // if the call was a failure and bubble is enabled, bubble the error
                if and(iszero(success), bubble) {
                    returndatacopy(fmp, 0x00, returndatasize())
                    revert(fmp, returndatasize())
                }
                // if the return value is not true, then the call is only successful if:
                // - the token address has code
                // - the returndata is empty
                success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
            }
            mstore(0x40, fmp)
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)

pragma solidity >=0.4.16;

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

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

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

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

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

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

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

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
 * consider using {ReentrancyGuardTransient} instead.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)

pragma solidity >=0.6.2;

import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";

/**
 * @title IERC1363
 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
 *
 * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
 * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
 */
interface IERC1363 is IERC20, IERC165 {
    /*
     * Note: the ERC-165 identifier for this interface is 0xb0202a11.
     * 0xb0202a11 ===
     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^
     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
     */

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferAndCall(address to, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @param data Additional data with no specified format, sent in call to `to`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param from The address which you want to send tokens from.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param from The address which you want to send tokens from.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @param data Additional data with no specified format, sent in call to `to`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function approveAndCall(address spender, uint256 value) external returns (bool);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     * @param data Additional data with no specified format, sent in call to `spender`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}

File 6 of 8 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)

pragma solidity >=0.4.16;

import {IERC165} from "../utils/introspection/IERC165.sol";

File 7 of 8 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20.sol)

pragma solidity >=0.4.16;

import {IERC20} from "../token/ERC20/IERC20.sol";

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)

pragma solidity >=0.4.16;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "remappings": []
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"uint256","name":"_lpPositionId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyRegistered","type":"error"},{"inputs":[],"name":"BelowMinimum","type":"error"},{"inputs":[],"name":"CannotSelfRefer","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidPlan","type":"error"},{"inputs":[],"name":"InvalidUsername","type":"error"},{"inputs":[],"name":"MaxPositions","type":"error"},{"inputs":[],"name":"MustRegisterFirst","type":"error"},{"inputs":[],"name":"NoRewards","type":"error"},{"inputs":[],"name":"NotLaunched","type":"error"},{"inputs":[],"name":"NotOwner","type":"error"},{"inputs":[],"name":"NotRegistered","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"ReferrerNotFound","type":"error"},{"inputs":[],"name":"ReferrerNotQualified","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"UsernameTaken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"planId","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Compounded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"referralReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"leadershipReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"DailyCalculationExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"day","type":"uint256"}],"name":"DailyRewardsBatchProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"planId","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"upline","type":"address"},{"indexed":true,"internalType":"address","name":"downline","type":"address"},{"indexed":false,"internalType":"uint8","name":"rank","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"LeadershipReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint8","name":"newRank","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RankUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"upline","type":"address"},{"indexed":true,"internalType":"address","name":"downline","type":"address"},{"indexed":false,"internalType":"uint8","name":"level","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ReferralReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"string","name":"username","type":"string"},{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"string","name":"uplineUsername","type":"string"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Registration","type":"event"},{"inputs":[],"name":"SERVICE_FEE_WALLET","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIME_STEP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"calculateDailyRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"planId","type":"uint8"}],"name":"compoundRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dailyRewardCurrentDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dailyRewardDayCompleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dailyRewardLastProcessedUserId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dailyRewardTotalROI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dailyRewardUsersProcessed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"planId","type":"uint8"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"}],"name":"getAvailableRewards","outputs":[{"internalType":"uint256","name":"totalAvailable","type":"uint256"},{"internalType":"uint256","name":"dailyROIAvailable","type":"uint256"},{"internalType":"uint256","name":"dailyReserve","type":"uint256"},{"internalType":"uint256","name":"networkAvailable","type":"uint256"},{"internalType":"uint256","name":"totalReferral","type":"uint256"},{"internalType":"uint256","name":"totalLeadership","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractStats","outputs":[{"internalType":"uint256","name":"_totalRegisteredUsers","type":"uint256"},{"internalType":"uint256","name":"_totalActiveUsers","type":"uint256"},{"internalType":"uint256","name":"_launchDate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDailyRewardStatus","outputs":[{"internalType":"uint256","name":"currentDay","type":"uint256"},{"internalType":"uint256","name":"processingDay","type":"uint256"},{"internalType":"uint256","name":"lastProcessedUserId","type":"uint256"},{"internalType":"uint256","name":"totalUsers","type":"uint256"},{"internalType":"uint256","name":"remainingUsers","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"day","type":"uint256"}],"name":"getDayInfo","outputs":[{"internalType":"bool","name":"completed","type":"bool"},{"internalType":"uint256","name":"usersProcessed","type":"uint256"},{"internalType":"uint256","name":"totalROI","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"}],"name":"getDepositCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getDepositInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint8","name":"planId","type":"uint8"},{"internalType":"bool","name":"claimed","type":"bool"},{"internalType":"bool","name":"isMatured","type":"bool"},{"internalType":"uint256","name":"expectedROI","type":"uint256"},{"internalType":"uint256","name":"generatedROI","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"}],"name":"getLevelDownlines","outputs":[{"internalType":"uint32[20]","name":"downlines","type":"uint32[20]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"}],"name":"getLevelEarnings","outputs":[{"internalType":"uint256[20]","name":"earnings","type":"uint256[20]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"planId","type":"uint8"}],"name":"getPlanInfo","outputs":[{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"totalROI","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"rankIndex","type":"uint8"}],"name":"getRankInfo","outputs":[{"internalType":"uint256","name":"rewardPct","type":"uint256"},{"internalType":"uint32","name":"teamCountNeeded","type":"uint32"},{"internalType":"uint256","name":"teamActiveDepositNeeded","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"}],"name":"getUserInfo","outputs":[{"internalType":"string","name":"username","type":"string"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"bool","name":"registered","type":"bool"},{"internalType":"uint256","name":"_totalActiveDeposit","type":"uint256"},{"internalType":"uint256","name":"_totalDeposited","type":"uint256"},{"internalType":"uint256","name":"_totalWithdrawn","type":"uint256"},{"internalType":"uint256","name":"_totalCompounded","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"}],"name":"getUserInfoExtra","outputs":[{"internalType":"uint256","name":"realActiveDeposit","type":"uint256"},{"internalType":"uint256","name":"activeDepositsCount","type":"uint256"},{"internalType":"uint8","name":"rank","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddr","type":"address"}],"name":"getUserTeamInfo","outputs":[{"internalType":"uint256","name":"teamActiveDeposit","type":"uint256"},{"internalType":"uint256","name":"teamTotalDeposit","type":"uint256"},{"internalType":"uint32","name":"teamCount","type":"uint32"},{"internalType":"uint32","name":"directsCount","type":"uint32"},{"internalType":"uint32","name":"qualifiedDirects","type":"uint32"},{"internalType":"uint8","name":"currentRank","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"referrerUsername","type":"string"},{"internalType":"address","name":"userAddr","type":"address"}],"name":"isValidReferrer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"username","type":"string"}],"name":"isValidUsername","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"levelDownlineCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint8","name":"","type":"uint8"}],"name":"levelReferralEarned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"levelRequirements","outputs":[{"internalType":"uint8","name":"minDirects","type":"uint8"},{"internalType":"uint256","name":"minSelfAUM","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"needsDailyRewardCalculation","outputs":[{"internalType":"bool","name":"needCall","type":"bool"},{"internalType":"uint256","name":"remainingUsers","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextUserId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"plans","outputs":[{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"totalROI","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"processMyDailyRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ranks","outputs":[{"internalType":"uint256","name":"rewardPct","type":"uint256"},{"internalType":"uint32","name":"teamCountNeeded","type":"uint32"},{"internalType":"uint256","name":"teamActiveDepositNeeded","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"username","type":"string"},{"internalType":"string","name":"referrerUsername","type":"string"}],"name":"register","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalActiveUsers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRegisteredUsers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdtIsToken0","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"userIdToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"usernameExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"usernameToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"users","outputs":[{"internalType":"address","name":"referrer","type":"address"},{"internalType":"string","name":"username","type":"string"},{"internalType":"bool","name":"registered","type":"bool"},{"internalType":"uint256","name":"userId","type":"uint256"},{"internalType":"uint256","name":"totalActiveDeposit","type":"uint256"},{"internalType":"uint256","name":"teamActiveDeposit","type":"uint256"},{"internalType":"uint256","name":"teamTotalDeposit","type":"uint256"},{"internalType":"uint256","name":"teamTotalCompound","type":"uint256"},{"internalType":"uint256","name":"totalDeposited","type":"uint256"},{"internalType":"uint256","name":"totalWithdrawn","type":"uint256"},{"internalType":"uint256","name":"totalCompounded","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"usersExtra","outputs":[{"internalType":"uint256","name":"networkRewardAvailable","type":"uint256"},{"internalType":"uint256","name":"dailyRewardReserve","type":"uint256"},{"internalType":"uint256","name":"totalReferralReward","type":"uint256"},{"internalType":"uint256","name":"totalROIEarned","type":"uint256"},{"internalType":"uint256","name":"totalLeadershipReward","type":"uint256"},{"internalType":"uint32","name":"teamCount","type":"uint32"},{"internalType":"uint32","name":"directsCount","type":"uint32"},{"internalType":"uint32","name":"qualifiedDirects","type":"uint32"},{"internalType":"uint8","name":"currentRank","type":"uint8"},{"internalType":"uint256","name":"lastCalculationTime","type":"uint256"}],"stateMutability":"view","type":"function"}]

6103806040526104b06101009081526103206101208190526101f4610140526101906101605261012c6101805260c86101a08190526101c08190526101e05260966102008190526102205260646102408190526102608190526102808190526102a08190526102c08190526102e081905261030081905290819052610340819052610360526200009490600b90601462000d9e565b50348015620000a1575f80fd5b5060405162005e3f38038062005e3f833981016040819052620000c49162000dfd565b60015f81905580546001600160a01b031916331781557355d398326f99059ff775485246999027b31979556080527346a15b0b27311cedf172ab29e4f4766fbe7f436460a05260c082905260e052604080518082018252600780825261012c6020928301819052600382815560049190915583518085018552600e8082526103e891850182905260055560065583518085018552601e8082526109609185018290529092556008919091558251808401909352603c83526115189183019190915280825160029182029290920191825560209283015160019283015560408051808201825283815268056bc75e2d631000008186018181525f808052601f80895293517f8c60882dec3cf54096060609fdd16c336781b436ca34f3f27a220dfcfa1d4855805460ff1990811660ff9384161790915592517f8c60882dec3cf54096060609fdd16c336781b436ca34f3f27a220dfcfa1d48565585518087018752878152808a01858152898452868b5290517f820fef5837650fa3b8e45045b88059d8deaf0810350ec511c47ef768a28c2c9b80548616918416919091179055517f820fef5837650fa3b8e45045b88059d8deaf0810350ec511c47ef768a28c2c9c55855180870187526003808252818b01868152898552878c5291517f5af4fb70d755f38349f04272636124ff9474fedf9ea09deea577daa305383b108054871691851691909117905590517f5af4fb70d755f38349f04272636124ff9474fedf9ea09deea577daa305383b115586518088018852818152808b01958652818452868b52517f9e71908050462d95d85d10ec71f33c35476f5af9a2363ff3b4f561b1ea6200508054861691841691909117905593517f9e71908050462d95d85d10ec71f33c35476f5af9a2363ff3b4f561b1ea6200515585518087018752848152680821ab0d4414980000818b0181815260048552878c5291517f44ef42eef5af19d25d4e44ae57c825e0d0624b9f37f2474ab961410a0aa295ff8054871691851691909117905590517f44ef42eef5af19d25d4e44ae57c825e0d0624b9f37f2474ab961410a0aa296005586518088018852858152808b019182526005808552878c5290517f8f7baaeb89fd2366535b48ed7d56321470a1399e8ab1b2456eb79477a77d951b8054871691851691909117905590517f8f7baaeb89fd2366535b48ed7d56321470a1399e8ab1b2456eb79477a77d951c5586518088018852948552680ad78ebc5ac6200000858b0181815260068552878c5295517fb59afb99c4de88e28b26eef6d7a02f582ab97b4ec5fdb5cf1f0116f112f13bde8054871691851691909117905594517fb59afb99c4de88e28b26eef6d7a02f582ab97b4ec5fdb5cf1f0116f112f13bdf5586518088018852818152808b019586526007808552878c5290517f5b3e240a505832e5e6c9a7abee1f9f8788f1ffd3b8bbc82bdedad1079d3734a68054871691851691909117905594517f5b3e240a505832e5e6c9a7abee1f9f8788f1ffd3b8bbc82bdedad1079d3734a75586518088018852818152680d8d726b7177a80000818c0181815260088652888d5291517f290280e7d5e2935e0b50d8b53915f33263d19e3d9e4512b77c7193cae76e01688054881691861691909117905590517f290280e7d5e2935e0b50d8b53915f33263d19e3d9e4512b77c7193cae76e01695587518089018952918252818b019081526009808552878c5291517f797e2d288100431f5f858c729cd7a996a2a7b4c4d5446876aea0e888879efbfd80548716918516919091179055517f797e2d288100431f5f858c729cd7a996a2a7b4c4d5446876aea0e888879efbfe5586518088018852858152681043561a8829300000818c01818152600a8652888d5291517f5d3a18624b866036268575c8d4a80a967939d2f98f317e52ad9d83f3fd01cf208054881691861691909117905590517f5d3a18624b866036268575c8d4a80a967939d2f98f317e52ad9d83f3fd01cf215587518089018952868152808c01918252600b8552878c52517fc0a7af8d24ca3b2822488d5a95e9c0d4d417000f20b52d9e8088d689094b58b580548716918516919091179055517fc0a7af8d24ca3b2822488d5a95e9c0d4d417000f20b52d9e8088d689094b58b655865180880188528581526812f939c99edab80000818c01818152600c8652888d5291517f511ac29f92e205e0d16cf1741c68d1f190f7b76570502b940c90a9f73a430abe8054881691861691909117905590517f511ac29f92e205e0d16cf1741c68d1f190f7b76570502b940c90a9f73a430abf5587518089018952868152808c01918252600d8552878c52517f1daa70a5e2042ce6b5e5c2a631438a85c8d5b368fab842c7f159c1ca28891e8b80548716918516919091179055517f1daa70a5e2042ce6b5e5c2a631438a85c8d5b368fab842c7f159c1ca28891e8c55865180880188528581526815af1d78b58c400000818c01818152600e8652888d5291517fa12e09df5c966bbe741292318caf6ba9a0ea92bd818fc17dc5b209561fcab2448054881691861691909117905590517fa12e09df5c966bbe741292318caf6ba9a0ea92bd818fc17dc5b209561fcab2455587518089018952868152808c01918252600f8552878c52517f1f0b3139ea9bd9b6849ca44242d280edc187cc644bff27185e2ebf579b5fb1b680548716918516919091179055517f1f0b3139ea9bd9b6849ca44242d280edc187cc644bff27185e2ebf579b5fb1b755865180880188528581526818650127cc3dc80000818c0181815260108652888d5291517fabbe889fb56d47a303749582195f0e5563cf143c45b463593db7a7a32c89da638054881691861691909117905590517fabbe889fb56d47a303749582195f0e5563cf143c45b463593db7a7a32c89da645587518089018952868152808c0191825260118552878c52517fd9bd2b0ffe451d811807bc41cc61e42c60f5fed09725f41ad5d13c018f2aed7c80548716918516919091179055517fd9bd2b0ffe451d811807bc41cc61e42c60f5fed09725f41ad5d13c018f2aed7d5586518088018852858152681b1ae4d6e2ef500000818c0181815260128652888d5291517f7bd5afea3f03bfa772a537ce124088119fa96205d291db17f5a8484973de93028054881691861691909117905590517f7bd5afea3f03bfa772a537ce124088119fa96205d291db17f5a8484973de93035587518089018952958652858b0190815260138452958a5293517f1fd5eaa72de83680fe3a2f2fdb6ab3d6d4ae9972bd821c832a15a14d64c2c1fd805490941691161790915591517f1fd5eaa72de83680fe3a2f2fdb6ab3d6d4ae9972bd821c832a15a14d64c2c1fe55825160608082018552606480835260fa838a0181905269021e19e0c9bab24000009387018490529089556021805463ffffffff1990811690921790556022929092558451808201865260c88082526101f4828b0181905269054b40b1f852bda0000092880183905260239190915560248054851690911790556025558451808201865261012c8082526103e8828b01819052690a968163f0a57b40000092880183905260269190915560278054851682179055602891909155855180830187526101908082526109c4828c0181905269152d02c7e14af6800000928901839052602991909155602a805486169091179055602b5585518083018752610258808252611388828c01819052692a5a058fc295ed000000928901839052602c91909155602d805486169091179055602e5585518083018752610320808252611d4c828c018190526969e10de76676d0800000928901839052602f91909155603080548616909117905560315585519182018652808252612710828a0181905269d3c21bcecceda100000092870183905260329190915560338054909316179091556034556369b015d09093556043939093558051808201909152908152680547572626f4c6f6f760bc1b8184015273c8d2701882a9a629e9a9332950fef78ee4ffd9a990915260359091527f2c923c2860e93b02953d9ac13149855dd4640ca32269e5b94850700e1a7f4e627f2c923c2860e93b02953d9ac13149855dd4640ca32269e5b94850700e1a7f4e6362000c8a838262000eb5565b5080546001600160a01b0319908116825560028201805460ff1916600117905560438054600384018190555f908152603960205260408120805490931673c8d2701882a9a629e9a9332950fef78ee4ffd9a91790925580549162000cee8362000f7d565b919050555073c8d2701882a9a629e9a9332950fef78ee4ffd9a960378360405162000d1a919062000fa2565b90815260200160405180910390205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550600160388360405162000d5f919062000fa2565b908152604051908190036020019020805491151560ff19909216919091179055603f8054905f62000d908362000f7d565b919050555050505062000fd0565b826014810192821562000dd5579160200282015b8281111562000dd5578251829061ffff1690559160200191906001019062000db2565b5062000de392915062000de7565b5090565b5b8082111562000de3575f815560010162000de8565b5f6020828403121562000e0e575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168062000e3e57607f821691505b60208210810362000e5d57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000eb0575f81815260208120601f850160051c8101602086101562000e8b5750805b601f850160051c820191505b8181101562000eac5782815560010162000e97565b5050505b505050565b81516001600160401b0381111562000ed15762000ed162000e15565b62000ee98162000ee2845462000e29565b8462000e63565b602080601f83116001811462000f1f575f841562000f075750858301515b5f19600386901b1c1916600185901b17855562000eac565b5f85815260208120601f198616915b8281101562000f4f5788860151825594840194600190910190840162000f2e565b508582101562000f6d57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f6001820162000f9b57634e487b7160e01b5f52601160045260245ffd5b5060010190565b5f82515f5b8181101562000fc3576020818601810151858301520162000fa7565b505f920191825250919050565b60805160a05160c05160e051614de06200105f5f395f818161079801528181612dad015281816136160152818161364601526137c901525f8181612cfd01528181612edd01528181612fcd01526136e501525f8181612d3101528181612ea301528181613046015281816135ee01526136ab01525f8181611ab9015281816135cc01526138180152614de05ff3fe608060405234801561000f575f80fd5b5060043610610281575f3560e01c80639d38312611610156578063d5a72a42116100ca578063dfe6b5d611610084578063dfe6b5d6146108fc578063e2e6c7d714610920578063f309e3f91461093f578063f7acff781461096d578063f825f14314610988578063f8eeed62146109bc575f80fd5b8063d5a72a4214610793578063d5cc83ab146107ba578063d75aea9d146107d9578063d7fc72841461080a578063dae3e9b4146108d6578063df927bbe146108e9575f80fd5b8063aecaa6341161011b578063aecaa6341461060e578063b162061614610636578063b169520114610649578063c09d0e0f14610671578063cb1dc5191461071b578063cee132f81461074e575f80fd5b80639d383126146105ab578063a1e6a255146105ca578063a7feae45146105d3578063a87430ba146105db578063acbca7e214610605575f80fd5b80633b032005116101f8578063715018a6116101b2578063715018a6146104db578063733b0eb9146104e357806381dbe8b11461051357806386d6b6be1461051c578063873e31fa146105465780638da5cb5b14610586575f80fd5b80633b032005146104535780633c7afca5146104665780633ffbd47f1461046f5780636386c1c714610482578063654cfdff146104a85780636a9564c7146104bb575f80fd5b806315ad7b9c1161024957806315ad7b9c1461035f57806315ff8dd9146103a45780632e5a15ca146103fb5780632fc3140e1461041e57806332bc298c1461042757806337ff924a14610431575f80fd5b80630930df6a146102855780630962ef79146102de5780630b11e312146102f357806311bdd73d1461030657806313fcaf5414610326575b5f80fd5b6102986102933660046145c9565b6109c5565b6040805198895260208901979097529587019490945260ff909216606086015215156080850152151560a084015260c083015260e0820152610100015b60405180910390f35b6102f16102ec3660046145f3565b610bde565b005b6102f16103013660046145f3565b610df6565b61031961031436600461460a565b6113ec565b6040516102d59190614625565b61035161033436600461460a565b6001600160a01b03165f908152603560205260409020600b015490565b6040519081526020016102d5565b61038f61036d366004614671565b603d60209081525f928352604080842090915290825290205463ffffffff1681565b60405163ffffffff90911681526020016102d5565b6103de6103b23660046145f3565b5f818152603a6020908152604080832054603b835281842054603c90935292205460ff90921693909250565b6040805193151584526020840192909252908201526060016102d5565b61040e610409366004614741565b61146a565b60405190151581526020016102d5565b61035160445481565b6103516201518081565b61040e61043f3660046145f3565b603a6020525f908152604090205460ff1681565b61040e610461366004614790565b61154f565b610351603f5481565b6102f161047d3660046147ca565b61159b565b61049561049036600461460a565b6118cf565b6040516102d59796959493929190614877565b6102f16104b63660046148c3565b6119ca565b6104ce6104c936600461460a565b611c86565b6040516102d591906148e4565b6102f1611ced565b6104eb611d61565b604080519586526020860194909452928401919091526060830152608082015260a0016102d5565b61035160455481565b61035161052a366004614671565b603e60209081525f928352604080842090915290825290205481565b61055961055436600461460a565b611de7565b604080519687526020870195909552938501929092526060840152608083015260a082015260c0016102d5565b6001546001600160a01b03165b6040516001600160a01b0390911681526020016102d5565b6105b3611e49565b6040805192151583526020830191909152016102d5565b61035160435481565b6102f1611f5c565b6105ee6105e936600461460a565b612163565b6040516102d59b9a9998979695949392919061490c565b61035160405481565b61062161061c366004614978565b61224e565b604080519283526020830191909152016102d5565b6106216106443660046145f3565b6122d4565b6105936106573660046145f3565b60396020525f90815260409020546001600160a01b031681565b6106df61067f36600461460a565b6001600160a01b03165f90815260356020908152604080832060369092529091206005808301546006909301549101549192909163ffffffff808216926401000000008304821692600160401b810490921691600160601b900460ff1690565b60408051968752602087019590955263ffffffff93841694860194909452908216606085015216608083015260ff1660a082015260c0016102d5565b61072e610729366004614978565b6122f5565b6040805193845263ffffffff9092166020840152908201526060016102d5565b61077a61075c366004614978565b601f6020525f90815260409020805460019091015460ff9091169082565b6040805160ff90931683526020830191909152016102d5565b61040e7f000000000000000000000000000000000000000000000000000000000000000081565b6103516107c83660046145f3565b603b6020525f908152604090205481565b6107ec6107e736600461460a565b612396565b60408051938452602084019290925260ff16908201526060016102d5565b61087d61081836600461460a565b60366020525f908152604090208054600182015460028301546003840154600485015460058601546006909601549495939492939192909163ffffffff808216926401000000008304821692600160401b810490921691600160601b900460ff16908a565b604080519a8b5260208b0199909952978901969096526060880194909452608087019290925263ffffffff90811660a087015290811660c08601521660e084015260ff16610100830152610120820152610140016102d5565b6102f16108e43660046148c3565b6124f0565b61072e6108f73660046145f3565b61285e565b603f54604054600254604080519384526020840192909252908201526060016102d5565b61035161092e3660046145f3565b603c6020525f908152604090205481565b61040e61094d366004614790565b805160208183018101805160388252928201919093012091525460ff1681565b61059373c8d2701882a9a629e9a9332950fef78ee4ffd9a981565b610593610996366004614790565b80516020818301810180516037825292820191909301209152546001600160a01b031681565b61035160025481565b6001600160a01b0382165f908152603560205260408120600b8101548291829182918291829182918291908a10610a335760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b60448201526064015b60405180910390fd5b5f81600b018b81548110610a4957610a49614991565b5f918252602082206005919091020160048181015491935060039160ff16908110610a7657610a76614991565b600202015490505f610a8b62015180836149b9565b8360010154610a9a91906149d0565b6004808501549192505f916127109160039160ff16908110610abe57610abe614991565b6002020160010154855f0154610ad491906149b9565b610ade91906149e3565b90505f824211610aee5742610af0565b825b90505f85600101548211610b04575f610b13565b6001860154610b139083614a02565b90505f808211610b23575f610b84565b62015180610b33876127106149b9565b610b3d91906149b9565b600480890154849160039160ff16908110610b5a57610b5a614991565b6002020160010154895f0154610b7091906149b9565b610b7a91906149b9565b610b8491906149e3565b9050865f0154876001015486896004015f9054906101000a900460ff168a60040160019054906101000a900460ff168942101589879f509f509f509f509f509f509f509f5050505050505050509295985092959890939650565b610be661288d565b6002541580610bf6575060025442105b15610c1457604051638dda39df60e01b815260040160405180910390fd5b335f9081526035602090815260408083206036909252909120600282015460ff16610c525760405163aba4733960e01b815260040160405180910390fd5b610c5b336128b5565b50600181015481545f610c6e82846149d0565b9050805f03610c9057604051630fec21fd60e21b815260040160405180910390fd5b855f03610c9b578095505b80861115610cbc57604051631e9acf1760e31b815260040160405180910390fd5b670de0b6b3a7640000861015610ce55760405163860b82a960e01b815260040160405180910390fd5b858315801590610cf457505f81115b15610d3357838110610d1757610d0a8482614a02565b5f60018701559050610d33565b80856001015f828254610d2a9190614a02565b909155505f9150505b5f83118015610d4157505f81115b15610d7057828110610d55575f8555610d6d565b80855f015f828254610d679190614a02565b90915550505b505f5b610d7a8733612ce3565b86866009015f828254610d8d91906149d0565b925050819055508660425f828254610da591906149d0565b90915550506040805188815242602082015233917f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a910160405180910390a2505050505050610df360015f55565b50565b610dfe61288d565b6002541580610e0e575060025442105b15610e2c57604051638dda39df60e01b815260040160405180910390fd5b5f8111610e7b5760405162461bcd60e51b815260206004820152601d60248201527f4c656e677468206d7573742062652067726561746572207468616e20300000006044820152606401610a2a565b5f6201518060025442610e8e9190614a02565b610e9891906149e3565b9050805f03610ea757506113e3565b6044541580610ec657506044545f908152603a602052604090205460ff165b15610f0e576044545b81811015610f0c575f818152603a602052604090205460ff16610efa5760448190555f604555610f0c565b80610f0481614a15565b915050610ecf565b505b6044545f908152603a602052604090205460ff1615610f2d57506113e3565b5f806045545f14610f4057604554610f43565b60015b6044549091505f62015180610f598360016149d0565b610f6391906149b9565b600254610f7091906149d0565b905042811115610f7d5750425b825b60435481108015610f8f57508685105b15611323575f818152603960209081526040808320546001600160a01b03168084526035835281842060369093529220600282015460ff16610fe05787610fd581614a15565b985050505050611311565b84816006015410610ff55787610fd581614a15565b5f805b600b8401548110156112505783600b01818154811061101957611019614991565b905f5260205f20906005020160040160019054906101000a900460ff1661123e575f600385600b01838154811061105257611052614991565b5f9182526020909120600460059092020181015460ff1690811061107857611078614991565b600202015490505f61108d62015180836149b9565b86600b0184815481106110a2576110a2614991565b905f5260205f209060050201600101546110bc91906149d0565b90505f86600b0184815481106110d4576110d4614991565b905f5260205f2090600502016002015490508181101561123a575f828b106110fc57826110fe565b8a5b9050818111611110575050505061123e565b5f61111b8383614a02565b90508015611237575f62015180611134876127106149b9565b61113e91906149b9565b8260038c600b018a8154811061115657611156614991565b5f9182526020909120600460059092020181015460ff1690811061117c5761117c614991565b60020201600101548c600b018a8154811061119957611199614991565b905f5260205f2090600502015f01546111b291906149b9565b6111bc91906149b9565b6111c691906149e3565b90506111d281896149d0565b9750828a600b0188815481106111ea576111ea614991565b905f5260205f20906005020160020181905550808a600b01888154811061121357611213614991565b905f5260205f2090600502016003015f82825461123091906149d0565b9091555050505b50505b5050505b8061124881614a15565b915050610ff8565b50801561128e5761126184826130bb565b61126b8482613250565b5f878152603c6020526040812080548392906112889084906149d0565b90915550505b600682018690558861129f81614a15565b5f898152603b602052604081208054929c509192506112bd83614a15565b9091555050604080518281525f6020820152428183015290516001600160a01b038616917fbc3e667b85309bf5b995e6447d14031fa213f47d4da0f1c041c733eb1e18914b919081900360600190a2505050505b8061131b81614a15565b915050610f7f565b5061132e84846149d0565b6045819055604354116113b3575f828152603a60209081526040808320805460ff19166001179055603c909152902054156113ae575f828152603c60205260408120546127109061138290610258906149b9565b61138c91906149e3565b90506113ac8173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b505b5f6045555b60405182907f23f8a1a4055fe6f4bd070e929249963966b1e8b4fd06d403d132ee8535a92aa6905f90a250505050505b610df360015f55565b6113f4614596565b5f5b60148160ff161015611464576001600160a01b0383165f908152603d6020908152604080832060ff851680855292529091205463ffffffff169083906014811061144257611442614991565b63ffffffff90921660209290920201528061145c81614a2d565b9150506113f6565b50919050565b5f8060378460405161147c9190614a4b565b908152604051908190036020019020546001600160a01b0316905073c8d2701882a9a629e9a9332950fef78ee4ffd9a81981016114bd576001915050611549565b6001600160a01b0381166114d4575f915050611549565b826001600160a01b0316816001600160a01b0316036114f6575f915050611549565b6001600160a01b0381165f9081526035602052604090206002015460ff16611521575f915050611549565b68015af1d78b58c4000061153482613433565b1015611543575f915050611549565b60019150505b92915050565b5f6115598261346f565b61156457505f919050565b6038826040516115749190614a4b565b9081526040519081900360200190205460ff161561159357505f919050565b506001919050565b6115a361288d565b60025415806115b3575060025442105b156115d157604051638dda39df60e01b815260040160405180910390fd5b335f9081526035602052604090206002015460ff161561160457604051630ea075bf60e21b815260040160405180910390fd5b61160d8261346f565b61162a57604051630a1de65160e31b815260040160405180910390fd5b60388260405161163a9190614a4b565b9081526040519081900360200190205460ff161561166b57604051636bc324ad60e01b815260040160405180910390fd5b5f60378260405161167c9190614a4b565b908152604051908190036020019020546001600160a01b0316905073c8d2701882a9a629e9a9332950fef78ee4ffd9a9811461176f576001600160a01b0381166116d957604051633665e87960e11b815260040160405180910390fd5b336001600160a01b03821603611702576040516368d7fd4960e11b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090206002015460ff1661173d57604051636dc69e6560e11b815260040160405180910390fd5b68015af1d78b58c4000061175082613433565b101561176f57604051636dc69e6560e11b815260040160405180910390fd5b335f9081526035602052604090206001810161178b8582614add565b5080546001600160a01b0383166001600160a01b031991821617825560028201805460ff1916600117905560438054600384018190555f908152603960205260408120805490931633179092558054916117e483614a15565b9190505550336037856040516117fa9190614a4b565b90815260200160405180910390205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550600160388560405161183d9190614a4b565b908152604051908190036020019020805491151560ff19909216919091179055603f8054905f61186c83614a15565b9190505550816001600160a01b0316336001600160a01b03167f78d6e8f849b1071e5deda6bc7f2c2a8a6e2d092683aec45e1b7f4fbc95860c0b8686426040516118b893929190614b99565b60405180910390a350506118cb60015f55565b5050565b6001600160a01b038082165f90815260356020526040812080546002820154600483015460088401546009850154600a86015460018701805460609a8a998a998a998a998a9993989697929094169560ff90911694909190879061193290614a66565b80601f016020809104026020016040519081016040528092919081815260200182805461195e90614a66565b80156119a95780601f10611980576101008083540402835291602001916119a9565b820191905f5260205f20905b81548152906001019060200180831161198c57829003601f168201915b50505050509650975097509750975097509750975050919395979092949650565b6119d261288d565b60025415806119e2575060025442105b15611a0057604051638dda39df60e01b815260040160405180910390fd5b670de0b6b3a7640000821015611a295760405163860b82a960e01b815260040160405180910390fd5b60048160ff1610611a4d576040516321f2425960e01b815260040160405180910390fd5b335f908152603560205260409020600281015460ff16611a8057604051633a075e6360e01b815260040160405180910390fd5b600b81015461019011611aa65760405163291b490560e21b815260040160405180910390fd5b600881015415611ae16001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308761357a565b5f611aeb856135b0565b90505f612710611afd610258846149b9565b611b0791906149e3565b9050611b278173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b6040805160c0810182528381524260208083018281529383019182525f6060840181815260ff808c166080870190815260a08701848152600b8d018054600181810183559187529686209851600590970290980195865597519685019690965593516002840155516003830155925160049091018054945115156101000261ffff19909516919092161792909217909155600885018054849290611bcc9084906149d0565b9250508190555081846004015f828254611be691906149d0565b925050819055508160415f828254611bfe91906149d0565b90915550611c119050338360015f61384c565b8215611c3557611c2033613afb565b60408054905f611c2f83614a15565b91905055505b6040805183815260ff871660208201524281830152905133917f658ea7d02788018eff5425fa04c446062f80a2026f9899163e3a221cc30d0936919081900360600190a2505050506118cb60015f55565b611c8e614596565b5f5b60148160ff161015611464576001600160a01b0383165f908152603e6020908152604080832060ff851680855292529091205490839060148110611cd657611cd6614991565b602002015280611ce581614a2d565b915050611c90565b6001546001600160a01b03163314611d18576040516330cd747160e01b815260040160405180910390fd5b6001546040516001600160a01b03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c64820905f90a2600180546001600160a01b0319169055565b5f805f805f6201518060025442611d789190614a02565b611d8291906149e3565b9450604454935060455492505f60435411611d9d575f611dac565b6001604354611dac9190614a02565b91505f8315611dbb5783611dbe565b60015b90508060435411611dcf575f611ddd565b80604354611ddd9190614a02565b9150509091929394565b6001600160a01b0381165f9081526036602052604081208190819081908190819081611e1289613c81565b8254909150611e2181836149d0565b600184015484546002860154600490960154929d949c50909a50985092965091945092505050565b5f806002545f1480611e5c575060025442105b15611e6957505f91829150565b5f6201518060025442611e7c9190614a02565b611e8691906149e3565b9050805f03611e9957505f928392509050565b604454604554811580611eb957505f828152603a602052604090205460ff165b15611efc57815b83811015611efa575f818152603a602052604090205460ff16611ee8578092505f9150611efa565b80611ef281614a15565b915050611ec0565b505b5f828152603a602052604090205460ff1615611f1e57505f9485945092505050565b5f8115611f2b5781611f2e565b60015b90508060435411611f3f575f611f4d565b80604354611f4d9190614a02565b94505f85119550505050509091565b611f6461288d565b6002541580611f74575060025442105b15611f9257604051638dda39df60e01b815260040160405180910390fd5b335f9081526035602052604090206002015460ff16611fc45760405163aba4733960e01b815260040160405180910390fd5b335f90815260366020526040902060068101544211611fe35750612158565b5f6201518060025442611ff69190614a02565b61200091906149e3565b90505f82600601545f14612033576201518060025484600601546120249190614a02565b61202e91906149e3565b612035565b5f5b90505f815b8381116120fc575f620151806120518360016149d0565b61205b91906149b9565b60025461206891906149d0565b9050428111156120755750425b8086600601541061208657506120ea565b5f6120913383613e4b565b905061209d81856149d0565b60068801839055604080518381525f60208201524281830152905191955033917fbc3e667b85309bf5b995e6447d14031fa213f47d4da0f1c041c733eb1e18914b9181900360600190a250505b806120f481614a15565b91505061203a565b5080156121535761210d33826130bb565b6121173382613250565b5f612710612127610258846149b9565b61213191906149e3565b90506121518173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b505b505050505b61216160015f55565b565b60356020525f9081526040902080546001820180546001600160a01b03909216929161218e90614a66565b80601f01602080910402602001604051908101604052809291908181526020018280546121ba90614a66565b80156122055780601f106121dc57610100808354040283529160200191612205565b820191905f5260205f20905b8154815290600101906020018083116121e857829003601f168201915b50505060028401546003850154600486015460058701546006880154600789015460088a015460098b0154600a909b0154999a60ff90971699959850939650919490939192918b565b5f8060048360ff16106122925760405162461bcd60e51b815260206004820152600c60248201526b24b73b30b634b210383630b760a11b6044820152606401610a2a565b60038360ff16600481106122a8576122a8614991565b6002020154600360ff8516600481106122c3576122c3614991565b600202016001015491509150915091565b600381600481106122e3575f80fd5b60020201805460019091015490915082565b5f805f60078460ff161061233a5760405162461bcd60e51b815260206004820152600c60248201526b496e76616c69642072616e6b60a01b6044820152606401610a2a565b5f60208560ff166007811061235157612351614991565b60408051606081018252600392909202929092018054808352600182015463ffffffff1660208401819052600290920154929093018290529197919650945092505050565b6001600160a01b0381165f9081526035602090815260408083206036909252822082918291600b8201835b81548110156124d5578181815481106123dc576123dc614991565b905f5260205f20906005020160040160019054906101000a900460ff166124c3575f62015180600384848154811061241657612416614991565b5f9182526020909120600460059092020181015460ff1690811061243c5761243c614991565b600202015461244b91906149b9565b83838154811061245d5761245d614991565b905f5260205f2090600502016001015461247791906149d0565b905080421061248657506124c3565b82828154811061249857612498614991565b905f5260205f2090600502015f0154886124b291906149d0565b9750866124be81614a15565b975050505b806124cd81614a15565b9150506123c1565b50506005015460ff600160601b909104169150509193909250565b6124f861288d565b6002541580612508575060025442105b1561252657604051638dda39df60e01b815260040160405180910390fd5b60048160ff161061254a576040516321f2425960e01b815260040160405180910390fd5b335f9081526035602090815260408083206036909252909120600282015460ff166125885760405163aba4733960e01b815260040160405180910390fd5b600b820154610190116125ae5760405163291b490560e21b815260040160405180910390fd5b6125b7336128b5565b50600181015481545f6125ca82846149d0565b9050805f036125ec57604051630fec21fd60e21b815260040160405180910390fd5b865f036125f7578096505b8087111561261857604051631e9acf1760e31b815260040160405180910390fd5b670de0b6b3a76400008710156126415760405163860b82a960e01b815260040160405180910390fd5b86831580159061265057505f81115b1561268f57838110612673576126668482614a02565b5f6001870155905061268f565b80856001015f8282546126869190614a02565b909155505f9150505b5f8311801561269d57505f81115b156126cc578281106126b1575f85556126c9565b80855f015f8282546126c39190614a02565b90915550505b505f5b5f6127106126dc6102588b6149b9565b6126e691906149e3565b90506127068173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b86600b016040518060c001604052808b81526020014281526020014281526020015f81526020018a60ff1681526020015f1515815250908060018154018082558091505060019003905f5260205f2090600502015f909190919091505f820151815f01556020820151816001015560408201518160020155606082015181600301556080820151816004015f6101000a81548160ff021916908360ff16021790555060a08201518160040160016101000a81548160ff02191690831515021790555050508887600a015f8282546127dd91906149d0565b9250508190555088876004015f8282546127f791906149d0565b9091555061280a9050338a60018061384c565b604080518a815260ff8a1660208201524281830152905133917f2f43906271c2313ff3872901245076d7f7f3bda8288909521826dd32e3b2540d919081900360600190a2505050505050506118cb60015f55565b6020816007811061286d575f80fd5b600302018054600182015460029092015490925063ffffffff9091169083565b60025f54036128af57604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b6001600160a01b0381165f908152603560209081526040808320603690925282208280805b600b850154811015612c715784600b0181815481106128fb576128fb614991565b905f5260205f20906005020160040160019054906101000a900460ff16612c5f575f62015180600387600b01848154811061293857612938614991565b5f9182526020909120600460059092020181015460ff1690811061295e5761295e614991565b600202015461296d91906149b9565b86600b01838154811061298257612982614991565b905f5260205f2090600502016001015461299c91906149d0565b9050804210612c5d575f612710600388600b0185815481106129c0576129c0614991565b5f9182526020909120600460059092020181015460ff169081106129e6576129e6614991565b600202016001015488600b018581548110612a0357612a03614991565b905f5260205f2090600502015f0154612a1c91906149b9565b612a2691906149e3565b87600b018481548110612a3b57612a3b614991565b905f5260205f2090600502015f0154612a5491906149d0565b90505f612710600389600b018681548110612a7157612a71614991565b5f9182526020909120600460059092020181015460ff16908110612a9757612a97614991565b600202016001015489600b018681548110612ab457612ab4614991565b905f5260205f2090600502015f0154612acd91906149b9565b612ad791906149e3565b905087600b018481548110612aee57612aee614991565b905f5260205f20906005020160030154811115612b425787600b018481548110612b1a57612b1a614991565b905f5260205f2090600502016003015481612b359190614a02565b612b3f90866149d0565b94505b600188600b018581548110612b5957612b59614991565b905f5260205f20906005020160040160016101000a81548160ff02191690831515021790555087600b018481548110612b9457612b94614991565b905f5260205f2090600502015f0154886004015410612c1b5787600b018481548110612bc257612bc2614991565b905f5260205f2090600502015f0154886004015f828254612be39190614a02565b9091555050600b8801805485908110612bfe57612bfe614991565b905f5260205f2090600502015f015486612c1891906149d0565b95505b80876003015f828254612c2e91906149d0565b9250508190555081876001015f828254612c4891906149d0565b90915550612c589050828a6149d0565b985050505b505b80612c6981614a15565b9150506128da565b508115612c8457612c8486835f8061384c565b8015612cda57612c9486826130bb565b612c9e8682613250565b5f612710612cae610258846149b9565b612cb891906149e3565b9050612cd88173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b505b50505050919050565b815f03612cee575050565b60405163133f757160e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201525f90819081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906399fbab889060240161018060405180830381865afa158015612d77573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d9b9190614c12565b9b509b5050509950505050505050505f7f0000000000000000000000000000000000000000000000000000000000000000612dd65781612dd8565b825b905085816001600160801b03161015612fc1575f612dff6001600160801b03831688614a02565b90505f670de0b6b3a7640000612e1e68012b27d72e93fc2abc846149b9565b612e2891906149e3565b9050806001600160801b0381165f03612e3f575060015b866001600160801b0316816001600160801b03161115612ea15760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e74204c50206c6971756964697479000000000000006044820152606401610a2a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630c49ccbe6040518060a001604052807f00000000000000000000000000000000000000000000000000000000000000008152602001846001600160801b031681526020015f81526020015f81526020014261012c612f2a91906149d0565b9052604080516001600160e01b031960e085901b1681528251600482015260208301516001600160801b0316602482015290820151604482015260608201516064820152608090910151608482015260a40160408051808303815f875af1158015612f97573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fbb9190614ceb565b50505050505b604080516080810182527f000000000000000000000000000000000000000000000000000000000000000081526001600160a01b03878116602083019081526001600160801b0383850181815260608501828152955163fc6f786560e01b815294516004860152915183166024850152905181166044840152925190921660648201527f00000000000000000000000000000000000000000000000000000000000000009091169063fc6f78659060840160408051808303815f875af115801561308d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130b19190614ceb565b5050505050505050565b6001600160a01b038083165f90815260356020526040812054909116905b601460ff82161080156130f457506001600160a01b03821615155b1561324a576001600160a01b0382165f90815260366020526040902061311a838361422a565b1561321a575f612710600b8460ff166014811061313957613139614991565b015461314590876149b9565b61314f91906149e3565b905080825f015f82825461316391906149d0565b9250508190555080826002015f82825461317d91906149d0565b90915550506001600160a01b0384165f908152603e6020908152604080832060ff87168452909152812080548392906131b79084906149d0565b90915550506001600160a01b038087169085167fb95cd440a52937795da4af7f392ab0f953bea11ef59d553bf04ea0c63a9e2c9b6131f6866001614d0d565b6040805160ff909216825260208201869052429082015260600160405180910390a3505b506001600160a01b039182165f90815260356020526040902054909116908061324281614a2d565b9150506130d9565b50505050565b6001600160a01b038083165f9081526035602052604081205490911690805b606460ff821610801561328a57506001600160a01b03831615155b1561342c576001600160a01b0383165f90815260356020908152604080832060368352908320600581015491939092600160601b90920460ff169182600781106132d6576132d6614991565b6003020160010154600584015463ffffffff91821691161080159061331c575060208260ff166007811061330c5761330c614991565b6003020160020154846005015410155b1561333f5760208260ff166007811061333757613337614991565b600302015490505b858111156133f7575f6133528783614a02565b90505f612710613362838c6149b9565b61336c91906149e3565b905080855f015f82825461338091906149d0565b9250508190555080856004015f82825461339a91906149d0565b90915550506040805160ff8616815260208101839052428183015290516001600160a01b038d811692908c16917f8d2091022f06ad0b5b021c10b844e2555df2df0029a672b3e6ac2c85957ee81d9181900360600190a382975050505b6103e88610613409575050505061342c565b505090546001600160a01b0316935081905061342481614a2d565b91505061326f565b5050505050565b6001600160a01b0381165f908152603560205260408120600b8101546101901115613462578060040154613468565b80600801545b9392505050565b5f80829050600381511080613485575060148151115b1561349257505f92915050565b5f5b8151811015613570575f8282815181106134b0576134b0614991565b01602001516001600160f81b0319169050600360fc1b81108015906134e35750603960f81b6001600160f81b0319821611155b1580156135195750604160f81b6001600160f81b03198216108015906135175750602d60f91b6001600160f81b0319821611155b155b801561354e5750606160f81b6001600160f81b031982161080159061354c5750603d60f91b6001600160f81b0319821611155b155b1561355d57505f949350505050565b508061356881614a15565b915050613494565b5060019392505050565b6135888484848460016142bc565b61324a57604051635274afe760e01b81526001600160a01b0385166004820152602401610a2a565b5f815f036135bf57505f919050565b6136136001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000084614329565b5f7f000000000000000000000000000000000000000000000000000000000000000061363f575f613641565b825b90505f7f000000000000000000000000000000000000000000000000000000000000000061366f5783613671565b5f5b90505f60646136818460636149b9565b61368b91906149e3565b90505f606461369b8460636149b9565b6136a591906149e3565b90505f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663219f5d176040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000081526020018981526020018881526020018781526020018681526020014261012c61372f91906149d0565b9052604080516001600160e01b031960e085901b1681528251600482015260208301516024820152908201516044820152606082015160648201526080820151608482015260a09091015160a482015260c4016060604051808303815f875af115801561379e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137c29190614d26565b92509250507f00000000000000000000000000000000000000000000000000000000000000006137f257806137f4565b815b965086881115613841575f613809888a614a02565b905061383f6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633836143a3565b505b505050505050919050565b6001600160a01b038085165f90815260356020526040902054168015613998576001600160a01b038082165f9081526036602090815260408083209389168352603590915290206004015484156139105768015af1d78b58c4000081101580156138c7575068015af1d78b58c400006138c58783614a02565b105b1561390b57600582018054600160401b900463ffffffff169060086138eb83614d58565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b613995565b68015af1d78b58c400008110801561393a575068015af1d78b58c4000061393787836149d0565b10155b15613995576005820154600160401b900463ffffffff161561399557600582018054600160401b900463ffffffff1690600861397583614d7a565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b50505b5f5b6001600160a01b038216158015906139b55750606460ff8216105b15613af3578315613a54576001600160a01b0382165f90815260356020526040812060050180548792906139ea9084906149d0565b90915550508215613a2a576001600160a01b0382165f9081526035602052604081206007018054879290613a1f9084906149d0565b90915550613abb9050565b6001600160a01b0382165f9081526035602052604081206006018054879290613a1f9084906149d0565b6001600160a01b0382165f908152603560205260409020600501548511613a9f576001600160a01b0382165f9081526035602052604081206005018054879290613a1f908490614a02565b6001600160a01b0382165f908152603560205260408120600501555b613ac4826143b0565b6001600160a01b039182165f908152603560205260409020549091169080613aeb81614a2d565b91505061399a565b505050505050565b6001600160a01b038082165f90815260356020526040902054168015613b71576001600160a01b0381165f9081526036602052604090206005018054640100000000900463ffffffff16906004613b5183614d58565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b5f5b6001600160a01b03821615801590613b8e5750606460ff8216105b15613c7c576001600160a01b0382165f908152603660205260408120600501805463ffffffff1691613bbf83614d58565b91906101000a81548163ffffffff021916908363ffffffff16021790555050601460ff168160ff161015613c44576001600160a01b0382165f908152603d6020908152604080832060ff851684529091528120805463ffffffff1691613c2483614d58565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b613c4d826143b0565b6001600160a01b039182165f908152603560205260409020549091169080613c7481614a2d565b915050613b73565b505050565b6001600160a01b0381165f908152603560209081526040808320603690925282206001810154925b600b830154811015613e435782600b018181548110613cca57613cca614991565b905f5260205f20906005020160040160019054906101000a900460ff16613e31575f62015180600385600b018481548110613d0757613d07614991565b5f9182526020909120600460059092020181015460ff16908110613d2d57613d2d614991565b6002020154613d3c91906149b9565b84600b018381548110613d5157613d51614991565b905f5260205f20906005020160010154613d6b91906149d0565b9050804210613e2f57612710600385600b018481548110613d8e57613d8e614991565b5f9182526020909120600460059092020181015460ff16908110613db457613db4614991565b600202016001015485600b018481548110613dd157613dd1614991565b905f5260205f2090600502015f0154613dea91906149b9565b613df491906149e3565b84600b018381548110613e0957613e09614991565b905f5260205f2090600502015f0154613e2291906149d0565b613e2c90866149d0565b94505b505b80613e3b81614a15565b915050613ca9565b505050919050565b6001600160a01b0382165f908152603560205260408120815b600b8201548110156142225781600b018181548110613e8557613e85614991565b905f5260205f20906005020160040160019054906101000a900460ff16614210575f600383600b018381548110613ebe57613ebe614991565b5f9182526020909120600460059092020181015460ff16908110613ee457613ee4614991565b600202015490505f613ef962015180836149b9565b84600b018481548110613f0e57613f0e614991565b905f5260205f20906005020160010154613f2891906149d0565b90508084600b018481548110613f4057613f40614991565b905f5260205f2090600502016002015410156140eb575f818710613f645781613f66565b865b905084600b018481548110613f7d57613f7d614991565b905f5260205f209060050201600201548111613f9b57505050614210565b5f85600b018581548110613fb157613fb1614991565b905f5260205f2090600502016002015482613fcc9190614a02565b905080156140e8575f62015180613fe5866127106149b9565b613fef91906149b9565b82600389600b01898154811061400757614007614991565b5f9182526020909120600460059092020181015460ff1690811061402d5761402d614991565b600202016001015489600b01898154811061404a5761404a614991565b905f5260205f2090600502015f015461406391906149b9565b61406d91906149b9565b61407791906149e3565b905061408381896149d0565b97508287600b01878154811061409b5761409b614991565b905f5260205f209060050201600201819055508087600b0187815481106140c4576140c4614991565b905f5260205f2090600502016003015f8282546140e191906149d0565b9091555050505b50505b80861061420d575f612710600386600b01868154811061410d5761410d614991565b5f9182526020909120600460059092020181015460ff1690811061413357614133614991565b600202016001015486600b01868154811061415057614150614991565b905f5260205f2090600502015f015461416991906149b9565b61417391906149e3565b90508085600b01858154811061418b5761418b614991565b905f5260205f20906005020160030154101561420b575f85600b0185815481106141b7576141b7614991565b905f5260205f20906005020160030154826141d29190614a02565b90506141de81886149d0565b96508186600b0186815481106141f6576141f6614991565b905f5260205f20906005020160030181905550505b505b50505b8061421a81614a15565b915050613e64565b505092915050565b5f601460ff83161061423d57505f611549565b6001600160a01b0383165f90815260366020908152604080832060ff8681168552601f8452938290208251808401909352805490941680835260019094015492820192909252600582015491929091600160401b900463ffffffff16108015906142b3575080602001516142b086613433565b10155b95945050505050565b6040516323b872dd60e01b5f8181526001600160a01b038781166004528616602452604485905291602083606481808c5af1925060015f5114831661431857838315161561430c573d5f823e3d81fd5b5f883b113d1516831692505b604052505f60605295945050505050565b6143358383835f6144ea565b613c7c5761434683835f60016144ea565b61436e57604051635274afe760e01b81526001600160a01b0384166004820152602401610a2a565b61437b83838360016144ea565b613c7c57604051635274afe760e01b81526001600160a01b0384166004820152602401610a2a565b61437b838383600161454c565b6001600160a01b0381165f90815260356020908152604080832060369092529091206005810154600160601b900460ff1660065b60208160ff16600781106143fa576143fa614991565b6003020160010154600584015463ffffffff918216911610801590614440575060208160ff166007811061443057614430614991565b6003020160020154846005015410155b1561444d57809150614468565b60ff811615614468578061446081614d98565b9150506143e4565b50600582015460ff828116600160601b909204161461324a5760058201805460ff60601b1916600160601b60ff841690810291909117909155604080519182524260208301526001600160a01b038616917f741d7439fd15937c8d73d3e8fde5a7847d18b945292ab9831186ecab48980832910160405180910390a250505050565b60405163095ea7b360e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316614540578383151615614534573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b60405163a9059cbb60e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316614540578383151615614534573d5f823e3d81fd5b6040518061028001604052806014906020820280368337509192915050565b6001600160a01b0381168114610df3575f80fd5b5f80604083850312156145da575f80fd5b82356145e5816145b5565b946020939093013593505050565b5f60208284031215614603575f80fd5b5035919050565b5f6020828403121561461a575f80fd5b8135613468816145b5565b610280810181835f5b601481101561465357815163ffffffff1683526020928301929091019060010161462e565b50505092915050565b803560ff8116811461466c575f80fd5b919050565b5f8060408385031215614682575f80fd5b823561468d816145b5565b915061469b6020840161465c565b90509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126146c7575f80fd5b813567ffffffffffffffff808211156146e2576146e26146a4565b604051601f8301601f19908116603f0116810190828211818310171561470a5761470a6146a4565b81604052838152866020858801011115614722575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215614752575f80fd5b823567ffffffffffffffff811115614768575f80fd5b614774858286016146b8565b9250506020830135614785816145b5565b809150509250929050565b5f602082840312156147a0575f80fd5b813567ffffffffffffffff8111156147b6575f80fd5b6147c2848285016146b8565b949350505050565b5f80604083850312156147db575f80fd5b823567ffffffffffffffff808211156147f2575f80fd5b6147fe868387016146b8565b93506020850135915080821115614813575f80fd5b50614820858286016146b8565b9150509250929050565b5f5b8381101561484457818101518382015260200161482c565b50505f910152565b5f815180845261486381602086016020860161482a565b601f01601f19169290920160200192915050565b60e081525f61488960e083018a61484c565b6001600160a01b039890981660208301525094151560408601526060850193909352608084019190915260a083015260c090910152919050565b5f80604083850312156148d4575f80fd5b8235915061469b6020840161465c565b610280810181835f5b60148110156146535781518352602092830192909101906001016148ed565b6001600160a01b038c168152610160602082018190525f906149308382018e61484c565b9b1515604084015250506060810198909852608088019690965260a087019490945260c086019290925260e08501526101008401526101208301526101409091015292915050565b5f60208284031215614988575f80fd5b6134688261465c565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417611549576115496149a5565b80820180821115611549576115496149a5565b5f826149fd57634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115611549576115496149a5565b5f60018201614a2657614a266149a5565b5060010190565b5f60ff821660ff8103614a4257614a426149a5565b60010192915050565b5f8251614a5c81846020870161482a565b9190910192915050565b600181811c90821680614a7a57607f821691505b60208210810361146457634e487b7160e01b5f52602260045260245ffd5b601f821115613c7c575f81815260208120601f850160051c81016020861015614abe5750805b601f850160051c820191505b81811015613af357828155600101614aca565b815167ffffffffffffffff811115614af757614af76146a4565b614b0b81614b058454614a66565b84614a98565b602080601f831160018114614b3e575f8415614b275750858301515b5f19600386901b1c1916600185901b178555613af3565b5f85815260208120601f198616915b82811015614b6c57888601518255948401946001909101908401614b4d565b5085821015614b8957878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b606081525f614bab606083018661484c565b8281036020840152614bbd818661484c565b915050826040830152949350505050565b805161466c816145b5565b805162ffffff8116811461466c575f80fd5b8051600281900b811461466c575f80fd5b80516001600160801b038116811461466c575f80fd5b5f805f805f805f805f805f806101808d8f031215614c2e575f80fd5b8c516bffffffffffffffffffffffff81168114614c49575f80fd5b9b50614c5760208e01614bce565b9a50614c6560408e01614bce565b9950614c7360608e01614bce565b9850614c8160808e01614bd9565b9750614c8f60a08e01614beb565b9650614c9d60c08e01614beb565b9550614cab60e08e01614bfc565b94506101008d015193506101208d01519250614cca6101408e01614bfc565b9150614cd96101608e01614bfc565b90509295989b509295989b509295989b565b5f8060408385031215614cfc575f80fd5b505080516020909101519092909150565b60ff8181168382160190811115611549576115496149a5565b5f805f60608486031215614d38575f80fd5b614d4184614bfc565b925060208401519150604084015190509250925092565b5f63ffffffff808316818103614d7057614d706149a5565b6001019392505050565b5f63ffffffff821680614d8f57614d8f6149a5565b5f190192915050565b5f60ff821680614d8f57614d8f6149a556fea2646970667358221220cc9c802175e7e1372bf4f2db7e675048ea2d525b415abfa02094df35960facc464736f6c63430008140033000000000000000000000000000000000000000000000000000000000064c627

Deployed Bytecode

0x608060405234801561000f575f80fd5b5060043610610281575f3560e01c80639d38312611610156578063d5a72a42116100ca578063dfe6b5d611610084578063dfe6b5d6146108fc578063e2e6c7d714610920578063f309e3f91461093f578063f7acff781461096d578063f825f14314610988578063f8eeed62146109bc575f80fd5b8063d5a72a4214610793578063d5cc83ab146107ba578063d75aea9d146107d9578063d7fc72841461080a578063dae3e9b4146108d6578063df927bbe146108e9575f80fd5b8063aecaa6341161011b578063aecaa6341461060e578063b162061614610636578063b169520114610649578063c09d0e0f14610671578063cb1dc5191461071b578063cee132f81461074e575f80fd5b80639d383126146105ab578063a1e6a255146105ca578063a7feae45146105d3578063a87430ba146105db578063acbca7e214610605575f80fd5b80633b032005116101f8578063715018a6116101b2578063715018a6146104db578063733b0eb9146104e357806381dbe8b11461051357806386d6b6be1461051c578063873e31fa146105465780638da5cb5b14610586575f80fd5b80633b032005146104535780633c7afca5146104665780633ffbd47f1461046f5780636386c1c714610482578063654cfdff146104a85780636a9564c7146104bb575f80fd5b806315ad7b9c1161024957806315ad7b9c1461035f57806315ff8dd9146103a45780632e5a15ca146103fb5780632fc3140e1461041e57806332bc298c1461042757806337ff924a14610431575f80fd5b80630930df6a146102855780630962ef79146102de5780630b11e312146102f357806311bdd73d1461030657806313fcaf5414610326575b5f80fd5b6102986102933660046145c9565b6109c5565b6040805198895260208901979097529587019490945260ff909216606086015215156080850152151560a084015260c083015260e0820152610100015b60405180910390f35b6102f16102ec3660046145f3565b610bde565b005b6102f16103013660046145f3565b610df6565b61031961031436600461460a565b6113ec565b6040516102d59190614625565b61035161033436600461460a565b6001600160a01b03165f908152603560205260409020600b015490565b6040519081526020016102d5565b61038f61036d366004614671565b603d60209081525f928352604080842090915290825290205463ffffffff1681565b60405163ffffffff90911681526020016102d5565b6103de6103b23660046145f3565b5f818152603a6020908152604080832054603b835281842054603c90935292205460ff90921693909250565b6040805193151584526020840192909252908201526060016102d5565b61040e610409366004614741565b61146a565b60405190151581526020016102d5565b61035160445481565b6103516201518081565b61040e61043f3660046145f3565b603a6020525f908152604090205460ff1681565b61040e610461366004614790565b61154f565b610351603f5481565b6102f161047d3660046147ca565b61159b565b61049561049036600461460a565b6118cf565b6040516102d59796959493929190614877565b6102f16104b63660046148c3565b6119ca565b6104ce6104c936600461460a565b611c86565b6040516102d591906148e4565b6102f1611ced565b6104eb611d61565b604080519586526020860194909452928401919091526060830152608082015260a0016102d5565b61035160455481565b61035161052a366004614671565b603e60209081525f928352604080842090915290825290205481565b61055961055436600461460a565b611de7565b604080519687526020870195909552938501929092526060840152608083015260a082015260c0016102d5565b6001546001600160a01b03165b6040516001600160a01b0390911681526020016102d5565b6105b3611e49565b6040805192151583526020830191909152016102d5565b61035160435481565b6102f1611f5c565b6105ee6105e936600461460a565b612163565b6040516102d59b9a9998979695949392919061490c565b61035160405481565b61062161061c366004614978565b61224e565b604080519283526020830191909152016102d5565b6106216106443660046145f3565b6122d4565b6105936106573660046145f3565b60396020525f90815260409020546001600160a01b031681565b6106df61067f36600461460a565b6001600160a01b03165f90815260356020908152604080832060369092529091206005808301546006909301549101549192909163ffffffff808216926401000000008304821692600160401b810490921691600160601b900460ff1690565b60408051968752602087019590955263ffffffff93841694860194909452908216606085015216608083015260ff1660a082015260c0016102d5565b61072e610729366004614978565b6122f5565b6040805193845263ffffffff9092166020840152908201526060016102d5565b61077a61075c366004614978565b601f6020525f90815260409020805460019091015460ff9091169082565b6040805160ff90931683526020830191909152016102d5565b61040e7f000000000000000000000000000000000000000000000000000000000000000181565b6103516107c83660046145f3565b603b6020525f908152604090205481565b6107ec6107e736600461460a565b612396565b60408051938452602084019290925260ff16908201526060016102d5565b61087d61081836600461460a565b60366020525f908152604090208054600182015460028301546003840154600485015460058601546006909601549495939492939192909163ffffffff808216926401000000008304821692600160401b810490921691600160601b900460ff16908a565b604080519a8b5260208b0199909952978901969096526060880194909452608087019290925263ffffffff90811660a087015290811660c08601521660e084015260ff16610100830152610120820152610140016102d5565b6102f16108e43660046148c3565b6124f0565b61072e6108f73660046145f3565b61285e565b603f54604054600254604080519384526020840192909252908201526060016102d5565b61035161092e3660046145f3565b603c6020525f908152604090205481565b61040e61094d366004614790565b805160208183018101805160388252928201919093012091525460ff1681565b61059373c8d2701882a9a629e9a9332950fef78ee4ffd9a981565b610593610996366004614790565b80516020818301810180516037825292820191909301209152546001600160a01b031681565b61035160025481565b6001600160a01b0382165f908152603560205260408120600b8101548291829182918291829182918291908a10610a335760405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b60448201526064015b60405180910390fd5b5f81600b018b81548110610a4957610a49614991565b5f918252602082206005919091020160048181015491935060039160ff16908110610a7657610a76614991565b600202015490505f610a8b62015180836149b9565b8360010154610a9a91906149d0565b6004808501549192505f916127109160039160ff16908110610abe57610abe614991565b6002020160010154855f0154610ad491906149b9565b610ade91906149e3565b90505f824211610aee5742610af0565b825b90505f85600101548211610b04575f610b13565b6001860154610b139083614a02565b90505f808211610b23575f610b84565b62015180610b33876127106149b9565b610b3d91906149b9565b600480890154849160039160ff16908110610b5a57610b5a614991565b6002020160010154895f0154610b7091906149b9565b610b7a91906149b9565b610b8491906149e3565b9050865f0154876001015486896004015f9054906101000a900460ff168a60040160019054906101000a900460ff168942101589879f509f509f509f509f509f509f509f5050505050505050509295985092959890939650565b610be661288d565b6002541580610bf6575060025442105b15610c1457604051638dda39df60e01b815260040160405180910390fd5b335f9081526035602090815260408083206036909252909120600282015460ff16610c525760405163aba4733960e01b815260040160405180910390fd5b610c5b336128b5565b50600181015481545f610c6e82846149d0565b9050805f03610c9057604051630fec21fd60e21b815260040160405180910390fd5b855f03610c9b578095505b80861115610cbc57604051631e9acf1760e31b815260040160405180910390fd5b670de0b6b3a7640000861015610ce55760405163860b82a960e01b815260040160405180910390fd5b858315801590610cf457505f81115b15610d3357838110610d1757610d0a8482614a02565b5f60018701559050610d33565b80856001015f828254610d2a9190614a02565b909155505f9150505b5f83118015610d4157505f81115b15610d7057828110610d55575f8555610d6d565b80855f015f828254610d679190614a02565b90915550505b505f5b610d7a8733612ce3565b86866009015f828254610d8d91906149d0565b925050819055508660425f828254610da591906149d0565b90915550506040805188815242602082015233917f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a910160405180910390a2505050505050610df360015f55565b50565b610dfe61288d565b6002541580610e0e575060025442105b15610e2c57604051638dda39df60e01b815260040160405180910390fd5b5f8111610e7b5760405162461bcd60e51b815260206004820152601d60248201527f4c656e677468206d7573742062652067726561746572207468616e20300000006044820152606401610a2a565b5f6201518060025442610e8e9190614a02565b610e9891906149e3565b9050805f03610ea757506113e3565b6044541580610ec657506044545f908152603a602052604090205460ff165b15610f0e576044545b81811015610f0c575f818152603a602052604090205460ff16610efa5760448190555f604555610f0c565b80610f0481614a15565b915050610ecf565b505b6044545f908152603a602052604090205460ff1615610f2d57506113e3565b5f806045545f14610f4057604554610f43565b60015b6044549091505f62015180610f598360016149d0565b610f6391906149b9565b600254610f7091906149d0565b905042811115610f7d5750425b825b60435481108015610f8f57508685105b15611323575f818152603960209081526040808320546001600160a01b03168084526035835281842060369093529220600282015460ff16610fe05787610fd581614a15565b985050505050611311565b84816006015410610ff55787610fd581614a15565b5f805b600b8401548110156112505783600b01818154811061101957611019614991565b905f5260205f20906005020160040160019054906101000a900460ff1661123e575f600385600b01838154811061105257611052614991565b5f9182526020909120600460059092020181015460ff1690811061107857611078614991565b600202015490505f61108d62015180836149b9565b86600b0184815481106110a2576110a2614991565b905f5260205f209060050201600101546110bc91906149d0565b90505f86600b0184815481106110d4576110d4614991565b905f5260205f2090600502016002015490508181101561123a575f828b106110fc57826110fe565b8a5b9050818111611110575050505061123e565b5f61111b8383614a02565b90508015611237575f62015180611134876127106149b9565b61113e91906149b9565b8260038c600b018a8154811061115657611156614991565b5f9182526020909120600460059092020181015460ff1690811061117c5761117c614991565b60020201600101548c600b018a8154811061119957611199614991565b905f5260205f2090600502015f01546111b291906149b9565b6111bc91906149b9565b6111c691906149e3565b90506111d281896149d0565b9750828a600b0188815481106111ea576111ea614991565b905f5260205f20906005020160020181905550808a600b01888154811061121357611213614991565b905f5260205f2090600502016003015f82825461123091906149d0565b9091555050505b50505b5050505b8061124881614a15565b915050610ff8565b50801561128e5761126184826130bb565b61126b8482613250565b5f878152603c6020526040812080548392906112889084906149d0565b90915550505b600682018690558861129f81614a15565b5f898152603b602052604081208054929c509192506112bd83614a15565b9091555050604080518281525f6020820152428183015290516001600160a01b038616917fbc3e667b85309bf5b995e6447d14031fa213f47d4da0f1c041c733eb1e18914b919081900360600190a2505050505b8061131b81614a15565b915050610f7f565b5061132e84846149d0565b6045819055604354116113b3575f828152603a60209081526040808320805460ff19166001179055603c909152902054156113ae575f828152603c60205260408120546127109061138290610258906149b9565b61138c91906149e3565b90506113ac8173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b505b5f6045555b60405182907f23f8a1a4055fe6f4bd070e929249963966b1e8b4fd06d403d132ee8535a92aa6905f90a250505050505b610df360015f55565b6113f4614596565b5f5b60148160ff161015611464576001600160a01b0383165f908152603d6020908152604080832060ff851680855292529091205463ffffffff169083906014811061144257611442614991565b63ffffffff90921660209290920201528061145c81614a2d565b9150506113f6565b50919050565b5f8060378460405161147c9190614a4b565b908152604051908190036020019020546001600160a01b0316905073c8d2701882a9a629e9a9332950fef78ee4ffd9a81981016114bd576001915050611549565b6001600160a01b0381166114d4575f915050611549565b826001600160a01b0316816001600160a01b0316036114f6575f915050611549565b6001600160a01b0381165f9081526035602052604090206002015460ff16611521575f915050611549565b68015af1d78b58c4000061153482613433565b1015611543575f915050611549565b60019150505b92915050565b5f6115598261346f565b61156457505f919050565b6038826040516115749190614a4b565b9081526040519081900360200190205460ff161561159357505f919050565b506001919050565b6115a361288d565b60025415806115b3575060025442105b156115d157604051638dda39df60e01b815260040160405180910390fd5b335f9081526035602052604090206002015460ff161561160457604051630ea075bf60e21b815260040160405180910390fd5b61160d8261346f565b61162a57604051630a1de65160e31b815260040160405180910390fd5b60388260405161163a9190614a4b565b9081526040519081900360200190205460ff161561166b57604051636bc324ad60e01b815260040160405180910390fd5b5f60378260405161167c9190614a4b565b908152604051908190036020019020546001600160a01b0316905073c8d2701882a9a629e9a9332950fef78ee4ffd9a9811461176f576001600160a01b0381166116d957604051633665e87960e11b815260040160405180910390fd5b336001600160a01b03821603611702576040516368d7fd4960e11b815260040160405180910390fd5b6001600160a01b0381165f9081526035602052604090206002015460ff1661173d57604051636dc69e6560e11b815260040160405180910390fd5b68015af1d78b58c4000061175082613433565b101561176f57604051636dc69e6560e11b815260040160405180910390fd5b335f9081526035602052604090206001810161178b8582614add565b5080546001600160a01b0383166001600160a01b031991821617825560028201805460ff1916600117905560438054600384018190555f908152603960205260408120805490931633179092558054916117e483614a15565b9190505550336037856040516117fa9190614a4b565b90815260200160405180910390205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550600160388560405161183d9190614a4b565b908152604051908190036020019020805491151560ff19909216919091179055603f8054905f61186c83614a15565b9190505550816001600160a01b0316336001600160a01b03167f78d6e8f849b1071e5deda6bc7f2c2a8a6e2d092683aec45e1b7f4fbc95860c0b8686426040516118b893929190614b99565b60405180910390a350506118cb60015f55565b5050565b6001600160a01b038082165f90815260356020526040812080546002820154600483015460088401546009850154600a86015460018701805460609a8a998a998a998a998a9993989697929094169560ff90911694909190879061193290614a66565b80601f016020809104026020016040519081016040528092919081815260200182805461195e90614a66565b80156119a95780601f10611980576101008083540402835291602001916119a9565b820191905f5260205f20905b81548152906001019060200180831161198c57829003601f168201915b50505050509650975097509750975097509750975050919395979092949650565b6119d261288d565b60025415806119e2575060025442105b15611a0057604051638dda39df60e01b815260040160405180910390fd5b670de0b6b3a7640000821015611a295760405163860b82a960e01b815260040160405180910390fd5b60048160ff1610611a4d576040516321f2425960e01b815260040160405180910390fd5b335f908152603560205260409020600281015460ff16611a8057604051633a075e6360e01b815260040160405180910390fd5b600b81015461019011611aa65760405163291b490560e21b815260040160405180910390fd5b600881015415611ae16001600160a01b037f00000000000000000000000055d398326f99059ff775485246999027b31979551633308761357a565b5f611aeb856135b0565b90505f612710611afd610258846149b9565b611b0791906149e3565b9050611b278173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b6040805160c0810182528381524260208083018281529383019182525f6060840181815260ff808c166080870190815260a08701848152600b8d018054600181810183559187529686209851600590970290980195865597519685019690965593516002840155516003830155925160049091018054945115156101000261ffff19909516919092161792909217909155600885018054849290611bcc9084906149d0565b9250508190555081846004015f828254611be691906149d0565b925050819055508160415f828254611bfe91906149d0565b90915550611c119050338360015f61384c565b8215611c3557611c2033613afb565b60408054905f611c2f83614a15565b91905055505b6040805183815260ff871660208201524281830152905133917f658ea7d02788018eff5425fa04c446062f80a2026f9899163e3a221cc30d0936919081900360600190a2505050506118cb60015f55565b611c8e614596565b5f5b60148160ff161015611464576001600160a01b0383165f908152603e6020908152604080832060ff851680855292529091205490839060148110611cd657611cd6614991565b602002015280611ce581614a2d565b915050611c90565b6001546001600160a01b03163314611d18576040516330cd747160e01b815260040160405180910390fd5b6001546040516001600160a01b03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c64820905f90a2600180546001600160a01b0319169055565b5f805f805f6201518060025442611d789190614a02565b611d8291906149e3565b9450604454935060455492505f60435411611d9d575f611dac565b6001604354611dac9190614a02565b91505f8315611dbb5783611dbe565b60015b90508060435411611dcf575f611ddd565b80604354611ddd9190614a02565b9150509091929394565b6001600160a01b0381165f9081526036602052604081208190819081908190819081611e1289613c81565b8254909150611e2181836149d0565b600184015484546002860154600490960154929d949c50909a50985092965091945092505050565b5f806002545f1480611e5c575060025442105b15611e6957505f91829150565b5f6201518060025442611e7c9190614a02565b611e8691906149e3565b9050805f03611e9957505f928392509050565b604454604554811580611eb957505f828152603a602052604090205460ff165b15611efc57815b83811015611efa575f818152603a602052604090205460ff16611ee8578092505f9150611efa565b80611ef281614a15565b915050611ec0565b505b5f828152603a602052604090205460ff1615611f1e57505f9485945092505050565b5f8115611f2b5781611f2e565b60015b90508060435411611f3f575f611f4d565b80604354611f4d9190614a02565b94505f85119550505050509091565b611f6461288d565b6002541580611f74575060025442105b15611f9257604051638dda39df60e01b815260040160405180910390fd5b335f9081526035602052604090206002015460ff16611fc45760405163aba4733960e01b815260040160405180910390fd5b335f90815260366020526040902060068101544211611fe35750612158565b5f6201518060025442611ff69190614a02565b61200091906149e3565b90505f82600601545f14612033576201518060025484600601546120249190614a02565b61202e91906149e3565b612035565b5f5b90505f815b8381116120fc575f620151806120518360016149d0565b61205b91906149b9565b60025461206891906149d0565b9050428111156120755750425b8086600601541061208657506120ea565b5f6120913383613e4b565b905061209d81856149d0565b60068801839055604080518381525f60208201524281830152905191955033917fbc3e667b85309bf5b995e6447d14031fa213f47d4da0f1c041c733eb1e18914b9181900360600190a250505b806120f481614a15565b91505061203a565b5080156121535761210d33826130bb565b6121173382613250565b5f612710612127610258846149b9565b61213191906149e3565b90506121518173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b505b505050505b61216160015f55565b565b60356020525f9081526040902080546001820180546001600160a01b03909216929161218e90614a66565b80601f01602080910402602001604051908101604052809291908181526020018280546121ba90614a66565b80156122055780601f106121dc57610100808354040283529160200191612205565b820191905f5260205f20905b8154815290600101906020018083116121e857829003601f168201915b50505060028401546003850154600486015460058701546006880154600789015460088a015460098b0154600a909b0154999a60ff90971699959850939650919490939192918b565b5f8060048360ff16106122925760405162461bcd60e51b815260206004820152600c60248201526b24b73b30b634b210383630b760a11b6044820152606401610a2a565b60038360ff16600481106122a8576122a8614991565b6002020154600360ff8516600481106122c3576122c3614991565b600202016001015491509150915091565b600381600481106122e3575f80fd5b60020201805460019091015490915082565b5f805f60078460ff161061233a5760405162461bcd60e51b815260206004820152600c60248201526b496e76616c69642072616e6b60a01b6044820152606401610a2a565b5f60208560ff166007811061235157612351614991565b60408051606081018252600392909202929092018054808352600182015463ffffffff1660208401819052600290920154929093018290529197919650945092505050565b6001600160a01b0381165f9081526035602090815260408083206036909252822082918291600b8201835b81548110156124d5578181815481106123dc576123dc614991565b905f5260205f20906005020160040160019054906101000a900460ff166124c3575f62015180600384848154811061241657612416614991565b5f9182526020909120600460059092020181015460ff1690811061243c5761243c614991565b600202015461244b91906149b9565b83838154811061245d5761245d614991565b905f5260205f2090600502016001015461247791906149d0565b905080421061248657506124c3565b82828154811061249857612498614991565b905f5260205f2090600502015f0154886124b291906149d0565b9750866124be81614a15565b975050505b806124cd81614a15565b9150506123c1565b50506005015460ff600160601b909104169150509193909250565b6124f861288d565b6002541580612508575060025442105b1561252657604051638dda39df60e01b815260040160405180910390fd5b60048160ff161061254a576040516321f2425960e01b815260040160405180910390fd5b335f9081526035602090815260408083206036909252909120600282015460ff166125885760405163aba4733960e01b815260040160405180910390fd5b600b820154610190116125ae5760405163291b490560e21b815260040160405180910390fd5b6125b7336128b5565b50600181015481545f6125ca82846149d0565b9050805f036125ec57604051630fec21fd60e21b815260040160405180910390fd5b865f036125f7578096505b8087111561261857604051631e9acf1760e31b815260040160405180910390fd5b670de0b6b3a76400008710156126415760405163860b82a960e01b815260040160405180910390fd5b86831580159061265057505f81115b1561268f57838110612673576126668482614a02565b5f6001870155905061268f565b80856001015f8282546126869190614a02565b909155505f9150505b5f8311801561269d57505f81115b156126cc578281106126b1575f85556126c9565b80855f015f8282546126c39190614a02565b90915550505b505f5b5f6127106126dc6102588b6149b9565b6126e691906149e3565b90506127068173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b86600b016040518060c001604052808b81526020014281526020014281526020015f81526020018a60ff1681526020015f1515815250908060018154018082558091505060019003905f5260205f2090600502015f909190919091505f820151815f01556020820151816001015560408201518160020155606082015181600301556080820151816004015f6101000a81548160ff021916908360ff16021790555060a08201518160040160016101000a81548160ff02191690831515021790555050508887600a015f8282546127dd91906149d0565b9250508190555088876004015f8282546127f791906149d0565b9091555061280a9050338a60018061384c565b604080518a815260ff8a1660208201524281830152905133917f2f43906271c2313ff3872901245076d7f7f3bda8288909521826dd32e3b2540d919081900360600190a2505050505050506118cb60015f55565b6020816007811061286d575f80fd5b600302018054600182015460029092015490925063ffffffff9091169083565b60025f54036128af57604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b6001600160a01b0381165f908152603560209081526040808320603690925282208280805b600b850154811015612c715784600b0181815481106128fb576128fb614991565b905f5260205f20906005020160040160019054906101000a900460ff16612c5f575f62015180600387600b01848154811061293857612938614991565b5f9182526020909120600460059092020181015460ff1690811061295e5761295e614991565b600202015461296d91906149b9565b86600b01838154811061298257612982614991565b905f5260205f2090600502016001015461299c91906149d0565b9050804210612c5d575f612710600388600b0185815481106129c0576129c0614991565b5f9182526020909120600460059092020181015460ff169081106129e6576129e6614991565b600202016001015488600b018581548110612a0357612a03614991565b905f5260205f2090600502015f0154612a1c91906149b9565b612a2691906149e3565b87600b018481548110612a3b57612a3b614991565b905f5260205f2090600502015f0154612a5491906149d0565b90505f612710600389600b018681548110612a7157612a71614991565b5f9182526020909120600460059092020181015460ff16908110612a9757612a97614991565b600202016001015489600b018681548110612ab457612ab4614991565b905f5260205f2090600502015f0154612acd91906149b9565b612ad791906149e3565b905087600b018481548110612aee57612aee614991565b905f5260205f20906005020160030154811115612b425787600b018481548110612b1a57612b1a614991565b905f5260205f2090600502016003015481612b359190614a02565b612b3f90866149d0565b94505b600188600b018581548110612b5957612b59614991565b905f5260205f20906005020160040160016101000a81548160ff02191690831515021790555087600b018481548110612b9457612b94614991565b905f5260205f2090600502015f0154886004015410612c1b5787600b018481548110612bc257612bc2614991565b905f5260205f2090600502015f0154886004015f828254612be39190614a02565b9091555050600b8801805485908110612bfe57612bfe614991565b905f5260205f2090600502015f015486612c1891906149d0565b95505b80876003015f828254612c2e91906149d0565b9250508190555081876001015f828254612c4891906149d0565b90915550612c589050828a6149d0565b985050505b505b80612c6981614a15565b9150506128da565b508115612c8457612c8486835f8061384c565b8015612cda57612c9486826130bb565b612c9e8682613250565b5f612710612cae610258846149b9565b612cb891906149e3565b9050612cd88173c8d2701882a9a629e9a9332950fef78ee4ffd9a9612ce3565b505b50505050919050565b815f03612cee575050565b60405163133f757160e31b81527f000000000000000000000000000000000000000000000000000000000064c62760048201525f90819081906001600160a01b037f00000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f436416906399fbab889060240161018060405180830381865afa158015612d77573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d9b9190614c12565b9b509b5050509950505050505050505f7f0000000000000000000000000000000000000000000000000000000000000001612dd65781612dd8565b825b905085816001600160801b03161015612fc1575f612dff6001600160801b03831688614a02565b90505f670de0b6b3a7640000612e1e68012b27d72e93fc2abc846149b9565b612e2891906149e3565b9050806001600160801b0381165f03612e3f575060015b866001600160801b0316816001600160801b03161115612ea15760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e74204c50206c6971756964697479000000000000006044820152606401610a2a565b7f00000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f43646001600160a01b0316630c49ccbe6040518060a001604052807f000000000000000000000000000000000000000000000000000000000064c6278152602001846001600160801b031681526020015f81526020015f81526020014261012c612f2a91906149d0565b9052604080516001600160e01b031960e085901b1681528251600482015260208301516001600160801b0316602482015290820151604482015260608201516064820152608090910151608482015260a40160408051808303815f875af1158015612f97573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fbb9190614ceb565b50505050505b604080516080810182527f000000000000000000000000000000000000000000000000000000000064c62781526001600160a01b03878116602083019081526001600160801b0383850181815260608501828152955163fc6f786560e01b815294516004860152915183166024850152905181166044840152925190921660648201527f00000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f43649091169063fc6f78659060840160408051808303815f875af115801561308d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130b19190614ceb565b5050505050505050565b6001600160a01b038083165f90815260356020526040812054909116905b601460ff82161080156130f457506001600160a01b03821615155b1561324a576001600160a01b0382165f90815260366020526040902061311a838361422a565b1561321a575f612710600b8460ff166014811061313957613139614991565b015461314590876149b9565b61314f91906149e3565b905080825f015f82825461316391906149d0565b9250508190555080826002015f82825461317d91906149d0565b90915550506001600160a01b0384165f908152603e6020908152604080832060ff87168452909152812080548392906131b79084906149d0565b90915550506001600160a01b038087169085167fb95cd440a52937795da4af7f392ab0f953bea11ef59d553bf04ea0c63a9e2c9b6131f6866001614d0d565b6040805160ff909216825260208201869052429082015260600160405180910390a3505b506001600160a01b039182165f90815260356020526040902054909116908061324281614a2d565b9150506130d9565b50505050565b6001600160a01b038083165f9081526035602052604081205490911690805b606460ff821610801561328a57506001600160a01b03831615155b1561342c576001600160a01b0383165f90815260356020908152604080832060368352908320600581015491939092600160601b90920460ff169182600781106132d6576132d6614991565b6003020160010154600584015463ffffffff91821691161080159061331c575060208260ff166007811061330c5761330c614991565b6003020160020154846005015410155b1561333f5760208260ff166007811061333757613337614991565b600302015490505b858111156133f7575f6133528783614a02565b90505f612710613362838c6149b9565b61336c91906149e3565b905080855f015f82825461338091906149d0565b9250508190555080856004015f82825461339a91906149d0565b90915550506040805160ff8616815260208101839052428183015290516001600160a01b038d811692908c16917f8d2091022f06ad0b5b021c10b844e2555df2df0029a672b3e6ac2c85957ee81d9181900360600190a382975050505b6103e88610613409575050505061342c565b505090546001600160a01b0316935081905061342481614a2d565b91505061326f565b5050505050565b6001600160a01b0381165f908152603560205260408120600b8101546101901115613462578060040154613468565b80600801545b9392505050565b5f80829050600381511080613485575060148151115b1561349257505f92915050565b5f5b8151811015613570575f8282815181106134b0576134b0614991565b01602001516001600160f81b0319169050600360fc1b81108015906134e35750603960f81b6001600160f81b0319821611155b1580156135195750604160f81b6001600160f81b03198216108015906135175750602d60f91b6001600160f81b0319821611155b155b801561354e5750606160f81b6001600160f81b031982161080159061354c5750603d60f91b6001600160f81b0319821611155b155b1561355d57505f949350505050565b508061356881614a15565b915050613494565b5060019392505050565b6135888484848460016142bc565b61324a57604051635274afe760e01b81526001600160a01b0385166004820152602401610a2a565b5f815f036135bf57505f919050565b6136136001600160a01b037f00000000000000000000000055d398326f99059ff775485246999027b3197955167f00000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f436484614329565b5f7f000000000000000000000000000000000000000000000000000000000000000161363f575f613641565b825b90505f7f000000000000000000000000000000000000000000000000000000000000000161366f5783613671565b5f5b90505f60646136818460636149b9565b61368b91906149e3565b90505f606461369b8460636149b9565b6136a591906149e3565b90505f807f00000000000000000000000046a15b0b27311cedf172ab29e4f4766fbe7f43646001600160a01b031663219f5d176040518060c001604052807f000000000000000000000000000000000000000000000000000000000064c62781526020018981526020018881526020018781526020018681526020014261012c61372f91906149d0565b9052604080516001600160e01b031960e085901b1681528251600482015260208301516024820152908201516044820152606082015160648201526080820151608482015260a09091015160a482015260c4016060604051808303815f875af115801561379e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137c29190614d26565b92509250507f00000000000000000000000000000000000000000000000000000000000000016137f257806137f4565b815b965086881115613841575f613809888a614a02565b905061383f6001600160a01b037f00000000000000000000000055d398326f99059ff775485246999027b31979551633836143a3565b505b505050505050919050565b6001600160a01b038085165f90815260356020526040902054168015613998576001600160a01b038082165f9081526036602090815260408083209389168352603590915290206004015484156139105768015af1d78b58c4000081101580156138c7575068015af1d78b58c400006138c58783614a02565b105b1561390b57600582018054600160401b900463ffffffff169060086138eb83614d58565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b613995565b68015af1d78b58c400008110801561393a575068015af1d78b58c4000061393787836149d0565b10155b15613995576005820154600160401b900463ffffffff161561399557600582018054600160401b900463ffffffff1690600861397583614d7a565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b50505b5f5b6001600160a01b038216158015906139b55750606460ff8216105b15613af3578315613a54576001600160a01b0382165f90815260356020526040812060050180548792906139ea9084906149d0565b90915550508215613a2a576001600160a01b0382165f9081526035602052604081206007018054879290613a1f9084906149d0565b90915550613abb9050565b6001600160a01b0382165f9081526035602052604081206006018054879290613a1f9084906149d0565b6001600160a01b0382165f908152603560205260409020600501548511613a9f576001600160a01b0382165f9081526035602052604081206005018054879290613a1f908490614a02565b6001600160a01b0382165f908152603560205260408120600501555b613ac4826143b0565b6001600160a01b039182165f908152603560205260409020549091169080613aeb81614a2d565b91505061399a565b505050505050565b6001600160a01b038082165f90815260356020526040902054168015613b71576001600160a01b0381165f9081526036602052604090206005018054640100000000900463ffffffff16906004613b5183614d58565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b5f5b6001600160a01b03821615801590613b8e5750606460ff8216105b15613c7c576001600160a01b0382165f908152603660205260408120600501805463ffffffff1691613bbf83614d58565b91906101000a81548163ffffffff021916908363ffffffff16021790555050601460ff168160ff161015613c44576001600160a01b0382165f908152603d6020908152604080832060ff851684529091528120805463ffffffff1691613c2483614d58565b91906101000a81548163ffffffff021916908363ffffffff160217905550505b613c4d826143b0565b6001600160a01b039182165f908152603560205260409020549091169080613c7481614a2d565b915050613b73565b505050565b6001600160a01b0381165f908152603560209081526040808320603690925282206001810154925b600b830154811015613e435782600b018181548110613cca57613cca614991565b905f5260205f20906005020160040160019054906101000a900460ff16613e31575f62015180600385600b018481548110613d0757613d07614991565b5f9182526020909120600460059092020181015460ff16908110613d2d57613d2d614991565b6002020154613d3c91906149b9565b84600b018381548110613d5157613d51614991565b905f5260205f20906005020160010154613d6b91906149d0565b9050804210613e2f57612710600385600b018481548110613d8e57613d8e614991565b5f9182526020909120600460059092020181015460ff16908110613db457613db4614991565b600202016001015485600b018481548110613dd157613dd1614991565b905f5260205f2090600502015f0154613dea91906149b9565b613df491906149e3565b84600b018381548110613e0957613e09614991565b905f5260205f2090600502015f0154613e2291906149d0565b613e2c90866149d0565b94505b505b80613e3b81614a15565b915050613ca9565b505050919050565b6001600160a01b0382165f908152603560205260408120815b600b8201548110156142225781600b018181548110613e8557613e85614991565b905f5260205f20906005020160040160019054906101000a900460ff16614210575f600383600b018381548110613ebe57613ebe614991565b5f9182526020909120600460059092020181015460ff16908110613ee457613ee4614991565b600202015490505f613ef962015180836149b9565b84600b018481548110613f0e57613f0e614991565b905f5260205f20906005020160010154613f2891906149d0565b90508084600b018481548110613f4057613f40614991565b905f5260205f2090600502016002015410156140eb575f818710613f645781613f66565b865b905084600b018481548110613f7d57613f7d614991565b905f5260205f209060050201600201548111613f9b57505050614210565b5f85600b018581548110613fb157613fb1614991565b905f5260205f2090600502016002015482613fcc9190614a02565b905080156140e8575f62015180613fe5866127106149b9565b613fef91906149b9565b82600389600b01898154811061400757614007614991565b5f9182526020909120600460059092020181015460ff1690811061402d5761402d614991565b600202016001015489600b01898154811061404a5761404a614991565b905f5260205f2090600502015f015461406391906149b9565b61406d91906149b9565b61407791906149e3565b905061408381896149d0565b97508287600b01878154811061409b5761409b614991565b905f5260205f209060050201600201819055508087600b0187815481106140c4576140c4614991565b905f5260205f2090600502016003015f8282546140e191906149d0565b9091555050505b50505b80861061420d575f612710600386600b01868154811061410d5761410d614991565b5f9182526020909120600460059092020181015460ff1690811061413357614133614991565b600202016001015486600b01868154811061415057614150614991565b905f5260205f2090600502015f015461416991906149b9565b61417391906149e3565b90508085600b01858154811061418b5761418b614991565b905f5260205f20906005020160030154101561420b575f85600b0185815481106141b7576141b7614991565b905f5260205f20906005020160030154826141d29190614a02565b90506141de81886149d0565b96508186600b0186815481106141f6576141f6614991565b905f5260205f20906005020160030181905550505b505b50505b8061421a81614a15565b915050613e64565b505092915050565b5f601460ff83161061423d57505f611549565b6001600160a01b0383165f90815260366020908152604080832060ff8681168552601f8452938290208251808401909352805490941680835260019094015492820192909252600582015491929091600160401b900463ffffffff16108015906142b3575080602001516142b086613433565b10155b95945050505050565b6040516323b872dd60e01b5f8181526001600160a01b038781166004528616602452604485905291602083606481808c5af1925060015f5114831661431857838315161561430c573d5f823e3d81fd5b5f883b113d1516831692505b604052505f60605295945050505050565b6143358383835f6144ea565b613c7c5761434683835f60016144ea565b61436e57604051635274afe760e01b81526001600160a01b0384166004820152602401610a2a565b61437b83838360016144ea565b613c7c57604051635274afe760e01b81526001600160a01b0384166004820152602401610a2a565b61437b838383600161454c565b6001600160a01b0381165f90815260356020908152604080832060369092529091206005810154600160601b900460ff1660065b60208160ff16600781106143fa576143fa614991565b6003020160010154600584015463ffffffff918216911610801590614440575060208160ff166007811061443057614430614991565b6003020160020154846005015410155b1561444d57809150614468565b60ff811615614468578061446081614d98565b9150506143e4565b50600582015460ff828116600160601b909204161461324a5760058201805460ff60601b1916600160601b60ff841690810291909117909155604080519182524260208301526001600160a01b038616917f741d7439fd15937c8d73d3e8fde5a7847d18b945292ab9831186ecab48980832910160405180910390a250505050565b60405163095ea7b360e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316614540578383151615614534573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b60405163a9059cbb60e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316614540578383151615614534573d5f823e3d81fd5b6040518061028001604052806014906020820280368337509192915050565b6001600160a01b0381168114610df3575f80fd5b5f80604083850312156145da575f80fd5b82356145e5816145b5565b946020939093013593505050565b5f60208284031215614603575f80fd5b5035919050565b5f6020828403121561461a575f80fd5b8135613468816145b5565b610280810181835f5b601481101561465357815163ffffffff1683526020928301929091019060010161462e565b50505092915050565b803560ff8116811461466c575f80fd5b919050565b5f8060408385031215614682575f80fd5b823561468d816145b5565b915061469b6020840161465c565b90509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126146c7575f80fd5b813567ffffffffffffffff808211156146e2576146e26146a4565b604051601f8301601f19908116603f0116810190828211818310171561470a5761470a6146a4565b81604052838152866020858801011115614722575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f8060408385031215614752575f80fd5b823567ffffffffffffffff811115614768575f80fd5b614774858286016146b8565b9250506020830135614785816145b5565b809150509250929050565b5f602082840312156147a0575f80fd5b813567ffffffffffffffff8111156147b6575f80fd5b6147c2848285016146b8565b949350505050565b5f80604083850312156147db575f80fd5b823567ffffffffffffffff808211156147f2575f80fd5b6147fe868387016146b8565b93506020850135915080821115614813575f80fd5b50614820858286016146b8565b9150509250929050565b5f5b8381101561484457818101518382015260200161482c565b50505f910152565b5f815180845261486381602086016020860161482a565b601f01601f19169290920160200192915050565b60e081525f61488960e083018a61484c565b6001600160a01b039890981660208301525094151560408601526060850193909352608084019190915260a083015260c090910152919050565b5f80604083850312156148d4575f80fd5b8235915061469b6020840161465c565b610280810181835f5b60148110156146535781518352602092830192909101906001016148ed565b6001600160a01b038c168152610160602082018190525f906149308382018e61484c565b9b1515604084015250506060810198909852608088019690965260a087019490945260c086019290925260e08501526101008401526101208301526101409091015292915050565b5f60208284031215614988575f80fd5b6134688261465c565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417611549576115496149a5565b80820180821115611549576115496149a5565b5f826149fd57634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115611549576115496149a5565b5f60018201614a2657614a266149a5565b5060010190565b5f60ff821660ff8103614a4257614a426149a5565b60010192915050565b5f8251614a5c81846020870161482a565b9190910192915050565b600181811c90821680614a7a57607f821691505b60208210810361146457634e487b7160e01b5f52602260045260245ffd5b601f821115613c7c575f81815260208120601f850160051c81016020861015614abe5750805b601f850160051c820191505b81811015613af357828155600101614aca565b815167ffffffffffffffff811115614af757614af76146a4565b614b0b81614b058454614a66565b84614a98565b602080601f831160018114614b3e575f8415614b275750858301515b5f19600386901b1c1916600185901b178555613af3565b5f85815260208120601f198616915b82811015614b6c57888601518255948401946001909101908401614b4d565b5085821015614b8957878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b606081525f614bab606083018661484c565b8281036020840152614bbd818661484c565b915050826040830152949350505050565b805161466c816145b5565b805162ffffff8116811461466c575f80fd5b8051600281900b811461466c575f80fd5b80516001600160801b038116811461466c575f80fd5b5f805f805f805f805f805f806101808d8f031215614c2e575f80fd5b8c516bffffffffffffffffffffffff81168114614c49575f80fd5b9b50614c5760208e01614bce565b9a50614c6560408e01614bce565b9950614c7360608e01614bce565b9850614c8160808e01614bd9565b9750614c8f60a08e01614beb565b9650614c9d60c08e01614beb565b9550614cab60e08e01614bfc565b94506101008d015193506101208d01519250614cca6101408e01614bfc565b9150614cd96101608e01614bfc565b90509295989b509295989b509295989b565b5f8060408385031215614cfc575f80fd5b505080516020909101519092909150565b60ff8181168382160190811115611549576115496149a5565b5f805f60608486031215614d38575f80fd5b614d4184614bfc565b925060208401519150604084015190509250925092565b5f63ffffffff808316818103614d7057614d706149a5565b6001019392505050565b5f63ffffffff821680614d8f57614d8f6149a5565b5f190192915050565b5f60ff821680614d8f57614d8f6149a556fea2646970667358221220cc9c802175e7e1372bf4f2db7e675048ea2d525b415abfa02094df35960facc464736f6c63430008140033

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

000000000000000000000000000000000000000000000000000000000064c627

-----Decoded View---------------
Arg [0] : _lpPositionId (uint256): 6604327

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000000000000000000064c627


Block Transaction Gas Used Reward
view all blocks produced
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
View All Validatorset

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
Loading...
Loading
[ Download: CSV Export  ]

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