ETH Price: $1,913.84 (+4.76%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Fee Rates190610152024-01-22 8:13:35765 days ago1705911215IN
0x6caecA3C...2e0dd8763
0 ETH0.0095157666.59688976
Set Fee Rates190610022024-01-22 8:10:59765 days ago1705911059IN
0x6caecA3C...2e0dd8763
0 ETH0.0111515961.05042997
Set Fee Rates190609822024-01-22 8:06:59765 days ago1705910819IN
0x6caecA3C...2e0dd8763
0 ETH0.0096622252.89672485
Set Fee Rates190609622024-01-22 8:02:59765 days ago1705910579IN
0x6caecA3C...2e0dd8763
0 ETH0.0091889150.308845

Advanced mode:
Parent Transaction Hash Method Block
From
To
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LpLocker

Compiler Version
v0.8.22+commit.4fc1097e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "contracts/IUniswapV2Factory.sol";
import "contracts/INonfungiblePositionManager.sol";

contract LpLocker is ReentrancyGuard {
    address public owner;
    bool public pause;

    constructor(){
        owner = msg.sender;
        pause = false;
        //添加uniV2
        bytes memory _dex = bytes("uniswap");
        bytes memory _ver = bytes("v2");
        LpAddrsSet[_dex][_ver] = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
        emit SetFactoryAddress(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f, "uniswap", "v2");

        // 添加uniV3
        _dex = bytes("uniswap");
        _ver = bytes("v3");
        LpAddrsSet[_dex][_ver] = 0x1F98431c8aD98523631AE4a59f267346ea31F984;
        emit SetFactoryAddress(0x1F98431c8aD98523631AE4a59f267346ea31F984, "uniswap", "v3");
    }

    receive() external payable {}

    uint256 constant public PERCENT_DENOM = 1000;
    string constant public LP_V2 = "v2";
    string constant public LP_V3 = "v3";

    enum LockType {
        FixTokenLock,
        LinearTokenLock,
        LpV2Lock,
        LpV3Lock
    }

    enum LockerStatus {
        Locked,
        PendingRelease,
        Release
    }

    mapping (address => uint256) public IncomeSet;
    mapping (LockType => FeeRates) public FeesSet;
    mapping (address => mapping (bytes32 => LockerUnit)) public LockerSet;
    mapping (bytes => mapping (bytes => address)) public LpAddrsSet;

    struct FeeRates {
        bool created;
        uint256 lockOp;
        uint256 relockOp;
        uint256 transferOp;
        uint256 increaseOp;
        uint256 splitOp;
        uint256 extractOp;
    }

    struct LockerUnit {
        address owner;
        address token;
        string setName;
        uint256 lockAmount;
        uint256 cumulateClaimed;
        uint256 startTime;
        uint256 endTime;
        string dex;
        uint256 nftId;
        uint256 releasePerSecond;
        bool withdrawed;
        LockType lockType;
        LockerStatus status;
    }

    event SetNewOwner(
        address newOwner,
        address oldOwner
    );

    event SetFeeRates(
        LockType lockType,
        uint256 lockOp,
        uint256 relockOp,
        uint256 transferOp,
        uint256 increaseOp,
        uint256 splitOp,
        uint256 extractOp
    );

    event ExtractFees(
        address token,
        string feeType,
        uint256 amount
    );

    event IncreaseIncome(
        address token,
        uint256 amount
    );

    event DecreasetIncome(
        address token,
        uint256 amount
    );

    event CreateTokenLocker(
        bytes32 id,
        address token,
        string setName,
        address forWho,
        uint256 lockAmount,
        uint256 startTime,
        uint256 endTime,
        uint256 releasePerSecond,
        LockType lockType
    );

    event CreateLpLocker(
        bytes32 id,
        address token,
        string setName,
        address forWho,
        uint256 lockAmount,
        uint256 nftId,
        uint256 startTime,
        uint256 endTime,
        string dex,
        LockType lockType
    );

    event SetFactoryAddress(
        address addr,
        string dex,
        string version
    );

    event WithdrawToken(
        bytes32 lockId,
        uint256 amount,
        bool clearAll,
        LockType lockType
    );

    event TransferOwnership(
        address oldOwner,
        address newOwner,
        bytes32 oldLockId,
        bytes32 newLockId,
        string newSetName
    );

    event Relock(
        bytes32 lockId,
        uint256 timeUnix,
        LockType lockType
    );

    event IncreaseLockAmount(
        bytes32 lockId,
        address tokenAddr,
        uint256 lockAmount,
        LockType lockType
    );

    event SplitLocker(
        bytes32 originLockId,
        uint256 originLeftAmount,
        uint256 originRelease,
        bytes32 spliteLockId,
        uint256 splitAmount,
        uint256 splitRelease,
        string splitSetName,
        LockType lockType
    );

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

    modifier enablePause() {
        require(!pause, "Contract is paused");
        _;
    }

    function setNewOwner(address newOwner) public onlyOwner {
        owner = newOwner;

        emit SetNewOwner(newOwner, msg.sender);
    }

    function setPause(bool newStatus) public onlyOwner {
        pause = newStatus;
    }

    function setFactoryAddress(
        address addr, 
        string memory dex,
        string memory version
    ) public onlyOwner {
        bytes memory _dex = bytes(dex);
        bytes memory _ver = bytes(version);

        LpAddrsSet[_dex][_ver] = addr;

        emit SetFactoryAddress(addr, dex, version);
    }

    function getFactoryAddress(string memory dex, string memory version) public view returns(address) {
        bytes memory _dex = bytes(dex);
        bytes memory _ver = bytes(version);

        return LpAddrsSet[_dex][_ver];
    }

    function setFeeRates(
        LockType _type,
        uint256 lockOp,
        uint256 relockOp,
        uint256 transferOp,
        uint256 increaseOp,
        uint256 splitOp,
        uint256 extractOp
    ) public onlyOwner {
        FeeRates storage feeRates = FeesSet[_type];

        feeRates.created = true;
        feeRates.lockOp = lockOp;
        feeRates.relockOp = relockOp;
        feeRates.transferOp = transferOp;
        feeRates.increaseOp = increaseOp;
        feeRates.splitOp = splitOp;
        feeRates.extractOp = extractOp;

        emit SetFeeRates(_type, lockOp, relockOp, transferOp, increaseOp, splitOp, extractOp);
    }

    function isExistFeeRates(LockType _type) public view returns(bool) {
        return FeesSet[_type].created;
    }

    function getFeeRates(LockType _type) public view returns(FeeRates memory ) {
        return  FeesSet[_type];
    }

    function extractFees(address _token, uint256 amount) public onlyOwner {
        require(amount > 0, "Invalid extract amount");
       
        string memory _type;
        if (_token != address(0)) {
            require(amount <= IERC20(_token).balanceOf(address(this)), "Exceed the ERC20 balance");

            IncomeSet[_token] -= amount;
            _type = "ERC20";
            
            IERC20(_token).transfer(msg.sender, amount);
        } else {
            require(amount <= address(this).balance, "Exceed the ETH balance");
            
            IncomeSet[_token] -= amount;
            _type = "ETH";

            payable(msg.sender).transfer(amount); 
        }

        emit ExtractFees(_token, _type, amount);
    }

    function balanceOfFees(address _token) public view returns(uint256){
        return IncomeSet[_token];
    }

    function generateLockID(
        address tokenAddr, 
        address _owner, 
        string memory setName
    ) public pure returns(bytes32) {
        return keccak256(
            abi.encodePacked(
                tokenAddr, 
                _owner, 
                setName
            )
        );
    }

    function isExistLockID(
        address tokenAddr, 
        address _owner, 
        string memory setName
    ) public view returns(bool) {
        bytes32 id = generateLockID(tokenAddr, _owner, setName);
        LockerUnit storage unit = LockerSet[msg.sender][id];
        if (unit.owner == address(0)) return false;

        return true;
    }

    function withdrawAvaible(bytes32 lockId, address _owner) public view returns(uint256) {
        LockerUnit storage lockUnit = LockerSet[_owner][lockId];
        if(lockUnit.owner != _owner) return 0;

        uint256 startTime = lockUnit.startTime;
        uint256 endTime = lockUnit.endTime;
        uint256 nowUnix = block.timestamp;

        uint256 withdrawAmount;
        if(lockUnit.lockType == LockType.LinearTokenLock) {
            if(nowUnix > endTime) nowUnix = endTime;
            
            withdrawAmount = (nowUnix - startTime) *
                     lockUnit.releasePerSecond -
                      lockUnit.cumulateClaimed;

        } else if(lockUnit.lockType == LockType.LpV3Lock) {
            if(nowUnix <= endTime) return  0;
            withdrawAmount = 1;
        } else {
            if(nowUnix <= endTime) return  0;
            withdrawAmount = lockUnit.lockAmount;
        }

        return withdrawAmount;
    }

    function createTokenLocker(
        address tokenAddr,
        uint256 lockAmount,
        string memory setName,
        address forWho,
        uint256 endTime,
        LockType _type
    ) external nonReentrant enablePause {
        require(isExistFeeRates(_type), "Set up fee rates");
        require(forWho != address(0), "Not support zero address");
        require(bytes(setName).length > 0, "Value of setName must be set");
        require(_type == LockType.FixTokenLock || _type == LockType.LinearTokenLock, "Invalid token locker type");
        require(lockAmount <= IERC20(tokenAddr).balanceOf(msg.sender), "Not enough balance");
        require(!isExistLockID(tokenAddr, forWho, setName), "Locker ID already exist, how about use other name");

        uint256 nowUnix = block.timestamp;
        require(endTime > nowUnix, "Invalid unix end time");

        bytes32 lockId = generateLockID(tokenAddr, forWho, setName);
        
        FeeRates storage feeRates = FeesSet[_type];
        uint256 leftAmount = lockAmount - lockAmount * feeRates.lockOp / PERCENT_DENOM;
        IncomeSet[tokenAddr] += lockAmount * feeRates.lockOp / PERCENT_DENOM;

        uint256 _releaseAmount;
        if(_type == LockType.LinearTokenLock) _releaseAmount = leftAmount / (endTime - nowUnix);

        LockerUnit storage lockUnit = LockerSet[forWho][lockId];
        lockUnit.owner = forWho;
        lockUnit.token = tokenAddr;
        lockUnit.setName = setName;
        lockUnit.lockAmount = leftAmount;
        lockUnit.startTime = nowUnix;
        lockUnit.endTime = endTime;
        lockUnit.releasePerSecond = _releaseAmount;
        lockUnit.lockType = _type;
        lockUnit.withdrawed = false;

        if (_type == LockType.FixTokenLock) {
            lockUnit.status = LockerStatus.Locked;
        } else {
            lockUnit.status = LockerStatus.PendingRelease;
        }

        IERC20(tokenAddr).transferFrom(msg.sender, address(this), lockAmount);

        emit CreateTokenLocker(
            lockId, tokenAddr, setName, 
            forWho, leftAmount, 
            nowUnix, endTime, 
            _releaseAmount, _type
        );
    }

    function createLpLocker(
        address tokenAddr,
        address token0,
        address token1,
        uint256 lockAmount,
        uint256 nftId,
        string memory setName,
        address forWho,
        uint256 endTime,
        string memory dex,
        LockType _type
    ) external payable enablePause nonReentrant {
        require(isExistFeeRates(_type), "Set up fee rates");
        require(forWho != address(0), "Not support zero address");
        require(bytes(setName).length > 0, "Value of setName must be set");
        require(!isExistLockID(tokenAddr, forWho, setName), "Locker ID already exist, how about use other name");

        uint256 nowUnix = block.timestamp;
        require(endTime > nowUnix, "Invalid unix end time");

        FeeRates storage feeRates = FeesSet[_type];
        if (_type == LockType.LpV2Lock) {
            require(lockAmount <= IERC20(tokenAddr).balanceOf(msg.sender), "Not enough balance");

            address factory = getFactoryAddress(dex, LP_V2);
            require(factory != address(0), "Invalid dex value");

            require(tokenAddr == IUniswapV2Factory(factory).getPair(token0, token1), "Illegal LP V2 token address");

            IncomeSet[tokenAddr] += lockAmount * feeRates.lockOp / PERCENT_DENOM;

            IERC20(tokenAddr).transferFrom(msg.sender, address(this), lockAmount);
        } else if (_type == LockType.LpV3Lock) {
            require(msg.value >= feeRates.lockOp,"Not enough fee");
            require(
                INonfungiblePositionManager(tokenAddr).ownerOf(nftId) == msg.sender, 
                "Invalid V3 liquidity nft owner"
            );

            (, ,address _token0, address _token1,,,,,,,, ) = INonfungiblePositionManager(tokenAddr).positions(nftId);
            require(token0 == _token0, "Invalid token0");
            require(token1 == _token1, "Invalid token1");

            IncomeSet[address(0)] +=  msg.value;

            INonfungiblePositionManager(tokenAddr).transferFrom(msg.sender, address(this), nftId);
        } else {
            revert("Invalid locker type");
        }

        bytes32 lockId = generateLockID(tokenAddr, forWho, setName);
        LockerUnit storage lockUnit = LockerSet[forWho][lockId];
        lockUnit.owner = forWho;
        lockUnit.token = tokenAddr;
        lockUnit.setName = setName;
        lockUnit.lockAmount = _type == LockType.LpV3Lock ? 1 : lockAmount - lockAmount * feeRates.lockOp / PERCENT_DENOM;
        lockUnit.cumulateClaimed = 0;
        lockUnit.startTime = nowUnix;
        lockUnit.endTime = endTime;
        lockUnit.dex = dex;
        lockUnit.nftId = nftId;
        lockUnit.lockType = _type;
        lockUnit.status = LockerStatus.Locked;
        lockUnit.withdrawed = false;

        emit CreateLpLocker(
            lockId, tokenAddr, setName, 
            forWho, lockUnit.lockAmount, nftId, nowUnix, 
            endTime, dex, _type
        );
    }

    function withdrawToken(
        bytes32 lockId
    ) external payable nonReentrant {
        LockerUnit storage lockUnit = LockerSet[msg.sender][lockId];
        require(!lockUnit.withdrawed, "Can not withdraw repeatedly");

        require(isExistFeeRates(lockUnit.lockType), "Set up fee rates");
        require(msg.sender == lockUnit.owner, "Invalid locker owner");

        FeeRates storage feeRates = FeesSet[lockUnit.lockType];
        if (lockUnit.lockType == LockType.LpV3Lock) {
            require(msg.value >= feeRates.extractOp, "Not enough fee of extract");
        }

        uint256 withdrawAmount;
        if(lockUnit.lockType == LockType.LpV3Lock) {
            require(withdrawAvaible(lockId, msg.sender) > 0, "Can not withdraw before expiration");

            lockUnit.withdrawed = true;
            withdrawAmount = 1;

            IncomeSet[address(0)] += msg.value;

            IERC721(lockUnit.token).transferFrom(address(this), lockUnit.owner, lockUnit.nftId);
        } else {
            uint256 amount = withdrawAvaible(lockId, msg.sender);
            require(amount > 0, "Can not withdraw before expiration");

            lockUnit.cumulateClaimed += amount;

            if(lockUnit.lockType == LockType.LinearTokenLock) {
                if(withdrawAvaible(lockId, msg.sender) == 0) lockUnit.withdrawed = true;
            } else {
                lockUnit.withdrawed = true;
            }

            uint256 fee = amount * feeRates.extractOp / PERCENT_DENOM;
            uint256 leftAmount = amount-fee;

            IERC20(lockUnit.token).transfer(msg.sender, leftAmount);
            
            IncomeSet[lockUnit.token] += fee;

            withdrawAmount = leftAmount;
        }
        
        emit WithdrawToken(lockId, withdrawAmount, lockUnit.withdrawed ,lockUnit.lockType);
    }

    function transferOwnership(
        bytes32 lockId,
        address newOwner,
        string memory newSetName
    ) external payable nonReentrant {
        LockerUnit storage lockUnit = LockerSet[msg.sender][lockId];

        require(!lockUnit.withdrawed, "Lock already unlocked");
        
        require(msg.sender == lockUnit.owner, "Invalid locker owner");
        require(isExistFeeRates(lockUnit.lockType), "Set up fee rates");

        require(!isExistLockID(lockUnit.token, newOwner, newSetName), "Locker ID already exist, how about use other name");

        FeeRates storage feeRates = FeesSet[lockUnit.lockType];
        require(msg.value >= feeRates.transferOp, "Not enough fee for transfer");

        bytes32 newID = generateLockID(lockUnit.token, newOwner, newSetName);
        lockUnit.owner = newOwner;
        LockerSet[newOwner][newID] = lockUnit;

        delete LockerSet[msg.sender][lockId];

        IncomeSet[address(0)] += msg.value;

        emit TransferOwnership(msg.sender, newOwner, lockId, newID, newSetName);
    }

    function relock(
        bytes32 lockId,
        uint256 timeUnix
    ) external payable enablePause nonReentrant {
        LockerUnit storage lockUnit = LockerSet[msg.sender][lockId];

        require(!lockUnit.withdrawed, "Lock already unlocked");

        require(msg.sender == lockUnit.owner, "Invalid locker owner");
        require(isExistFeeRates(lockUnit.lockType), "Set up fee rates");

        FeeRates storage feeRates = FeesSet[lockUnit.lockType];

        require(msg.value >= feeRates.relockOp, "Not enough fee of relock");
        require(timeUnix > lockUnit.endTime, "New timestamp must bigger than old");

        if (lockUnit.lockType == LockType.LinearTokenLock) {
            lockUnit.releasePerSecond = (lockUnit.lockAmount-lockUnit.cumulateClaimed) / (timeUnix - lockUnit.startTime);
        }

        lockUnit.endTime = timeUnix;

        IncomeSet[address(0)] += msg.value;

        emit Relock(lockId, timeUnix, lockUnit.lockType);
    }

    function increaseLockAmount(
        bytes32 lockId,
        address tokenAddr,
        uint256 increaseAmount
    ) external enablePause nonReentrant {
        LockerUnit storage lockUnit = LockerSet[msg.sender][lockId];

        require(!lockUnit.withdrawed, "Lock already unlocked");

        require(msg.sender == lockUnit.owner, "Invalid locker owner");
        require(isExistFeeRates(lockUnit.lockType), "Set up fee rates");
        require(lockUnit.lockType != LockType.LpV3Lock, "Not support LP V3 token");
        require(increaseAmount > 0, "Must be large than 0");

        FeeRates storage feeRates = FeesSet[lockUnit.lockType];
        uint256 fee = increaseAmount * feeRates.increaseOp / PERCENT_DENOM;
        IncomeSet[tokenAddr] += fee;

        uint256 leftAmount = increaseAmount - fee;
        lockUnit.lockAmount += leftAmount;

        if (lockUnit.lockType == LockType.LinearTokenLock) {
            lockUnit.releasePerSecond = (lockUnit.lockAmount-lockUnit.cumulateClaimed) / (lockUnit.endTime - lockUnit.startTime);
        }

        IERC20(tokenAddr).transferFrom(msg.sender, address(this), increaseAmount);

        emit IncreaseLockAmount(lockId, tokenAddr, leftAmount, lockUnit.lockType);
    }

    function splitLocker(
        bytes32 lockId,
        address tokenAddr,
        uint256 splitAmount,
        string memory splitSetName
    ) external payable enablePause nonReentrant {
        LockerUnit storage lockUnit = LockerSet[msg.sender][lockId];

        require(!lockUnit.withdrawed, "Lock already unlocked");

        require(msg.sender == lockUnit.owner, "Invalid locker owner");
        require(isExistFeeRates(lockUnit.lockType), "Set up fee rates");
        require(lockUnit.lockType != LockType.LpV3Lock, "Not support LP V3 token");
        require(tokenAddr == lockUnit.token, "Invalid token address");
        require(!isExistLockID(lockUnit.token, lockUnit.owner, splitSetName), "Locker ID already exist, how about use other name");

        FeeRates storage feeRates = FeesSet[lockUnit.lockType];

        require(msg.value >= feeRates.splitOp, "Not enough splitOp fee");
        require(splitAmount < lockUnit.lockAmount, "Split amount is larger than lock amount");

        bytes32 splitLockId = generateLockID(tokenAddr, msg.sender, splitSetName);
        LockerUnit storage lockUnit2 = LockerSet[msg.sender][splitLockId];
        lockUnit2.owner = lockUnit.owner;
        lockUnit2.token = lockUnit.token;
        lockUnit2.setName = lockUnit.setName;
        lockUnit2.startTime = lockUnit.startTime;
        lockUnit2.endTime = lockUnit.endTime;
        lockUnit2.dex = lockUnit.dex;
        lockUnit2.releasePerSecond = lockUnit.releasePerSecond * splitAmount / lockUnit.lockAmount;
        lockUnit2.lockType = lockUnit.lockType;
        lockUnit2.lockAmount = splitAmount;
        lockUnit2.withdrawed = false;

        if (lockUnit.lockType == LockType.LinearTokenLock) {
            lockUnit2.cumulateClaimed = lockUnit.cumulateClaimed * splitAmount / lockUnit.lockAmount;
        } else {
            lockUnit2.cumulateClaimed = lockUnit.cumulateClaimed;
        }

        lockUnit.lockAmount -= splitAmount;
        lockUnit.cumulateClaimed -= lockUnit2.cumulateClaimed;
        lockUnit.releasePerSecond -= lockUnit2.releasePerSecond;

        IncomeSet[address(0)] += msg.value;

        emit SplitLocker(lockId, lockUnit.lockAmount, lockUnit.releasePerSecond, splitLockId, splitAmount, lockUnit2.releasePerSecond, splitSetName, lockUnit.lockType);
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";

interface IPoolInitializer {
    function createAndInitializePoolIfNecessary(
        address token0,
        address token1,
        uint24 fee,
        uint160 sqrtPriceX96
    ) external payable returns (address pool);
}

interface IERC721Permit is IERC721 {
    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function permit(
        address spender,
        uint256 tokenId,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external payable;
}

interface IPeripheryPayments {
    function unwrapWETH9(uint256 amountMinimum, address recipient) external payable;

    function refundETH() external payable;

    function sweepToken(
        address token,
        uint256 amountMinimum,
        address recipient
    ) external payable;
}

interface IPeripheryImmutableState {
    function factory() external view returns (address);

    function WETH9() external view returns (address);
}

// library PoolAddress {
//     bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;

//     // /// @notice The identifying key of the pool
//     // struct PoolKey {
//     //     address token0;
//     //     address token1;
//     //     uint24 fee;
//     // }

//     /// @notice Returns PoolKey: the ordered tokens with the matched fee levels
//     /// @param tokenA The first token of a pool, unsorted
//     /// @param tokenB The second token of a pool, unsorted
//     /// @param fee The fee level of the pool
//     /// @return Poolkey The pool details with ordered token0 and token1 assignments
//     // function getPoolKey(
//     //     address tokenA,
//     //     address tokenB,
//     //     uint24 fee
//     // ) internal pure returns (PoolKey memory) {
//     //     if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
//     //     return PoolKey({token0: tokenA, token1: tokenB, fee: fee});
//     // }

//     // /// @notice Deterministically computes the pool address given the factory and PoolKey
//     // /// @param factory The Uniswap V3 factory contract address
//     // /// @param key The PoolKey
//     // /// @return pool The contract address of the V3 pool
//     // function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {
//     //     require(key.token0 < key.token1);
//     //     pool = address(
//     //         uint256(
//     //             keccak256(
//     //                 abi.encodePacked(
//     //                     hex'ff',
//     //                     factory,
//     //                     keccak256(abi.encode(key.token0, key.token1, key.fee)),
//     //                     POOL_INIT_CODE_HASH
//     //                 )
//     //             )
//     //         )
//     //     );
//     // }
// }


interface INonfungiblePositionManager is
    IPoolInitializer,
    IPeripheryPayments,
    IPeripheryImmutableState,
    IERC721Metadata,
    IERC721Enumerable,
    IERC721Permit
{
    event IncreaseLiquidity(uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);
    event DecreaseLiquidity(uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);
    event Collect(uint256 indexed tokenId, address recipient, 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
        );

    struct MintParams {
        address token0;
        address token1;
        uint24 fee;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
    }

    function mint(MintParams calldata params)
        external
        payable
        returns (
            uint256 tokenId,
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        );

    struct IncreaseLiquidityParams {
        uint256 tokenId;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }
    
    function increaseLiquidity(IncreaseLiquidityParams calldata params)
        external
        payable
        returns (
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        );

    struct DecreaseLiquidityParams {
        uint256 tokenId;
        uint128 liquidity;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    function decreaseLiquidity(DecreaseLiquidityParams calldata params)
        external
        payable
        returns (uint256 amount0, uint256 amount1);

    struct CollectParams {
        uint256 tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }

    function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1);

    function burn(uint256 tokenId) external payable;
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

interface IUniswapV2Factory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}

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

pragma solidity ^0.8.20;

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

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

    /**
     * @dev Returns the 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 v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @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 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;

    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
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // 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.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.20;

import {IERC721} from "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.20;

import {IERC721} from "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.20;

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

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
     *   a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
     *   {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
     *   a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the address zero.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

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

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * 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[EIP 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"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"string","name":"setName","type":"string"},{"indexed":false,"internalType":"address","name":"forWho","type":"address"},{"indexed":false,"internalType":"uint256","name":"lockAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"string","name":"dex","type":"string"},{"indexed":false,"internalType":"enum LpLocker.LockType","name":"lockType","type":"uint8"}],"name":"CreateLpLocker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"string","name":"setName","type":"string"},{"indexed":false,"internalType":"address","name":"forWho","type":"address"},{"indexed":false,"internalType":"uint256","name":"lockAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"releasePerSecond","type":"uint256"},{"indexed":false,"internalType":"enum LpLocker.LockType","name":"lockType","type":"uint8"}],"name":"CreateTokenLocker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DecreasetIncome","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"string","name":"feeType","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ExtractFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"IncreaseIncome","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"lockId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"tokenAddr","type":"address"},{"indexed":false,"internalType":"uint256","name":"lockAmount","type":"uint256"},{"indexed":false,"internalType":"enum LpLocker.LockType","name":"lockType","type":"uint8"}],"name":"IncreaseLockAmount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"lockId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"timeUnix","type":"uint256"},{"indexed":false,"internalType":"enum LpLocker.LockType","name":"lockType","type":"uint8"}],"name":"Relock","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"string","name":"dex","type":"string"},{"indexed":false,"internalType":"string","name":"version","type":"string"}],"name":"SetFactoryAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"enum LpLocker.LockType","name":"lockType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"lockOp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"relockOp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"transferOp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"increaseOp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"splitOp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"extractOp","type":"uint256"}],"name":"SetFeeRates","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"},{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"}],"name":"SetNewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"originLockId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"originLeftAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"originRelease","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"spliteLockId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"splitAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"splitRelease","type":"uint256"},{"indexed":false,"internalType":"string","name":"splitSetName","type":"string"},{"indexed":false,"internalType":"enum LpLocker.LockType","name":"lockType","type":"uint8"}],"name":"SplitLocker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"},{"indexed":false,"internalType":"bytes32","name":"oldLockId","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"newLockId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"newSetName","type":"string"}],"name":"TransferOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"lockId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"clearAll","type":"bool"},{"indexed":false,"internalType":"enum LpLocker.LockType","name":"lockType","type":"uint8"}],"name":"WithdrawToken","type":"event"},{"inputs":[{"internalType":"enum LpLocker.LockType","name":"","type":"uint8"}],"name":"FeesSet","outputs":[{"internalType":"bool","name":"created","type":"bool"},{"internalType":"uint256","name":"lockOp","type":"uint256"},{"internalType":"uint256","name":"relockOp","type":"uint256"},{"internalType":"uint256","name":"transferOp","type":"uint256"},{"internalType":"uint256","name":"increaseOp","type":"uint256"},{"internalType":"uint256","name":"splitOp","type":"uint256"},{"internalType":"uint256","name":"extractOp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"IncomeSet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LP_V2","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LP_V3","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"LockerSet","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"string","name":"setName","type":"string"},{"internalType":"uint256","name":"lockAmount","type":"uint256"},{"internalType":"uint256","name":"cumulateClaimed","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"string","name":"dex","type":"string"},{"internalType":"uint256","name":"nftId","type":"uint256"},{"internalType":"uint256","name":"releasePerSecond","type":"uint256"},{"internalType":"bool","name":"withdrawed","type":"bool"},{"internalType":"enum LpLocker.LockType","name":"lockType","type":"uint8"},{"internalType":"enum LpLocker.LockerStatus","name":"status","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"LpAddrsSet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENT_DENOM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"balanceOfFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddr","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint256","name":"lockAmount","type":"uint256"},{"internalType":"uint256","name":"nftId","type":"uint256"},{"internalType":"string","name":"setName","type":"string"},{"internalType":"address","name":"forWho","type":"address"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"string","name":"dex","type":"string"},{"internalType":"enum LpLocker.LockType","name":"_type","type":"uint8"}],"name":"createLpLocker","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddr","type":"address"},{"internalType":"uint256","name":"lockAmount","type":"uint256"},{"internalType":"string","name":"setName","type":"string"},{"internalType":"address","name":"forWho","type":"address"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"enum LpLocker.LockType","name":"_type","type":"uint8"}],"name":"createTokenLocker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"extractFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddr","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"string","name":"setName","type":"string"}],"name":"generateLockID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"dex","type":"string"},{"internalType":"string","name":"version","type":"string"}],"name":"getFactoryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum LpLocker.LockType","name":"_type","type":"uint8"}],"name":"getFeeRates","outputs":[{"components":[{"internalType":"bool","name":"created","type":"bool"},{"internalType":"uint256","name":"lockOp","type":"uint256"},{"internalType":"uint256","name":"relockOp","type":"uint256"},{"internalType":"uint256","name":"transferOp","type":"uint256"},{"internalType":"uint256","name":"increaseOp","type":"uint256"},{"internalType":"uint256","name":"splitOp","type":"uint256"},{"internalType":"uint256","name":"extractOp","type":"uint256"}],"internalType":"struct LpLocker.FeeRates","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"lockId","type":"bytes32"},{"internalType":"address","name":"tokenAddr","type":"address"},{"internalType":"uint256","name":"increaseAmount","type":"uint256"}],"name":"increaseLockAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum LpLocker.LockType","name":"_type","type":"uint8"}],"name":"isExistFeeRates","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddr","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"string","name":"setName","type":"string"}],"name":"isExistLockID","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"lockId","type":"bytes32"},{"internalType":"uint256","name":"timeUnix","type":"uint256"}],"name":"relock","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"string","name":"dex","type":"string"},{"internalType":"string","name":"version","type":"string"}],"name":"setFactoryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum LpLocker.LockType","name":"_type","type":"uint8"},{"internalType":"uint256","name":"lockOp","type":"uint256"},{"internalType":"uint256","name":"relockOp","type":"uint256"},{"internalType":"uint256","name":"transferOp","type":"uint256"},{"internalType":"uint256","name":"increaseOp","type":"uint256"},{"internalType":"uint256","name":"splitOp","type":"uint256"},{"internalType":"uint256","name":"extractOp","type":"uint256"}],"name":"setFeeRates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newStatus","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"lockId","type":"bytes32"},{"internalType":"address","name":"tokenAddr","type":"address"},{"internalType":"uint256","name":"splitAmount","type":"uint256"},{"internalType":"string","name":"splitSetName","type":"string"}],"name":"splitLocker","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"lockId","type":"bytes32"},{"internalType":"address","name":"newOwner","type":"address"},{"internalType":"string","name":"newSetName","type":"string"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"lockId","type":"bytes32"},{"internalType":"address","name":"_owner","type":"address"}],"name":"withdrawAvaible","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"lockId","type":"bytes32"}],"name":"withdrawToken","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405234801562000010575f80fd5b5060015f81905580546001600160a81b0319163360ff60a01b191617905560408051808201825260078152660756e69737761760cc1b6020808301919091528251808401845260028152613b1960f11b918101919091529151909190735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f906005906200009290859062000274565b908152602001604051809103902082604051620000b0919062000274565b908152604080516020928190038301812080546001600160a01b0319166001600160a01b039590951694909417909355735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f83526060918301829052600791830191909152660756e69737761760cc1b608083015260a0908201819052600290820152613b1960f11b60c08201525f80516020620044d48339815191529060e00160405180910390a1604051806040016040528060078152602001660756e69737761760cc1b815250915060405180604001604052806002815260200161763360f01b8152509050731f98431c8ad98523631ae4a59f267346ea31f984600583604051620001b2919062000274565b908152602001604051809103902082604051620001d0919062000274565b908152604080516020928190038301812080546001600160a01b0319166001600160a01b039590951694909417909355731f98431c8ad98523631ae4a59f267346ea31f98483526060918301829052600791830191909152660756e69737761760cc1b608083015260a090820181905260029082015261763360f01b60c08201525f80516020620044d48339815191529060e00160405180910390a15050620002a2565b5f82515f5b8181101562000295576020818601810151858301520162000279565b505f920191825250919050565b61422480620002b05f395ff3fe6080604052600436106101b2575f3560e01c806380938ce4116100e7578063c2c90c8d11610087578063ebad839711610062578063ebad8397146105fb578063f5a1f5b41461060e578063f64d08d61461062d578063f7674d6314610665575f80fd5b8063c2c90c8d14610552578063d986ad591461057f578063e70af3351461059e575f80fd5b80639c6da83d116100c25780639c6da83d146104ee578063a6dd767d14610501578063b8b3ae5014610514578063bedb86fb14610533575f80fd5b806380938ce4146104295780638456cb591461049f5780638da5cb5b146104cf575f80fd5b806348d2ca941161015257806361b340581161012d57806361b340581461039e5780636860292c146103bd5780636f75d7f5146103d05780637ba0f0dd146103ef575f80fd5b806348d2ca94146102a1578063498a0bc0146102d55780635650ad5114610367575f80fd5b80630846e7eb1161018d5780630846e7eb146102255780631c8a3be414610244578063265cc77e1461026f5780633d607a4014610282575f80fd5b80630153f84c146101bd5780630441f773146101ef5780630452096b14610210575f80fd5b366101b957005b5f80fd5b3480156101c8575f80fd5b506101dc6101d736600461339f565b610684565b6040519081526020015b60405180910390f35b3480156101fa575f80fd5b5061020e61020936600461340b565b6106ba565b005b34801561021b575f80fd5b506101dc6103e881565b348015610230575f80fd5b5061020e61023f36600461348b565b610bf2565b34801561024f575f80fd5b506101dc61025e3660046134f2565b60026020525f908152604090205481565b61020e61027d36600461350d565b610cbf565b34801561028d575f80fd5b5061020e61029c36600461352d565b610f66565b3480156102ac575f80fd5b506101dc6102bb3660046134f2565b6001600160a01b03165f9081526002602052604090205490565b3480156102e0575f80fd5b506103306102ef36600461357b565b600360208190525f9182526040909120805460018201546002830154938301546004840154600585015460069095015460ff90941695929492939192909187565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016101e6565b348015610372575f80fd5b50610386610381366004613594565b61104d565b6040516001600160a01b0390911681526020016101e6565b3480156103a9575f80fd5b506101dc6103b83660046135f4565b6110a4565b61020e6103cb366004613622565b6111b0565b3480156103db575f80fd5b5061020e6103ea366004613681565b6116bb565b3480156103fa575f80fd5b5061041c60405180604001604052806002815260200161763360f01b81525081565b6040516101e69190613703565b348015610434575f80fd5b5061044861044336600461357b565b611a1a565b6040516101e691905f60e0820190508251151582526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015292915050565b3480156104aa575f80fd5b506001546104bf90600160a01b900460ff1681565b60405190151581526020016101e6565b3480156104da575f80fd5b50600154610386906001600160a01b031681565b61020e6104fc366004613715565b611ae3565b61020e61050f366004613739565b611eba565b34801561051f575f80fd5b5061020e61052e366004613750565b61231b565b34801561053e575f80fd5b5061020e61054d366004613787565b61260c565b34801561055d575f80fd5b5061041c604051806040016040528060028152602001613b1960f11b81525081565b34801561058a575f80fd5b506104bf61059936600461339f565b612654565b3480156105a9575f80fd5b506103866105b8366004613594565b815160208184018101805160058252928201948201949094209190935281518083018401805192815290840192909301919091209152546001600160a01b031681565b61020e6106093660046137a2565b6126a3565b348015610619575f80fd5b5061020e6106283660046134f2565b612fed565b348015610638575f80fd5b5061064c610647366004613750565b613070565b6040516101e69d9c9b9a999897969594939291906138a8565b348015610670575f80fd5b506104bf61067f36600461357b565b6131fd565b5f83838360405160200161069a93929190613946565b6040516020818303038152906040528051906020012090505b9392505050565b6106c261323d565b600154600160a01b900460ff16156106f55760405162461bcd60e51b81526004016106ec9061398b565b60405180910390fd5b6106fe816131fd565b61071a5760405162461bcd60e51b81526004016106ec906139b7565b6001600160a01b03831661076b5760405162461bcd60e51b81526020600482015260186024820152774e6f7420737570706f7274207a65726f206164647265737360401b60448201526064016106ec565b5f8451116107bb5760405162461bcd60e51b815260206004820152601c60248201527f56616c7565206f66207365744e616d65206d757374206265207365740000000060448201526064016106ec565b5f8160038111156107ce576107ce613870565b14806107eb575060018160038111156107e9576107e9613870565b145b6108375760405162461bcd60e51b815260206004820152601960248201527f496e76616c696420746f6b656e206c6f636b657220747970650000000000000060448201526064016106ec565b6040516370a0823160e01b81523360048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015610879573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089d91906139e1565b8511156108e15760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682062616c616e636560701b60448201526064016106ec565b6108ec868486612654565b156109095760405162461bcd60e51b81526004016106ec906139f8565b428083116109515760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420756e697820656e642074696d6560581b60448201526064016106ec565b5f61095d888688610684565b90505f60035f85600381111561097557610975613870565b600381111561098657610986613870565b81526020019081526020015f2090505f6103e882600101548a6109a99190613a5d565b6109b39190613a74565b6109bd908a613a93565b90506103e882600101548a6109d29190613a5d565b6109dc9190613a74565b6001600160a01b038b165f9081526002602052604081208054909190610a03908490613aa6565b909155505f90506001866003811115610a1e57610a1e613870565b03610a3a57610a2d8588613a93565b610a379083613a74565b90505b6001600160a01b038881165f818152600460209081526040808320898452909152902080546001600160a01b03199081169092178155600181018054909216928e1692909217905560028101610a908b82613b3c565b506003808201849055600582018790556006820189905560098201839055600a82018054899261ff001990911690610100908490811115610ad357610ad3613870565b0217905550600a8101805460ff191690555f876003811115610af757610af7613870565b03610b0f57600a8101805462ff000019169055610b23565b600a8101805462ff00001916620100001790555b8b6001600160a01b03166323b872dd33308e6040518463ffffffff1660e01b8152600401610b5393929190613bf8565b6020604051808303815f875af1158015610b6f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b939190613c1c565b507fc5325ed0db0a7daa50dd16b7349da163a487ebded0046afc5bc23f7581018418858d8c8c878b8e898f604051610bd399989796959493929190613c37565b60405180910390a1505050505050610bea60015f55565b505050505050565b6001546001600160a01b03163314610c1c5760405162461bcd60e51b81526004016106ec90613ca2565b604051829082908590600590610c33908590613cd1565b908152602001604051809103902082604051610c4f9190613cd1565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f46c25fd13b75a6950aa73e89e77d04e467880829db579a442248ed3d098a1d9f90610cb090879087908790613cec565b60405180910390a15050505050565b600154600160a01b900460ff1615610ce95760405162461bcd60e51b81526004016106ec9061398b565b610cf161323d565b335f9081526004602090815260408083208584529091529020600a81015460ff1615610d2f5760405162461bcd60e51b81526004016106ec90613d2b565b80546001600160a01b03163314610d585760405162461bcd60e51b81526004016106ec90613d5a565b600a810154610d6e90610100900460ff166131fd565b610d8a5760405162461bcd60e51b81526004016106ec906139b7565b5f60035f83600a0160019054906101000a900460ff166003811115610db157610db1613870565b6003811115610dc257610dc2613870565b81526020019081526020015f2090508060020154341015610e255760405162461bcd60e51b815260206004820152601860248201527f4e6f7420656e6f75676820666565206f662072656c6f636b000000000000000060448201526064016106ec565b81600601548311610e835760405162461bcd60e51b815260206004820152602260248201527f4e65772074696d657374616d70206d75737420626967676572207468616e206f6044820152611b1960f21b60648201526084016106ec565b6001600a830154610100900460ff166003811115610ea357610ea3613870565b03610edb576005820154610eb79084613a93565b82600401548360030154610ecb9190613a93565b610ed59190613a74565b60098301555b600682018390555f80805260026020525f805160206141cf8339815191528054349290610f09908490613aa6565b9091555050600a8201546040517f1397340e2d7027a973a29ee95161fece028c60c6481b25e47d5f8582a5ace6e091610f4f918791879161010090910460ff1690613d88565b60405180910390a15050610f6260015f55565b5050565b6001546001600160a01b03163314610f905760405162461bcd60e51b81526004016106ec90613ca2565b5f60035f896003811115610fa657610fa6613870565b6003811115610fb757610fb7613870565b8152602081019190915260409081015f20805460ff1916600190811782558101899055600281018890556003810187905560048101869055600581018590556006810184905590519091507fbef7735125feb4af2cc3ac99edddbed78eff28ecf0dd78b6f3a02b8545b10d839061103b908a908a908a908a908a908a908a90613dab565b60405180910390a15050505050505050565b6040515f9083908390600590611064908490613cd1565b9081526020016040518091039020816040516110809190613cd1565b908152604051908190036020019020546001600160a01b0316925050505b92915050565b6001600160a01b038082165f81815260046020908152604080832087845290915281208054919390929116146110dd575f91505061109e565b60058101546006820154425f6001600a860154610100900460ff16600381111561110957611109613870565b03611149578282111561111a578291505b6004850154600986015461112e8685613a93565b6111389190613a5d565b6111429190613a93565b90506111a5565b6003600a860154610100900460ff16600381111561116957611169613870565b0361118a57828211611182575f9550505050505061109e565b5060016111a5565b82821161119e575f9550505050505061109e565b5060038401545b979650505050505050565b600154600160a01b900460ff16156111da5760405162461bcd60e51b81526004016106ec9061398b565b6111e261323d565b335f9081526004602090815260408083208784529091529020600a81015460ff16156112205760405162461bcd60e51b81526004016106ec90613d2b565b80546001600160a01b031633146112495760405162461bcd60e51b81526004016106ec90613d5a565b600a81015461125f90610100900460ff166131fd565b61127b5760405162461bcd60e51b81526004016106ec906139b7565b6003600a820154610100900460ff16600381111561129b5761129b613870565b036112e25760405162461bcd60e51b81526020600482015260176024820152762737ba1039bab83837b93a102628102b19903a37b5b2b760491b60448201526064016106ec565b60018101546001600160a01b038581169116146113395760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420746f6b656e206164647265737360581b60448201526064016106ec565b60018101548154611357916001600160a01b03908116911684612654565b156113745760405162461bcd60e51b81526004016106ec906139f8565b5f60035f83600a0160019054906101000a900460ff16600381111561139b5761139b613870565b60038111156113ac576113ac613870565b81526020019081526020015f20905080600501543410156114085760405162461bcd60e51b81526020600482015260166024820152754e6f7420656e6f7567682073706c69744f702066656560501b60448201526064016106ec565b8160030154841061146b5760405162461bcd60e51b815260206004820152602760248201527f53706c697420616d6f756e74206973206c6172676572207468616e206c6f636b60448201526608185b5bdd5b9d60ca1b60648201526084016106ec565b5f611477863386610684565b335f9081526004602090815260408083208484529091529020845481546001600160a01b039182166001600160a01b031991821617835560018088015490840180549190931691161790559091506002808201906114d790860182613de9565b5060058085015490820155600680850154908201556007808201906114fe90860182613de9565b5083600301548685600901546115149190613a5d565b61151e9190613a74565b6009820155600a80850154908201805460ff61010093849004169261ff00199091169083600381111561155357611553613870565b021790555060038101869055600a8101805460ff191690556001600a850154610100900460ff16600381111561158b5761158b613870565b036115b95783600301548685600401546115a59190613a5d565b6115af9190613a74565b60048201556115c4565b600480850154908201555b85846003015f8282546115d79190613a93565b925050819055508060040154846004015f8282546115f59190613a93565b925050819055508060090154846009015f8282546116139190613a93565b90915550505f80805260026020525f805160206141cf833981519152805434929061163f908490613aa6565b925050819055507f63a07d15cc78e1ce062239cbc5a154aa74e2d75aad5cfc05ccf9b78bd6bbd58e8885600301548660090154858a86600901548b8b600a0160019054906101000a900460ff166040516116a0989796959493929190613eb4565b60405180910390a1505050506116b560015f55565b50505050565b600154600160a01b900460ff16156116e55760405162461bcd60e51b81526004016106ec9061398b565b6116ed61323d565b335f9081526004602090815260408083208684529091529020600a81015460ff161561172b5760405162461bcd60e51b81526004016106ec90613d2b565b80546001600160a01b031633146117545760405162461bcd60e51b81526004016106ec90613d5a565b600a81015461176a90610100900460ff166131fd565b6117865760405162461bcd60e51b81526004016106ec906139b7565b6003600a820154610100900460ff1660038111156117a6576117a6613870565b036117ed5760405162461bcd60e51b81526020600482015260176024820152762737ba1039bab83837b93a102628102b19903a37b5b2b760491b60448201526064016106ec565b5f82116118335760405162461bcd60e51b815260206004820152601460248201527304d757374206265206c61726765207468616e20360641b60448201526064016106ec565b5f60035f83600a0160019054906101000a900460ff16600381111561185a5761185a613870565b600381111561186b5761186b613870565b81526020019081526020015f2090505f6103e882600401548561188e9190613a5d565b6118989190613a74565b6001600160a01b0386165f908152600260205260408120805492935083929091906118c4908490613aa6565b909155505f90506118d58286613a93565b905080846003015f8282546118ea9190613aa6565b9091555060019050600a850154610100900460ff16600381111561191057611910613870565b0361194d57836005015484600601546119299190613a93565b8460040154856003015461193d9190613a93565b6119479190613a74565b60098501555b6040516323b872dd60e01b81526001600160a01b038716906323b872dd9061197d90339030908a90600401613bf8565b6020604051808303815f875af1158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd9190613c1c565b50600a8401546040517f985f8d2fe856ae5b5ebe1d450940412efc8cdcd761ff2a799e613caaf8c3b26491611a00918a918a918691610100900460ff1690613f08565b60405180910390a150505050611a1560015f55565b505050565b611a556040518060e001604052805f151581526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b60035f836003811115611a6a57611a6a613870565b6003811115611a7b57611a7b613870565b815260208082019290925260409081015f20815160e081018352815460ff16151581526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600581015460a08301526006015460c082015292915050565b611aeb61323d565b335f9081526004602090815260408083208684529091529020600a81015460ff1615611b295760405162461bcd60e51b81526004016106ec90613d2b565b80546001600160a01b03163314611b525760405162461bcd60e51b81526004016106ec90613d5a565b600a810154611b6890610100900460ff166131fd565b611b845760405162461bcd60e51b81526004016106ec906139b7565b6001810154611b9d906001600160a01b03168484612654565b15611bba5760405162461bcd60e51b81526004016106ec906139f8565b5f60035f83600a0160019054906101000a900460ff166003811115611be157611be1613870565b6003811115611bf257611bf2613870565b81526020019081526020015f2090508060030154341015611c555760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420656e6f7567682066656520666f72207472616e73666572000000000060448201526064016106ec565b60018201545f90611c70906001600160a01b03168686610684565b83546001600160a01b038088166001600160a01b0319928316811787555f818152600460209081526040808320878452909152902080548416909117815560018088015490820180549094169216919091179091559091508390600280820190611cdc90840182613de9565b506003820154816003015560048201548160040155600582015481600501556006820154816006015560078201816007019081611d199190613de9565b506008828101549082015560098083015490820155600a8083018054918301805460ff938416151560ff1982168117835592546101009081900490941693919261ff00191661ffff199091161790836003811115611d7957611d79613870565b0217905550600a82810154908201805460ff6201000093849004169262ff00001990911690836002811115611db057611db0613870565b021790555050335f9081526004602090815260408083208a8452909152812080546001600160a01b0319908116825560018201805490911690559150611df96002830182613294565b600382015f9055600482015f9055600582015f9055600682015f9055600782015f611e249190613294565b505f6008820181905560098201819055600a909101805462ffffff1916905580805260026020525f805160206141cf8339815191528054349290611e69908490613aa6565b90915550506040517feb034ad83e39c8082ceb28ded0be06e66698c113cf7ede6dc0931f2cdcb0941090611ea690339088908a9086908a90613f3b565b60405180910390a1505050611a1560015f55565b611ec261323d565b335f9081526004602090815260408083208484529091529020600a81015460ff1615611f305760405162461bcd60e51b815260206004820152601b60248201527f43616e206e6f742077697468647261772072657065617465646c79000000000060448201526064016106ec565b600a810154611f4690610100900460ff166131fd565b611f625760405162461bcd60e51b81526004016106ec906139b7565b80546001600160a01b03163314611f8b5760405162461bcd60e51b81526004016106ec90613d5a565b5f60035f83600a0160019054906101000a900460ff166003811115611fb257611fb2613870565b6003811115611fc357611fc3613870565b815260208101919091526040015f2090506003600a830154610100900460ff166003811115611ff457611ff4613870565b0361204d57806006015434101561204d5760405162461bcd60e51b815260206004820152601960248201527f4e6f7420656e6f75676820666565206f6620657874726163740000000000000060448201526064016106ec565b5f6003600a840154610100900460ff16600381111561206e5761206e613870565b0361214a575f61207e85336110a4565b1161209b5760405162461bcd60e51b81526004016106ec90613f74565b50600a8201805460ff191660019081179091555f80805260026020525f805160206141cf83398151915280543492906120d5908490613aa6565b90915550506001830154835460088501546040516323b872dd60e01b81526001600160a01b03938416936323b872dd936121189330939290911691600401613bf8565b5f604051808303815f87803b15801561212f575f80fd5b505af1158015612141573d5f803e3d5ffd5b505050506122c0565b5f61215585336110a4565b90505f81116121765760405162461bcd60e51b81526004016106ec90613f74565b80846004015f8282546121899190613aa6565b9091555060019050600a850154610100900460ff1660038111156121af576121af613870565b036121d9576121be85336110a4565b5f036121d457600a8401805460ff191660011790555b6121e9565b600a8401805460ff191660011790555b5f6103e88460060154836121fd9190613a5d565b6122079190613a74565b90505f6122148284613a93565b600187015460405163a9059cbb60e01b8152336004820152602481018390529192506001600160a01b03169063a9059cbb906044016020604051808303815f875af1158015612265573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122899190613c1c565b5060018601546001600160a01b03165f90815260026020526040812080548492906122b5908490613aa6565b909155509093505050505b600a8301546040517ff2b033e329bac1a6a57b003051067c56a646d4ec6169bea64e3a11b61bb33a7391612304918791859160ff8083169261010090041690613fb6565b60405180910390a150505061231860015f55565b50565b6001546001600160a01b031633146123455760405162461bcd60e51b81526004016106ec90613ca2565b5f811161238d5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a5908195e1d1c9858dd08185b5bdd5b9d60521b60448201526064016106ec565b60606001600160a01b03831615612510576040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa1580156123e0573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061240491906139e1565b8211156124535760405162461bcd60e51b815260206004820152601860248201527f457863656564207468652045524332302062616c616e6365000000000000000060448201526064016106ec565b6001600160a01b0383165f908152600260205260408120805484929061247a908490613a93565b90915550506040805180820182526005815264045524332360dc1b6020820152905163a9059cbb60e01b8152336004820152602481018490529091506001600160a01b0384169063a9059cbb906044016020604051808303815f875af11580156124e6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061250a9190613c1c565b506125cc565b478211156125595760405162461bcd60e51b815260206004820152601660248201527545786365656420746865204554482062616c616e636560501b60448201526064016106ec565b6001600160a01b0383165f9081526002602052604081208054849290612580908490613a93565b9091555050604080518082018252600381526208aa8960eb1b60208201529051909150339083156108fc029084905f818181858888f193505050501580156125ca573d5f803e3d5ffd5b505b7f0730287684eef65877209b393adbfb1cc1d80fa000bc457bbe0c0d13cac729398382846040516125ff93929190613fd9565b60405180910390a1505050565b6001546001600160a01b031633146126365760405162461bcd60e51b81526004016106ec90613ca2565b60018054911515600160a01b0260ff60a01b19909216919091179055565b5f80612661858585610684565b335f90815260046020908152604080832084845290915290208054919250906001600160a01b0316612697575f925050506106b3565b50600195945050505050565b600154600160a01b900460ff16156126cd5760405162461bcd60e51b81526004016106ec9061398b565b6126d561323d565b6126de816131fd565b6126fa5760405162461bcd60e51b81526004016106ec906139b7565b6001600160a01b03841661274b5760405162461bcd60e51b81526020600482015260186024820152774e6f7420737570706f7274207a65726f206164647265737360401b60448201526064016106ec565b5f85511161279b5760405162461bcd60e51b815260206004820152601c60248201527f56616c7565206f66207365744e616d65206d757374206265207365740000000060448201526064016106ec565b6127a68a8587612654565b156127c35760405162461bcd60e51b81526004016106ec906139f8565b4280841161280b5760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420756e697820656e642074696d6560581b60448201526064016106ec565b5f60035f84600381111561282157612821613870565b600381111561283257612832613870565b815260208101919091526040015f209050600283600381111561285757612857613870565b03612b07576040516370a0823160e01b81523360048201526001600160a01b038d16906370a0823190602401602060405180830381865afa15801561289e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128c291906139e1565b8911156129065760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682062616c616e636560701b60448201526064016106ec565b5f61292b85604051806040016040528060028152602001613b1960f11b81525061104d565b90506001600160a01b0381166129775760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964206465782076616c756560781b60448201526064016106ec565b60405163e6a4390560e01b81526001600160a01b038d811660048301528c8116602483015282169063e6a4390590604401602060405180830381865afa1580156129c3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129e79190614017565b6001600160a01b03168d6001600160a01b031614612a475760405162461bcd60e51b815260206004820152601b60248201527f496c6c6567616c204c5020563220746f6b656e2061646472657373000000000060448201526064016106ec565b6103e882600101548b612a5a9190613a5d565b612a649190613a74565b6001600160a01b038e165f9081526002602052604081208054909190612a8b908490613aa6565b90915550506040516323b872dd60e01b81526001600160a01b038e16906323b872dd90612ac090339030908f90600401613bf8565b6020604051808303815f875af1158015612adc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b009190613c1c565b5050612e10565b6003836003811115612b1b57612b1b613870565b03612dd2578060010154341015612b655760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f7567682066656560901b60448201526064016106ec565b6040516331a9108f60e11b81526004810189905233906001600160a01b038e1690636352211e90602401602060405180830381865afa158015612baa573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bce9190614017565b6001600160a01b031614612c245760405162461bcd60e51b815260206004820152601e60248201527f496e76616c6964205633206c6971756964697479206e6674206f776e6572000060448201526064016106ec565b60405163133f757160e31b8152600481018990525f9081906001600160a01b038f16906399fbab889060240161018060405180830381865afa158015612c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c909190614074565b5050505050505050935093505050816001600160a01b03168d6001600160a01b031614612cf05760405162461bcd60e51b815260206004820152600e60248201526d0496e76616c696420746f6b656e360941b60448201526064016106ec565b806001600160a01b03168c6001600160a01b031614612d425760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420746f6b656e3160901b60448201526064016106ec565b5f80805260026020525f805160206141cf8339815191528054349290612d69908490613aa6565b90915550506040516323b872dd60e01b81526001600160a01b038f16906323b872dd90612d9e90339030908f90600401613bf8565b5f604051808303815f87803b158015612db5575f80fd5b505af1158015612dc7573d5f803e3d5ffd5b505050505050612e10565b60405162461bcd60e51b8152602060048201526013602482015272496e76616c6964206c6f636b6572207479706560681b60448201526064016106ec565b5f612e1c8d888a610684565b90505f60045f896001600160a01b03166001600160a01b031681526020019081526020015f205f8381526020019081526020015f20905087815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508d816001015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555088816002019081612eb39190613b3c565b506003856003811115612ec857612ec8613870565b14612ef9576103e883600101548c612ee09190613a5d565b612eea9190613a74565b612ef4908c613a93565b612efc565b60015b60038201555f6004820155600581018490556006810187905560078101612f238782613b3c565b50600881018a9055600a8101805486919061ff001916610100836003811115612f4e57612f4e613870565b0217905550600a810180545f919062ff00001916620100008302179055505f81600a015f6101000a81548160ff0219169083151502179055507f1e19af4b097a0c446c1749bdc8a0c3f8bb7da8b63f1c6a943440b826892a2f56828f8b8b85600301548f8a8e8e8e604051612fcc9a9998979695949392919061414d565b60405180910390a150505050612fe160015f55565b50505050505050505050565b6001546001600160a01b031633146130175760405162461bcd60e51b81526004016106ec90613ca2565b600180546001600160a01b0319166001600160a01b038316908117909155604080519182523360208301527f7924376024f9d929bdada88af55c8759a72551342cca51509f3c3794e70fc6e0910160405180910390a150565b600460209081525f92835260408084209091529082529020805460018201546002830180546001600160a01b039384169492909316926130af90613ab9565b80601f01602080910402602001604051908101604052809291908181526020018280546130db90613ab9565b80156131265780601f106130fd57610100808354040283529160200191613126565b820191905f5260205f20905b81548152906001019060200180831161310957829003601f168201915b50505050509080600301549080600401549080600501549080600601549080600701805461315390613ab9565b80601f016020809104026020016040519081016040528092919081815260200182805461317f90613ab9565b80156131ca5780601f106131a1576101008083540402835291602001916131ca565b820191905f5260205f20905b8154815290600101906020018083116131ad57829003601f168201915b50505060088401546009850154600a909501549394909390925060ff80821692506101008204811691620100009004168d565b5f60035f83600381111561321357613213613870565b600381111561322457613224613870565b815260208101919091526040015f205460ff1692915050565b60025f540361328e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106ec565b60025f55565b5080546132a090613ab9565b5f825580601f106132af575050565b601f0160209004905f5260205f209081019061231891905b808211156132da575f81556001016132c7565b5090565b6001600160a01b0381168114612318575f80fd5b80356132fd816132de565b919050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112613325575f80fd5b813567ffffffffffffffff8082111561334057613340613302565b604051601f8301601f19908116603f0116810190828211818310171561336857613368613302565b81604052838152866020858801011115613380575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f805f606084860312156133b1575f80fd5b83356133bc816132de565b925060208401356133cc816132de565b9150604084013567ffffffffffffffff8111156133e7575f80fd5b6133f386828701613316565b9150509250925092565b8035600481106132fd575f80fd5b5f805f805f8060c08789031215613420575f80fd5b863561342b816132de565b955060208701359450604087013567ffffffffffffffff81111561344d575f80fd5b61345989828a01613316565b945050606087013561346a816132de565b92506080870135915061347f60a088016133fd565b90509295509295509295565b5f805f6060848603121561349d575f80fd5b83356134a8816132de565b9250602084013567ffffffffffffffff808211156134c4575f80fd5b6134d087838801613316565b935060408601359150808211156134e5575f80fd5b506133f386828701613316565b5f60208284031215613502575f80fd5b81356106b3816132de565b5f806040838503121561351e575f80fd5b50508035926020909101359150565b5f805f805f805f60e0888a031215613543575f80fd5b61354c886133fd565b9960208901359950604089013598606081013598506080810135975060a0810135965060c00135945092505050565b5f6020828403121561358b575f80fd5b6106b3826133fd565b5f80604083850312156135a5575f80fd5b823567ffffffffffffffff808211156135bc575f80fd5b6135c886838701613316565b935060208501359150808211156135dd575f80fd5b506135ea85828601613316565b9150509250929050565b5f8060408385031215613605575f80fd5b823591506020830135613617816132de565b809150509250929050565b5f805f8060808587031215613635575f80fd5b843593506020850135613647816132de565b925060408501359150606085013567ffffffffffffffff811115613669575f80fd5b61367587828801613316565b91505092959194509250565b5f805f60608486031215613693575f80fd5b8335925060208401356136a5816132de565b929592945050506040919091013590565b5f5b838110156136d05781810151838201526020016136b8565b50505f910152565b5f81518084526136ef8160208601602086016136b6565b601f01601f19169290920160200192915050565b602081525f6106b360208301846136d8565b5f805f60608486031215613727575f80fd5b8335925060208401356133cc816132de565b5f60208284031215613749575f80fd5b5035919050565b5f8060408385031215613761575f80fd5b823561376c816132de565b946020939093013593505050565b8015158114612318575f80fd5b5f60208284031215613797575f80fd5b81356106b38161377a565b5f805f805f805f805f806101408b8d0312156137bc575f80fd5b6137c58b6132f2565b99506137d360208c016132f2565b98506137e160408c016132f2565b975060608b0135965060808b0135955060a08b013567ffffffffffffffff8082111561380b575f80fd5b6138178e838f01613316565b965061382560c08e016132f2565b955060e08d013594506101008d0135915080821115613842575f80fd5b5061384f8d828e01613316565b92505061385f6101208c016133fd565b90509295989b9194979a5092959850565b634e487b7160e01b5f52602160045260245ffd5b6004811061389457613894613870565b9052565b6003811061389457613894613870565b6001600160a01b038e811682528d1660208201526101a0604082018190525f906138d49083018e6136d8565b8c60608401528b60808401528a60a08401528960c084015282810360e08401526138fe818a6136d8565b9150508661010083015285610120830152841515610140830152613926610160830185613884565b613934610180830184613898565b9e9d5050505050505050505050505050565b5f6bffffffffffffffffffffffff19808660601b168352808560601b16601484015250825161397c8160288501602087016136b6565b91909101602801949350505050565b60208082526012908201527110dbdb9d1c9858dd081a5cc81c185d5cd95960721b604082015260600190565b60208082526010908201526f5365742075702066656520726174657360801b604082015260600190565b5f602082840312156139f1575f80fd5b5051919050565b60208082526031908201527f4c6f636b657220494420616c72656164792065786973742c20686f772061626f604082015270757420757365206f74686572206e616d6560781b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761109e5761109e613a49565b5f82613a8e57634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561109e5761109e613a49565b8082018082111561109e5761109e613a49565b600181811c90821680613acd57607f821691505b602082108103613aeb57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115611a1557805f5260205f20601f840160051c81016020851015613b165750805b601f840160051c820191505b81811015613b35575f8155600101613b22565b5050505050565b815167ffffffffffffffff811115613b5657613b56613302565b613b6a81613b648454613ab9565b84613af1565b602080601f831160018114613b9d575f8415613b865750858301515b5f19600386901b1c1916600185901b178555610bea565b5f85815260208120601f198616915b82811015613bcb57888601518255948401946001909101908401613bac565b5085821015613be857878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f60208284031215613c2c575f80fd5b81516106b38161377a565b8981526001600160a01b038981166020830152610120604083018190525f91613c628483018c6136d8565b9250808a16606085015250508660808301528560a08301528460c08301528360e0830152613c94610100830184613884565b9a9950505050505050505050565b602080825260159082015274496e76616c6964206f776e6572206164647265737360581b604082015260600190565b5f8251613ce28184602087016136b6565b9190910192915050565b6001600160a01b03841681526060602082018190525f90613d0f908301856136d8565b8281036040840152613d2181856136d8565b9695505050505050565b602080825260159082015274131bd8dac8185b1c9958591e481d5b9b1bd8dad959605a1b604082015260600190565b60208082526014908201527324b73b30b634b2103637b1b5b2b91037bbb732b960611b604082015260600190565b8381526020810183905260608101613da36040830184613884565b949350505050565b60e08101613db9828a613884565b8760208301528660408301528560608301528460808301528360a08301528260c083015298975050505050505050565b818103613df4575050565b613dfe8254613ab9565b67ffffffffffffffff811115613e1657613e16613302565b613e2481613b648454613ab9565b5f601f821160018114613e55575f8315613e3e5750848201545b5f19600385901b1c1916600184901b178455613b35565b5f8581526020808220868352908220601f198616925b83811015613e8b5782860154825560019586019590910190602001613e6b565b5085831015613be8579301545f1960f8600387901b161c19169092555050600190811b01905550565b5f6101008a83528960208401528860408401528760608401528660808401528560a08401528060c0840152613eeb818401866136d8565b915050613efb60e0830184613884565b9998505050505050505050565b8481526001600160a01b03841660208201526040810183905260808101613f326060830184613884565b95945050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190525f906111a5908301846136d8565b60208082526022908201527f43616e206e6f74207769746864726177206265666f726520657870697261746960408201526137b760f11b606082015260800190565b84815260208101849052821515604082015260808101613f326060830184613884565b6001600160a01b03841681526060602082018190525f90613ffc908301856136d8565b9050826040830152949350505050565b80516132fd816132de565b5f60208284031215614027575f80fd5b81516106b3816132de565b805162ffffff811681146132fd575f80fd5b8051600281900b81146132fd575f80fd5b80516fffffffffffffffffffffffffffffffff811681146132fd575f80fd5b5f805f805f805f805f805f806101808d8f031215614090575f80fd5b8c516bffffffffffffffffffffffff811681146140ab575f80fd5b9b506140b960208e0161400c565b9a506140c760408e0161400c565b99506140d560608e0161400c565b98506140e360808e01614032565b97506140f160a08e01614044565b96506140ff60c08e01614044565b955061410d60e08e01614055565b94506101008d015193506101208d0151925061412c6101408e01614055565b915061413b6101608e01614055565b90509295989b509295989b509295989b565b8a81526001600160a01b038a81166020830152610140604083018190525f916141788483018d6136d8565b9150808b166060850152508860808401528760a08401528660c08401528560e08401528281036101008401526141ae81866136d8565b9150506141bf610120830184613884565b9b9a505050505050505050505056feac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077ba2646970667358221220dc2b1c7af753ab9e1a7a56050c60860262e4057b2faa53df6cec6788261b617d64736f6c6343000816003346c25fd13b75a6950aa73e89e77d04e467880829db579a442248ed3d098a1d9f

Deployed Bytecode

0x6080604052600436106101b2575f3560e01c806380938ce4116100e7578063c2c90c8d11610087578063ebad839711610062578063ebad8397146105fb578063f5a1f5b41461060e578063f64d08d61461062d578063f7674d6314610665575f80fd5b8063c2c90c8d14610552578063d986ad591461057f578063e70af3351461059e575f80fd5b80639c6da83d116100c25780639c6da83d146104ee578063a6dd767d14610501578063b8b3ae5014610514578063bedb86fb14610533575f80fd5b806380938ce4146104295780638456cb591461049f5780638da5cb5b146104cf575f80fd5b806348d2ca941161015257806361b340581161012d57806361b340581461039e5780636860292c146103bd5780636f75d7f5146103d05780637ba0f0dd146103ef575f80fd5b806348d2ca94146102a1578063498a0bc0146102d55780635650ad5114610367575f80fd5b80630846e7eb1161018d5780630846e7eb146102255780631c8a3be414610244578063265cc77e1461026f5780633d607a4014610282575f80fd5b80630153f84c146101bd5780630441f773146101ef5780630452096b14610210575f80fd5b366101b957005b5f80fd5b3480156101c8575f80fd5b506101dc6101d736600461339f565b610684565b6040519081526020015b60405180910390f35b3480156101fa575f80fd5b5061020e61020936600461340b565b6106ba565b005b34801561021b575f80fd5b506101dc6103e881565b348015610230575f80fd5b5061020e61023f36600461348b565b610bf2565b34801561024f575f80fd5b506101dc61025e3660046134f2565b60026020525f908152604090205481565b61020e61027d36600461350d565b610cbf565b34801561028d575f80fd5b5061020e61029c36600461352d565b610f66565b3480156102ac575f80fd5b506101dc6102bb3660046134f2565b6001600160a01b03165f9081526002602052604090205490565b3480156102e0575f80fd5b506103306102ef36600461357b565b600360208190525f9182526040909120805460018201546002830154938301546004840154600585015460069095015460ff90941695929492939192909187565b6040805197151588526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016101e6565b348015610372575f80fd5b50610386610381366004613594565b61104d565b6040516001600160a01b0390911681526020016101e6565b3480156103a9575f80fd5b506101dc6103b83660046135f4565b6110a4565b61020e6103cb366004613622565b6111b0565b3480156103db575f80fd5b5061020e6103ea366004613681565b6116bb565b3480156103fa575f80fd5b5061041c60405180604001604052806002815260200161763360f01b81525081565b6040516101e69190613703565b348015610434575f80fd5b5061044861044336600461357b565b611a1a565b6040516101e691905f60e0820190508251151582526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015292915050565b3480156104aa575f80fd5b506001546104bf90600160a01b900460ff1681565b60405190151581526020016101e6565b3480156104da575f80fd5b50600154610386906001600160a01b031681565b61020e6104fc366004613715565b611ae3565b61020e61050f366004613739565b611eba565b34801561051f575f80fd5b5061020e61052e366004613750565b61231b565b34801561053e575f80fd5b5061020e61054d366004613787565b61260c565b34801561055d575f80fd5b5061041c604051806040016040528060028152602001613b1960f11b81525081565b34801561058a575f80fd5b506104bf61059936600461339f565b612654565b3480156105a9575f80fd5b506103866105b8366004613594565b815160208184018101805160058252928201948201949094209190935281518083018401805192815290840192909301919091209152546001600160a01b031681565b61020e6106093660046137a2565b6126a3565b348015610619575f80fd5b5061020e6106283660046134f2565b612fed565b348015610638575f80fd5b5061064c610647366004613750565b613070565b6040516101e69d9c9b9a999897969594939291906138a8565b348015610670575f80fd5b506104bf61067f36600461357b565b6131fd565b5f83838360405160200161069a93929190613946565b6040516020818303038152906040528051906020012090505b9392505050565b6106c261323d565b600154600160a01b900460ff16156106f55760405162461bcd60e51b81526004016106ec9061398b565b60405180910390fd5b6106fe816131fd565b61071a5760405162461bcd60e51b81526004016106ec906139b7565b6001600160a01b03831661076b5760405162461bcd60e51b81526020600482015260186024820152774e6f7420737570706f7274207a65726f206164647265737360401b60448201526064016106ec565b5f8451116107bb5760405162461bcd60e51b815260206004820152601c60248201527f56616c7565206f66207365744e616d65206d757374206265207365740000000060448201526064016106ec565b5f8160038111156107ce576107ce613870565b14806107eb575060018160038111156107e9576107e9613870565b145b6108375760405162461bcd60e51b815260206004820152601960248201527f496e76616c696420746f6b656e206c6f636b657220747970650000000000000060448201526064016106ec565b6040516370a0823160e01b81523360048201526001600160a01b038716906370a0823190602401602060405180830381865afa158015610879573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061089d91906139e1565b8511156108e15760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682062616c616e636560701b60448201526064016106ec565b6108ec868486612654565b156109095760405162461bcd60e51b81526004016106ec906139f8565b428083116109515760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420756e697820656e642074696d6560581b60448201526064016106ec565b5f61095d888688610684565b90505f60035f85600381111561097557610975613870565b600381111561098657610986613870565b81526020019081526020015f2090505f6103e882600101548a6109a99190613a5d565b6109b39190613a74565b6109bd908a613a93565b90506103e882600101548a6109d29190613a5d565b6109dc9190613a74565b6001600160a01b038b165f9081526002602052604081208054909190610a03908490613aa6565b909155505f90506001866003811115610a1e57610a1e613870565b03610a3a57610a2d8588613a93565b610a379083613a74565b90505b6001600160a01b038881165f818152600460209081526040808320898452909152902080546001600160a01b03199081169092178155600181018054909216928e1692909217905560028101610a908b82613b3c565b506003808201849055600582018790556006820189905560098201839055600a82018054899261ff001990911690610100908490811115610ad357610ad3613870565b0217905550600a8101805460ff191690555f876003811115610af757610af7613870565b03610b0f57600a8101805462ff000019169055610b23565b600a8101805462ff00001916620100001790555b8b6001600160a01b03166323b872dd33308e6040518463ffffffff1660e01b8152600401610b5393929190613bf8565b6020604051808303815f875af1158015610b6f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b939190613c1c565b507fc5325ed0db0a7daa50dd16b7349da163a487ebded0046afc5bc23f7581018418858d8c8c878b8e898f604051610bd399989796959493929190613c37565b60405180910390a1505050505050610bea60015f55565b505050505050565b6001546001600160a01b03163314610c1c5760405162461bcd60e51b81526004016106ec90613ca2565b604051829082908590600590610c33908590613cd1565b908152602001604051809103902082604051610c4f9190613cd1565b90815260405190819003602001812080546001600160a01b03939093166001600160a01b0319909316929092179091557f46c25fd13b75a6950aa73e89e77d04e467880829db579a442248ed3d098a1d9f90610cb090879087908790613cec565b60405180910390a15050505050565b600154600160a01b900460ff1615610ce95760405162461bcd60e51b81526004016106ec9061398b565b610cf161323d565b335f9081526004602090815260408083208584529091529020600a81015460ff1615610d2f5760405162461bcd60e51b81526004016106ec90613d2b565b80546001600160a01b03163314610d585760405162461bcd60e51b81526004016106ec90613d5a565b600a810154610d6e90610100900460ff166131fd565b610d8a5760405162461bcd60e51b81526004016106ec906139b7565b5f60035f83600a0160019054906101000a900460ff166003811115610db157610db1613870565b6003811115610dc257610dc2613870565b81526020019081526020015f2090508060020154341015610e255760405162461bcd60e51b815260206004820152601860248201527f4e6f7420656e6f75676820666565206f662072656c6f636b000000000000000060448201526064016106ec565b81600601548311610e835760405162461bcd60e51b815260206004820152602260248201527f4e65772074696d657374616d70206d75737420626967676572207468616e206f6044820152611b1960f21b60648201526084016106ec565b6001600a830154610100900460ff166003811115610ea357610ea3613870565b03610edb576005820154610eb79084613a93565b82600401548360030154610ecb9190613a93565b610ed59190613a74565b60098301555b600682018390555f80805260026020525f805160206141cf8339815191528054349290610f09908490613aa6565b9091555050600a8201546040517f1397340e2d7027a973a29ee95161fece028c60c6481b25e47d5f8582a5ace6e091610f4f918791879161010090910460ff1690613d88565b60405180910390a15050610f6260015f55565b5050565b6001546001600160a01b03163314610f905760405162461bcd60e51b81526004016106ec90613ca2565b5f60035f896003811115610fa657610fa6613870565b6003811115610fb757610fb7613870565b8152602081019190915260409081015f20805460ff1916600190811782558101899055600281018890556003810187905560048101869055600581018590556006810184905590519091507fbef7735125feb4af2cc3ac99edddbed78eff28ecf0dd78b6f3a02b8545b10d839061103b908a908a908a908a908a908a908a90613dab565b60405180910390a15050505050505050565b6040515f9083908390600590611064908490613cd1565b9081526020016040518091039020816040516110809190613cd1565b908152604051908190036020019020546001600160a01b0316925050505b92915050565b6001600160a01b038082165f81815260046020908152604080832087845290915281208054919390929116146110dd575f91505061109e565b60058101546006820154425f6001600a860154610100900460ff16600381111561110957611109613870565b03611149578282111561111a578291505b6004850154600986015461112e8685613a93565b6111389190613a5d565b6111429190613a93565b90506111a5565b6003600a860154610100900460ff16600381111561116957611169613870565b0361118a57828211611182575f9550505050505061109e565b5060016111a5565b82821161119e575f9550505050505061109e565b5060038401545b979650505050505050565b600154600160a01b900460ff16156111da5760405162461bcd60e51b81526004016106ec9061398b565b6111e261323d565b335f9081526004602090815260408083208784529091529020600a81015460ff16156112205760405162461bcd60e51b81526004016106ec90613d2b565b80546001600160a01b031633146112495760405162461bcd60e51b81526004016106ec90613d5a565b600a81015461125f90610100900460ff166131fd565b61127b5760405162461bcd60e51b81526004016106ec906139b7565b6003600a820154610100900460ff16600381111561129b5761129b613870565b036112e25760405162461bcd60e51b81526020600482015260176024820152762737ba1039bab83837b93a102628102b19903a37b5b2b760491b60448201526064016106ec565b60018101546001600160a01b038581169116146113395760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420746f6b656e206164647265737360581b60448201526064016106ec565b60018101548154611357916001600160a01b03908116911684612654565b156113745760405162461bcd60e51b81526004016106ec906139f8565b5f60035f83600a0160019054906101000a900460ff16600381111561139b5761139b613870565b60038111156113ac576113ac613870565b81526020019081526020015f20905080600501543410156114085760405162461bcd60e51b81526020600482015260166024820152754e6f7420656e6f7567682073706c69744f702066656560501b60448201526064016106ec565b8160030154841061146b5760405162461bcd60e51b815260206004820152602760248201527f53706c697420616d6f756e74206973206c6172676572207468616e206c6f636b60448201526608185b5bdd5b9d60ca1b60648201526084016106ec565b5f611477863386610684565b335f9081526004602090815260408083208484529091529020845481546001600160a01b039182166001600160a01b031991821617835560018088015490840180549190931691161790559091506002808201906114d790860182613de9565b5060058085015490820155600680850154908201556007808201906114fe90860182613de9565b5083600301548685600901546115149190613a5d565b61151e9190613a74565b6009820155600a80850154908201805460ff61010093849004169261ff00199091169083600381111561155357611553613870565b021790555060038101869055600a8101805460ff191690556001600a850154610100900460ff16600381111561158b5761158b613870565b036115b95783600301548685600401546115a59190613a5d565b6115af9190613a74565b60048201556115c4565b600480850154908201555b85846003015f8282546115d79190613a93565b925050819055508060040154846004015f8282546115f59190613a93565b925050819055508060090154846009015f8282546116139190613a93565b90915550505f80805260026020525f805160206141cf833981519152805434929061163f908490613aa6565b925050819055507f63a07d15cc78e1ce062239cbc5a154aa74e2d75aad5cfc05ccf9b78bd6bbd58e8885600301548660090154858a86600901548b8b600a0160019054906101000a900460ff166040516116a0989796959493929190613eb4565b60405180910390a1505050506116b560015f55565b50505050565b600154600160a01b900460ff16156116e55760405162461bcd60e51b81526004016106ec9061398b565b6116ed61323d565b335f9081526004602090815260408083208684529091529020600a81015460ff161561172b5760405162461bcd60e51b81526004016106ec90613d2b565b80546001600160a01b031633146117545760405162461bcd60e51b81526004016106ec90613d5a565b600a81015461176a90610100900460ff166131fd565b6117865760405162461bcd60e51b81526004016106ec906139b7565b6003600a820154610100900460ff1660038111156117a6576117a6613870565b036117ed5760405162461bcd60e51b81526020600482015260176024820152762737ba1039bab83837b93a102628102b19903a37b5b2b760491b60448201526064016106ec565b5f82116118335760405162461bcd60e51b815260206004820152601460248201527304d757374206265206c61726765207468616e20360641b60448201526064016106ec565b5f60035f83600a0160019054906101000a900460ff16600381111561185a5761185a613870565b600381111561186b5761186b613870565b81526020019081526020015f2090505f6103e882600401548561188e9190613a5d565b6118989190613a74565b6001600160a01b0386165f908152600260205260408120805492935083929091906118c4908490613aa6565b909155505f90506118d58286613a93565b905080846003015f8282546118ea9190613aa6565b9091555060019050600a850154610100900460ff16600381111561191057611910613870565b0361194d57836005015484600601546119299190613a93565b8460040154856003015461193d9190613a93565b6119479190613a74565b60098501555b6040516323b872dd60e01b81526001600160a01b038716906323b872dd9061197d90339030908a90600401613bf8565b6020604051808303815f875af1158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd9190613c1c565b50600a8401546040517f985f8d2fe856ae5b5ebe1d450940412efc8cdcd761ff2a799e613caaf8c3b26491611a00918a918a918691610100900460ff1690613f08565b60405180910390a150505050611a1560015f55565b505050565b611a556040518060e001604052805f151581526020015f81526020015f81526020015f81526020015f81526020015f81526020015f81525090565b60035f836003811115611a6a57611a6a613870565b6003811115611a7b57611a7b613870565b815260208082019290925260409081015f20815160e081018352815460ff16151581526001820154938101939093526002810154918301919091526003810154606083015260048101546080830152600581015460a08301526006015460c082015292915050565b611aeb61323d565b335f9081526004602090815260408083208684529091529020600a81015460ff1615611b295760405162461bcd60e51b81526004016106ec90613d2b565b80546001600160a01b03163314611b525760405162461bcd60e51b81526004016106ec90613d5a565b600a810154611b6890610100900460ff166131fd565b611b845760405162461bcd60e51b81526004016106ec906139b7565b6001810154611b9d906001600160a01b03168484612654565b15611bba5760405162461bcd60e51b81526004016106ec906139f8565b5f60035f83600a0160019054906101000a900460ff166003811115611be157611be1613870565b6003811115611bf257611bf2613870565b81526020019081526020015f2090508060030154341015611c555760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420656e6f7567682066656520666f72207472616e73666572000000000060448201526064016106ec565b60018201545f90611c70906001600160a01b03168686610684565b83546001600160a01b038088166001600160a01b0319928316811787555f818152600460209081526040808320878452909152902080548416909117815560018088015490820180549094169216919091179091559091508390600280820190611cdc90840182613de9565b506003820154816003015560048201548160040155600582015481600501556006820154816006015560078201816007019081611d199190613de9565b506008828101549082015560098083015490820155600a8083018054918301805460ff938416151560ff1982168117835592546101009081900490941693919261ff00191661ffff199091161790836003811115611d7957611d79613870565b0217905550600a82810154908201805460ff6201000093849004169262ff00001990911690836002811115611db057611db0613870565b021790555050335f9081526004602090815260408083208a8452909152812080546001600160a01b0319908116825560018201805490911690559150611df96002830182613294565b600382015f9055600482015f9055600582015f9055600682015f9055600782015f611e249190613294565b505f6008820181905560098201819055600a909101805462ffffff1916905580805260026020525f805160206141cf8339815191528054349290611e69908490613aa6565b90915550506040517feb034ad83e39c8082ceb28ded0be06e66698c113cf7ede6dc0931f2cdcb0941090611ea690339088908a9086908a90613f3b565b60405180910390a1505050611a1560015f55565b611ec261323d565b335f9081526004602090815260408083208484529091529020600a81015460ff1615611f305760405162461bcd60e51b815260206004820152601b60248201527f43616e206e6f742077697468647261772072657065617465646c79000000000060448201526064016106ec565b600a810154611f4690610100900460ff166131fd565b611f625760405162461bcd60e51b81526004016106ec906139b7565b80546001600160a01b03163314611f8b5760405162461bcd60e51b81526004016106ec90613d5a565b5f60035f83600a0160019054906101000a900460ff166003811115611fb257611fb2613870565b6003811115611fc357611fc3613870565b815260208101919091526040015f2090506003600a830154610100900460ff166003811115611ff457611ff4613870565b0361204d57806006015434101561204d5760405162461bcd60e51b815260206004820152601960248201527f4e6f7420656e6f75676820666565206f6620657874726163740000000000000060448201526064016106ec565b5f6003600a840154610100900460ff16600381111561206e5761206e613870565b0361214a575f61207e85336110a4565b1161209b5760405162461bcd60e51b81526004016106ec90613f74565b50600a8201805460ff191660019081179091555f80805260026020525f805160206141cf83398151915280543492906120d5908490613aa6565b90915550506001830154835460088501546040516323b872dd60e01b81526001600160a01b03938416936323b872dd936121189330939290911691600401613bf8565b5f604051808303815f87803b15801561212f575f80fd5b505af1158015612141573d5f803e3d5ffd5b505050506122c0565b5f61215585336110a4565b90505f81116121765760405162461bcd60e51b81526004016106ec90613f74565b80846004015f8282546121899190613aa6565b9091555060019050600a850154610100900460ff1660038111156121af576121af613870565b036121d9576121be85336110a4565b5f036121d457600a8401805460ff191660011790555b6121e9565b600a8401805460ff191660011790555b5f6103e88460060154836121fd9190613a5d565b6122079190613a74565b90505f6122148284613a93565b600187015460405163a9059cbb60e01b8152336004820152602481018390529192506001600160a01b03169063a9059cbb906044016020604051808303815f875af1158015612265573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122899190613c1c565b5060018601546001600160a01b03165f90815260026020526040812080548492906122b5908490613aa6565b909155509093505050505b600a8301546040517ff2b033e329bac1a6a57b003051067c56a646d4ec6169bea64e3a11b61bb33a7391612304918791859160ff8083169261010090041690613fb6565b60405180910390a150505061231860015f55565b50565b6001546001600160a01b031633146123455760405162461bcd60e51b81526004016106ec90613ca2565b5f811161238d5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a5908195e1d1c9858dd08185b5bdd5b9d60521b60448201526064016106ec565b60606001600160a01b03831615612510576040516370a0823160e01b81523060048201526001600160a01b038416906370a0823190602401602060405180830381865afa1580156123e0573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061240491906139e1565b8211156124535760405162461bcd60e51b815260206004820152601860248201527f457863656564207468652045524332302062616c616e6365000000000000000060448201526064016106ec565b6001600160a01b0383165f908152600260205260408120805484929061247a908490613a93565b90915550506040805180820182526005815264045524332360dc1b6020820152905163a9059cbb60e01b8152336004820152602481018490529091506001600160a01b0384169063a9059cbb906044016020604051808303815f875af11580156124e6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061250a9190613c1c565b506125cc565b478211156125595760405162461bcd60e51b815260206004820152601660248201527545786365656420746865204554482062616c616e636560501b60448201526064016106ec565b6001600160a01b0383165f9081526002602052604081208054849290612580908490613a93565b9091555050604080518082018252600381526208aa8960eb1b60208201529051909150339083156108fc029084905f818181858888f193505050501580156125ca573d5f803e3d5ffd5b505b7f0730287684eef65877209b393adbfb1cc1d80fa000bc457bbe0c0d13cac729398382846040516125ff93929190613fd9565b60405180910390a1505050565b6001546001600160a01b031633146126365760405162461bcd60e51b81526004016106ec90613ca2565b60018054911515600160a01b0260ff60a01b19909216919091179055565b5f80612661858585610684565b335f90815260046020908152604080832084845290915290208054919250906001600160a01b0316612697575f925050506106b3565b50600195945050505050565b600154600160a01b900460ff16156126cd5760405162461bcd60e51b81526004016106ec9061398b565b6126d561323d565b6126de816131fd565b6126fa5760405162461bcd60e51b81526004016106ec906139b7565b6001600160a01b03841661274b5760405162461bcd60e51b81526020600482015260186024820152774e6f7420737570706f7274207a65726f206164647265737360401b60448201526064016106ec565b5f85511161279b5760405162461bcd60e51b815260206004820152601c60248201527f56616c7565206f66207365744e616d65206d757374206265207365740000000060448201526064016106ec565b6127a68a8587612654565b156127c35760405162461bcd60e51b81526004016106ec906139f8565b4280841161280b5760405162461bcd60e51b8152602060048201526015602482015274496e76616c696420756e697820656e642074696d6560581b60448201526064016106ec565b5f60035f84600381111561282157612821613870565b600381111561283257612832613870565b815260208101919091526040015f209050600283600381111561285757612857613870565b03612b07576040516370a0823160e01b81523360048201526001600160a01b038d16906370a0823190602401602060405180830381865afa15801561289e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128c291906139e1565b8911156129065760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682062616c616e636560701b60448201526064016106ec565b5f61292b85604051806040016040528060028152602001613b1960f11b81525061104d565b90506001600160a01b0381166129775760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964206465782076616c756560781b60448201526064016106ec565b60405163e6a4390560e01b81526001600160a01b038d811660048301528c8116602483015282169063e6a4390590604401602060405180830381865afa1580156129c3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129e79190614017565b6001600160a01b03168d6001600160a01b031614612a475760405162461bcd60e51b815260206004820152601b60248201527f496c6c6567616c204c5020563220746f6b656e2061646472657373000000000060448201526064016106ec565b6103e882600101548b612a5a9190613a5d565b612a649190613a74565b6001600160a01b038e165f9081526002602052604081208054909190612a8b908490613aa6565b90915550506040516323b872dd60e01b81526001600160a01b038e16906323b872dd90612ac090339030908f90600401613bf8565b6020604051808303815f875af1158015612adc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b009190613c1c565b5050612e10565b6003836003811115612b1b57612b1b613870565b03612dd2578060010154341015612b655760405162461bcd60e51b815260206004820152600e60248201526d4e6f7420656e6f7567682066656560901b60448201526064016106ec565b6040516331a9108f60e11b81526004810189905233906001600160a01b038e1690636352211e90602401602060405180830381865afa158015612baa573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bce9190614017565b6001600160a01b031614612c245760405162461bcd60e51b815260206004820152601e60248201527f496e76616c6964205633206c6971756964697479206e6674206f776e6572000060448201526064016106ec565b60405163133f757160e31b8152600481018990525f9081906001600160a01b038f16906399fbab889060240161018060405180830381865afa158015612c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c909190614074565b5050505050505050935093505050816001600160a01b03168d6001600160a01b031614612cf05760405162461bcd60e51b815260206004820152600e60248201526d0496e76616c696420746f6b656e360941b60448201526064016106ec565b806001600160a01b03168c6001600160a01b031614612d425760405162461bcd60e51b815260206004820152600e60248201526d496e76616c696420746f6b656e3160901b60448201526064016106ec565b5f80805260026020525f805160206141cf8339815191528054349290612d69908490613aa6565b90915550506040516323b872dd60e01b81526001600160a01b038f16906323b872dd90612d9e90339030908f90600401613bf8565b5f604051808303815f87803b158015612db5575f80fd5b505af1158015612dc7573d5f803e3d5ffd5b505050505050612e10565b60405162461bcd60e51b8152602060048201526013602482015272496e76616c6964206c6f636b6572207479706560681b60448201526064016106ec565b5f612e1c8d888a610684565b90505f60045f896001600160a01b03166001600160a01b031681526020019081526020015f205f8381526020019081526020015f20905087815f015f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508d816001015f6101000a8154816001600160a01b0302191690836001600160a01b0316021790555088816002019081612eb39190613b3c565b506003856003811115612ec857612ec8613870565b14612ef9576103e883600101548c612ee09190613a5d565b612eea9190613a74565b612ef4908c613a93565b612efc565b60015b60038201555f6004820155600581018490556006810187905560078101612f238782613b3c565b50600881018a9055600a8101805486919061ff001916610100836003811115612f4e57612f4e613870565b0217905550600a810180545f919062ff00001916620100008302179055505f81600a015f6101000a81548160ff0219169083151502179055507f1e19af4b097a0c446c1749bdc8a0c3f8bb7da8b63f1c6a943440b826892a2f56828f8b8b85600301548f8a8e8e8e604051612fcc9a9998979695949392919061414d565b60405180910390a150505050612fe160015f55565b50505050505050505050565b6001546001600160a01b031633146130175760405162461bcd60e51b81526004016106ec90613ca2565b600180546001600160a01b0319166001600160a01b038316908117909155604080519182523360208301527f7924376024f9d929bdada88af55c8759a72551342cca51509f3c3794e70fc6e0910160405180910390a150565b600460209081525f92835260408084209091529082529020805460018201546002830180546001600160a01b039384169492909316926130af90613ab9565b80601f01602080910402602001604051908101604052809291908181526020018280546130db90613ab9565b80156131265780601f106130fd57610100808354040283529160200191613126565b820191905f5260205f20905b81548152906001019060200180831161310957829003601f168201915b50505050509080600301549080600401549080600501549080600601549080600701805461315390613ab9565b80601f016020809104026020016040519081016040528092919081815260200182805461317f90613ab9565b80156131ca5780601f106131a1576101008083540402835291602001916131ca565b820191905f5260205f20905b8154815290600101906020018083116131ad57829003601f168201915b50505060088401546009850154600a909501549394909390925060ff80821692506101008204811691620100009004168d565b5f60035f83600381111561321357613213613870565b600381111561322457613224613870565b815260208101919091526040015f205460ff1692915050565b60025f540361328e5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016106ec565b60025f55565b5080546132a090613ab9565b5f825580601f106132af575050565b601f0160209004905f5260205f209081019061231891905b808211156132da575f81556001016132c7565b5090565b6001600160a01b0381168114612318575f80fd5b80356132fd816132de565b919050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112613325575f80fd5b813567ffffffffffffffff8082111561334057613340613302565b604051601f8301601f19908116603f0116810190828211818310171561336857613368613302565b81604052838152866020858801011115613380575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f805f606084860312156133b1575f80fd5b83356133bc816132de565b925060208401356133cc816132de565b9150604084013567ffffffffffffffff8111156133e7575f80fd5b6133f386828701613316565b9150509250925092565b8035600481106132fd575f80fd5b5f805f805f8060c08789031215613420575f80fd5b863561342b816132de565b955060208701359450604087013567ffffffffffffffff81111561344d575f80fd5b61345989828a01613316565b945050606087013561346a816132de565b92506080870135915061347f60a088016133fd565b90509295509295509295565b5f805f6060848603121561349d575f80fd5b83356134a8816132de565b9250602084013567ffffffffffffffff808211156134c4575f80fd5b6134d087838801613316565b935060408601359150808211156134e5575f80fd5b506133f386828701613316565b5f60208284031215613502575f80fd5b81356106b3816132de565b5f806040838503121561351e575f80fd5b50508035926020909101359150565b5f805f805f805f60e0888a031215613543575f80fd5b61354c886133fd565b9960208901359950604089013598606081013598506080810135975060a0810135965060c00135945092505050565b5f6020828403121561358b575f80fd5b6106b3826133fd565b5f80604083850312156135a5575f80fd5b823567ffffffffffffffff808211156135bc575f80fd5b6135c886838701613316565b935060208501359150808211156135dd575f80fd5b506135ea85828601613316565b9150509250929050565b5f8060408385031215613605575f80fd5b823591506020830135613617816132de565b809150509250929050565b5f805f8060808587031215613635575f80fd5b843593506020850135613647816132de565b925060408501359150606085013567ffffffffffffffff811115613669575f80fd5b61367587828801613316565b91505092959194509250565b5f805f60608486031215613693575f80fd5b8335925060208401356136a5816132de565b929592945050506040919091013590565b5f5b838110156136d05781810151838201526020016136b8565b50505f910152565b5f81518084526136ef8160208601602086016136b6565b601f01601f19169290920160200192915050565b602081525f6106b360208301846136d8565b5f805f60608486031215613727575f80fd5b8335925060208401356133cc816132de565b5f60208284031215613749575f80fd5b5035919050565b5f8060408385031215613761575f80fd5b823561376c816132de565b946020939093013593505050565b8015158114612318575f80fd5b5f60208284031215613797575f80fd5b81356106b38161377a565b5f805f805f805f805f806101408b8d0312156137bc575f80fd5b6137c58b6132f2565b99506137d360208c016132f2565b98506137e160408c016132f2565b975060608b0135965060808b0135955060a08b013567ffffffffffffffff8082111561380b575f80fd5b6138178e838f01613316565b965061382560c08e016132f2565b955060e08d013594506101008d0135915080821115613842575f80fd5b5061384f8d828e01613316565b92505061385f6101208c016133fd565b90509295989b9194979a5092959850565b634e487b7160e01b5f52602160045260245ffd5b6004811061389457613894613870565b9052565b6003811061389457613894613870565b6001600160a01b038e811682528d1660208201526101a0604082018190525f906138d49083018e6136d8565b8c60608401528b60808401528a60a08401528960c084015282810360e08401526138fe818a6136d8565b9150508661010083015285610120830152841515610140830152613926610160830185613884565b613934610180830184613898565b9e9d5050505050505050505050505050565b5f6bffffffffffffffffffffffff19808660601b168352808560601b16601484015250825161397c8160288501602087016136b6565b91909101602801949350505050565b60208082526012908201527110dbdb9d1c9858dd081a5cc81c185d5cd95960721b604082015260600190565b60208082526010908201526f5365742075702066656520726174657360801b604082015260600190565b5f602082840312156139f1575f80fd5b5051919050565b60208082526031908201527f4c6f636b657220494420616c72656164792065786973742c20686f772061626f604082015270757420757365206f74686572206e616d6560781b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761109e5761109e613a49565b5f82613a8e57634e487b7160e01b5f52601260045260245ffd5b500490565b8181038181111561109e5761109e613a49565b8082018082111561109e5761109e613a49565b600181811c90821680613acd57607f821691505b602082108103613aeb57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115611a1557805f5260205f20601f840160051c81016020851015613b165750805b601f840160051c820191505b81811015613b35575f8155600101613b22565b5050505050565b815167ffffffffffffffff811115613b5657613b56613302565b613b6a81613b648454613ab9565b84613af1565b602080601f831160018114613b9d575f8415613b865750858301515b5f19600386901b1c1916600185901b178555610bea565b5f85815260208120601f198616915b82811015613bcb57888601518255948401946001909101908401613bac565b5085821015613be857878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f60208284031215613c2c575f80fd5b81516106b38161377a565b8981526001600160a01b038981166020830152610120604083018190525f91613c628483018c6136d8565b9250808a16606085015250508660808301528560a08301528460c08301528360e0830152613c94610100830184613884565b9a9950505050505050505050565b602080825260159082015274496e76616c6964206f776e6572206164647265737360581b604082015260600190565b5f8251613ce28184602087016136b6565b9190910192915050565b6001600160a01b03841681526060602082018190525f90613d0f908301856136d8565b8281036040840152613d2181856136d8565b9695505050505050565b602080825260159082015274131bd8dac8185b1c9958591e481d5b9b1bd8dad959605a1b604082015260600190565b60208082526014908201527324b73b30b634b2103637b1b5b2b91037bbb732b960611b604082015260600190565b8381526020810183905260608101613da36040830184613884565b949350505050565b60e08101613db9828a613884565b8760208301528660408301528560608301528460808301528360a08301528260c083015298975050505050505050565b818103613df4575050565b613dfe8254613ab9565b67ffffffffffffffff811115613e1657613e16613302565b613e2481613b648454613ab9565b5f601f821160018114613e55575f8315613e3e5750848201545b5f19600385901b1c1916600184901b178455613b35565b5f8581526020808220868352908220601f198616925b83811015613e8b5782860154825560019586019590910190602001613e6b565b5085831015613be8579301545f1960f8600387901b161c19169092555050600190811b01905550565b5f6101008a83528960208401528860408401528760608401528660808401528560a08401528060c0840152613eeb818401866136d8565b915050613efb60e0830184613884565b9998505050505050505050565b8481526001600160a01b03841660208201526040810183905260808101613f326060830184613884565b95945050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190525f906111a5908301846136d8565b60208082526022908201527f43616e206e6f74207769746864726177206265666f726520657870697261746960408201526137b760f11b606082015260800190565b84815260208101849052821515604082015260808101613f326060830184613884565b6001600160a01b03841681526060602082018190525f90613ffc908301856136d8565b9050826040830152949350505050565b80516132fd816132de565b5f60208284031215614027575f80fd5b81516106b3816132de565b805162ffffff811681146132fd575f80fd5b8051600281900b81146132fd575f80fd5b80516fffffffffffffffffffffffffffffffff811681146132fd575f80fd5b5f805f805f805f805f805f806101808d8f031215614090575f80fd5b8c516bffffffffffffffffffffffff811681146140ab575f80fd5b9b506140b960208e0161400c565b9a506140c760408e0161400c565b99506140d560608e0161400c565b98506140e360808e01614032565b97506140f160a08e01614044565b96506140ff60c08e01614044565b955061410d60e08e01614055565b94506101008d015193506101208d0151925061412c6101408e01614055565b915061413b6101608e01614055565b90509295989b509295989b509295989b565b8a81526001600160a01b038a81166020830152610140604083018190525f916141788483018d6136d8565b9150808b166060850152508860808401528760a08401528660c08401528560e08401528281036101008401526141ae81866136d8565b9150506141bf610120830184613884565b9b9a505050505050505050505056feac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077ba2646970667358221220dc2b1c7af753ab9e1a7a56050c60860262e4057b2faa53df6cec6788261b617d64736f6c63430008160033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
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.