Contract 0xcf619207c73ce5e5cf6007b53736170bd1eefcdc 2

Txn Hash Method
Block
From
To
Value [Txn Fee]
0x8b0116b38dc17988feff467105bfc6d9bb5efd3e91ae99895403b1b2df90d21bAuto Balance For...110236922022-10-05 22:39:0129 secs ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.00101178327
0xdc969bf296bf5eb6f548f13b336f304e213c98364dd9533d0cf68af01d90c2f3Auto Balance For...110236892022-10-05 22:38:3159 secs ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012400205
0x415c7da5c349e90e7df91e9965cc14d3b9ca6d27ddd8e3f093aa9062778ded52Auto Balance For...110236832022-10-05 22:38:011 min ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x353908236058129e2303528d265b6d3f57865efc6b44cf9717c8406197035d18Auto Balance For...110236782022-10-05 22:37:311 min ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001011781296
0x78de4a2f4a8d98f8d245fb8976cc26d87d06f3f7e216d277ab53d85328cc1e4cAuto Balance For...110236732022-10-05 22:37:012 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x43ebda4d2b8bd8d5f16b4d99da2104341d4c028e90958bf55a9dcc28f8d8a524Auto Balance For...110236702022-10-05 22:36:312 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x3019e08404dc9385b758835ebb10a4828b351c11b93b1c3de2ac2b83f53cd347Auto Balance For...110236622022-10-05 22:36:013 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001011781296
0xf8dc49b8c22d6b3893414741d1d1aee0d79d697c1fdcacc0c1a599a57d4216acAuto Balance For...110236582022-10-05 22:35:313 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x297c4a6f62c1cc11c32af2ece211429bc50f28d044a3fe7e9b4a5c41700c2a53Auto Balance For...110236532022-10-05 22:34:514 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x1b12403e4cc0ff62278017029a3c4ece03e5d216ed7481744abd4122795763c4Auto Balance For...110236502022-10-05 22:34:215 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001011781296
0xd023ec66f52321c6e69cd3214cf161bda152632f7923365051d0cc80b1ed7c79Auto Balance For...110236442022-10-05 22:34:015 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001011781296
0x5a6f91f2ef6b910d1983da718f1246a54888b6a667c57795a2e23be21a7bf07fAuto Balance For...110236392022-10-05 22:33:216 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x7713922231507e11f81e14a63a890989c25ec072ed98b8287fef9d9146bea795Auto Balance For...110236352022-10-05 22:32:516 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001011781296
0xb785e83314f9dc8b81ffdfc3e15068d0d17eb90e9b6422947cf7ce86366bf69dAuto Balance For...110236322022-10-05 22:32:277 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001011893825
0xb68f2ebb5a81515ef6bd884c053e04054795a1c4eb56c0177bf07fbf052ca8e0Auto Balance For...110236252022-10-05 22:32:017 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x361a2a155aed700ebec466384d4fa24f85fdc6440a6e45ce39fb3fa56718bdfdAuto Balance For...110236212022-10-05 22:31:218 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0xa9354b54210660e6d6bc640d59ac3937176c99e2f86a3e87a39505964e99d063Auto Balance For...110236162022-10-05 22:31:018 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001011781296
0xa6bf2ec155c54e1cb0a29d25a5e431773125b73d18c250f22d74b6c4647b26bdAuto Balance For...110236132022-10-05 22:30:318 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x099e258538252b2635c4469e61dfa576f4703a744d72462f6fe7346449ea4f6aAuto Balance For...110236052022-10-05 22:30:019 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0xa3ee6a8f9fbd175f1b915ea7312139dc238ad8aac80ce902694ff9426dd0b355Auto Balance For...110236002022-10-05 22:29:319 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x8b6eb7902d0bbac1c1c9271e983b76fc3390591c8441460e26f0548c28bcc4b2Auto Balance For...110235952022-10-05 22:29:0110 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001011879019
0xc20a393dbad2d688d92f2c91cd410d8e7b917e87d06f1e7b5c5fa624d42232bcAuto Balance For...110235902022-10-05 22:28:3110 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x13d9284acebd2bfa093dbcb1fab5f2f3d53d667d6d1f47e556dcdfe3f8f493a9Auto Balance For...110235862022-10-05 22:28:0111 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x9cab3cc0cadc3dc0dcfb0c1b57255abd6ea4c8b7f62bab9150306c64ceba77e0Auto Balance For...110235812022-10-05 22:27:3111 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
0x9d2fd9ad96c5be5de9d4369dea5d4fe6cf5ec255584802a8b89e3e64a39f0a3dAuto Balance For...110235762022-10-05 22:27:0112 mins ago0x4935b168ea3481e52922fa3052586afcc7ebadbb IN  0xcf619207c73ce5e5cf6007b53736170bd1eefcdc0 FTM0.001012398231
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x6b78c8c09fb70b4b464912788235275fae9137f221a7f9f9a4e55ce9e00d68d8102054092022-08-29 2:04:3737 days 20 hrs ago 0x4935b168ea3481e52922fa3052586afcc7ebadbb  Contract Creation0 FTM
[ Download CSV Export 
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
MasterPlatypusV3

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 9 : MasterPlatypusV3.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "./interfaces/IMasterPlatypusV3.sol";
import "./interfaces/IMARKET.sol";
import "./interfaces/IveMARKET.sol";
import "./interfaces/IAsset.sol";
import "./libraries/Math.sol";
import "./libraries/AddressArray.sol";

contract MasterPlatypusV3 is IMasterPlatypusV3{ 
    /** 
        pid:  0 - USDT_LP
              1 - DAI_LP
              2 - USDC_LP
    */
    struct LPStakedUserInfo {
        uint256 pid;
        uint256 lpAmount;
        uint256 rewardAmount;
        uint256 rewardLastTimestamp; // second        
        uint256 autoBalancePeriod;  // second, 0- no auto_balance
        uint256 autoBalanceLastTimestamp; //second
    }

    struct PTPStakedUserInfo {
        uint256 ptpAmount;
        uint256 totalPtpAmount; // for autoInvest: totalPtpAmount-ptpAmount: will be staked step by step, should create veptp reward
        uint256 rewardAmount;
        uint256 rewardLastTimestamp; // second        
    }
    
    address private _owner;
    IMARKET private PTP;
    IveMARKET private VePTP;

    // fantom testnet
    address private fUSDT_LP = address(0xd0E8f96191D3eE2392D7780c85f7103D4E2335D6);
    address private DAI_LP = address(0x248e0900F1e6B0a5e364a103E24bB5C49A717577);
    address private USDC_LP = address(0x4daF18138E7B1620f141B6BAa76A60cDcBD02b41);   

    address[] public lpTokens;
    address[] private _lpStakers;
    mapping(uint256 => mapping(address => LPStakedUserInfo)) private _lpStakedUserInfo;
    mapping(address => PTPStakedUserInfo) private _ptpStakedUserInfo;
    
    uint256 private _rfBasePTP = 1157400000; 
    uint256 private _rfBoostPTP = 37870000000000000; 
    uint256 private _rfVePTP = 3858100000000; 
    uint256 private _rfVePTPMultiple = 100;    // users can get reward maximum 100 times of staked PTP amount
    
    event PTPBaseFactorUpdated(address indexed user, uint256 oldFactor, uint256 newFactor);
    event PTPBoostFactorUpdated(address indexed user, uint256 oldFactor, uint256 newFactor);
    event VePTPFactorUpdated(address indexed user, uint256 oldFactor, uint256 newFactor);
    event VePTPMultipleFactorUpdated(address indexed user, uint256 oldFactor, uint256 newFactor);
    event PTPUpdated(address indexed user, address indexed oldPtp, address indexed newPtp);
    event VePTPUpdated(address indexed user, address indexed oldVePtp, address indexed newVePtp);
    event LPAdded(address indexed user, address indexed lptoken);
    event LPDeleted(address indexed user, address indexed lptoken);
    event LPStaked(address indexed user, address indexed lptoken, uint256 amount);
    event LPUnStaked(address indexed user, address indexed lptoken, uint256 amount);
    event PTPStaked(address indexed user, address indexed ptptoken, uint256 amount);
    event PTPUnStaked(address indexed user, address indexed ptptoken, uint256 amount);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    event PTPClaimed(address indexed user, uint256 amount);
    event VePTPClaimed(address indexed user, uint256 amount);
    event AutoBalanced(uint256 balancedUserCount);
    event AutoBalancedUser(address user, uint256 oldLPAmount1, uint256 newLPAmount1,uint256 oldLPAmount2, uint256 newLPAmount2,uint256 oldLPAmount3, uint256 newLPAmount3);
    event SetAutoBalanceUser(address user, bool isAutoBalance, uint256 autoBalancePeriod);   

    using AddressArray for address[]; 

    constructor () {       
        _owner = msg.sender;        
        lpTokens.push(fUSDT_LP);
        lpTokens.push(DAI_LP);
        lpTokens.push(USDC_LP);
    }   

    modifier onlyOwner() {
        require(_owner == msg.sender, "Ownable: caller is not the owner");
        _;
    } 

    function renounceOwnership() public onlyOwner {
        _transferOwnership(address(0));
    }

    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        require(newOwner != _owner, "Ownable: same owner");
        _transferOwnership(newOwner);
    }

    function _transferOwnership(address newOwner) internal {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }

    function isLpExist(address tk) private view returns (bool) {        
        return AddressArray.isExist(lpTokens, tk);
    }
    
    function addLPToken(address lpToken) public onlyOwner {
        require(lpToken != address(0), "addLPToken: zero address");
        require(Address.isContract(address(lpToken)), 'addLPToken: LP token must be a valid contract');
        require(isLpExist(lpToken) == false, "addLPToken: already exist");        
        AddressArray.addAddr(lpTokens, lpToken);
        emit LPAdded(msg.sender, lpToken);
    }

    function deleteLPToken(address lpToken) public onlyOwner {       
        AddressArray.deleteAddrOrder(lpTokens, lpToken);        
        emit LPDeleted(msg.sender, lpToken);
    }

    function ptp() public override view returns (address) {
        return address(PTP);
    }

    function veptp() public override view returns (address) {
        return address(VePTP);
    }

    function factors() public view returns (uint256 rfBasePTP, uint256 rfBoostPTP, uint256 rfVePTP, uint256 rfVePTPMultiple) {
        rfBasePTP = _rfBasePTP;
        rfBoostPTP = _rfBoostPTP;
        rfVePTP = _rfVePTP;
        rfVePTPMultiple =_rfVePTPMultiple;
    }

    function updateBaseRewardFactorPTP(uint256 newFactor) public onlyOwner {
        require (newFactor > 0, "updateBaseRewardFactorPTP: reward factor can not be negative");
        uint256 oldFactor = _rfBasePTP;
        _rfBasePTP = newFactor;
        emit PTPBaseFactorUpdated(msg.sender, oldFactor, newFactor);
    }

    function updateBoostRewardFactorPTP(uint256 newFactor) public onlyOwner {
        require (newFactor > 0, "updateBoostRewardFactorPTP: reward factor can not be negative");
        uint256 oldFactor = _rfBoostPTP;
        _rfBoostPTP = newFactor;
        emit PTPBoostFactorUpdated(msg.sender, oldFactor, newFactor);
    }

    function updateRewardFactorVePTP(uint256 newFactor) public onlyOwner {
        require (newFactor > 0, "updateRewardFactorVePTP: reward factor can not be negative");
        uint256 oldFactor = _rfVePTP;
        _rfVePTP = newFactor;
        emit VePTPFactorUpdated(msg.sender, oldFactor, newFactor);
    }

    function updateRewardFactorVePTPMultiple(uint256 newFactor) public onlyOwner {
        require (newFactor > 0, "updateRewardFactorVePTPMultiple: multiple reward factor can not be negative");
        uint256 oldFactor = _rfVePTPMultiple;
        _rfVePTPMultiple = newFactor;
        emit VePTPMultipleFactorUpdated(msg.sender, oldFactor, newFactor);
    }

    // LP Staking / Unstaking
    function isExistLPStakedUserInfo(uint256 pid, address user) private view returns (bool) {
        return _lpStakedUserInfo[pid][user].lpAmount > 0;
    }

    function _totalLPAmount() internal view returns (uint256) {
        uint256 totalLpAmounts;
        for (uint i=0;i<lpTokens.length;i++) {
            totalLpAmounts += IAsset(lpTokens[i]).totalSupply() / (10**IAsset(lpTokens[i]).decimals());
        }
        return totalLpAmounts;
    }

    function _coverageRatio (uint256 pid) private view returns (uint256) {
        if (IAsset(lpTokens[pid]).liability() > 0) 
            return IAsset(lpTokens[pid]).cash() * 100000 / IAsset(lpTokens[pid]).liability();
        return 0;
    }

    function _calcIncreasedBasePTPReward (uint256 pid, LPStakedUserInfo storage userinfo) private view returns (uint256) {
        if (block.timestamp - userinfo.rewardLastTimestamp > 60 && IAsset(lpTokens[pid]).totalSupply() > 0)
            return _rfBasePTP * userinfo.lpAmount * (block.timestamp - userinfo.rewardLastTimestamp) * _coverageRatio(pid) * _totalLPAmount() / (lpTokens.length * (IAsset(lpTokens[pid]).totalSupply() / (10**IAsset(lpTokens[pid]).decimals())) * 10**18 * 100000);
        else return 0;
    }

    function _calcIncreasedBoostPTPReward (uint256 pid, address user, LPStakedUserInfo storage userinfo) private view returns (uint256) {
        if (block.timestamp - userinfo.rewardLastTimestamp > 60) {
            uint256 sum = _sumSqrtLPVe(pid);
            if (sum > 0) 
                return _rfBoostPTP * Math.sqrt(userinfo.lpAmount * VePTP.balanceOf(user)) * (block.timestamp - userinfo.rewardLastTimestamp) / (sum * 10**18);
            else return 0;
        } else return 0;
    }

    function _sumSqrtLPVe (uint256 pid) private view returns (uint256) {
        uint256 sum;
        for (uint256 i=0;i<VePTP.holders().length;i++) {
            sum += Math.sqrt(_lpStakedUserInfo[pid][VePTP.holders()[i]].lpAmount * VePTP.balanceOf(VePTP.holders()[i]));
        }
        return sum;
    }

    function _calcPTPReward (uint256 pid, address user, LPStakedUserInfo storage userinfo) private view returns (uint256) {
        uint256 baseIncreasedPTP = _calcIncreasedBasePTPReward(pid, userinfo);
        uint256 boostIncreasedPTP = _calcIncreasedBoostPTPReward(pid, user, userinfo);
        return userinfo.rewardAmount + baseIncreasedPTP + boostIncreasedPTP;
    }

    function _updateLPStakedUserInfoForStaking (uint256 pid, address user, uint256 amount) private {        
        LPStakedUserInfo storage userinfo = _lpStakedUserInfo[pid][user];

        if (isExistLPStakedUserInfo(pid, user)) {            
            _lpStakedUserInfo[pid][user].rewardAmount = _calcPTPReward(pid, user, userinfo);            
        } else {
            _lpStakedUserInfo[pid][user].rewardAmount = 0;
        }
        
        _lpStakedUserInfo[pid][user].rewardLastTimestamp = block.timestamp;
        _lpStakedUserInfo[pid][user].lpAmount += amount / (10**IAsset(lpTokens[pid]).decimals());

        AddressArray.addAddr(_lpStakers, user);
    }

    function _updateLPStakedUserInfoForStakingFromOther (uint256 pid, address user, uint256 amount, uint256 autoBalancePeriod) private {        
        LPStakedUserInfo storage userinfo = _lpStakedUserInfo[pid][user];

        if (isExistLPStakedUserInfo(pid, user)) {            
            _lpStakedUserInfo[pid][user].rewardAmount = _calcPTPReward(pid, user, userinfo);            
        } else {
            _lpStakedUserInfo[pid][user].rewardAmount = 0;
        }
        
        _lpStakedUserInfo[pid][user].rewardLastTimestamp = block.timestamp;
        _lpStakedUserInfo[pid][user].lpAmount += amount / (10**IAsset(lpTokens[pid]).decimals());        
        _lpStakedUserInfo[pid][user].autoBalanceLastTimestamp = block.timestamp;

        _lpStakedUserInfo[0][user].autoBalancePeriod = autoBalancePeriod;
        _lpStakedUserInfo[1][user].autoBalancePeriod = autoBalancePeriod;
        _lpStakedUserInfo[2][user].autoBalancePeriod = autoBalancePeriod;

        AddressArray.addAddr(_lpStakers, user);
    }

    function _updateLPStakedUserInfoForUnStaking (uint256 pid, address user, uint256 amount) private {
        require(isExistLPStakedUserInfo(pid, user), "_updateLPStakedUserInfoForUnStaking: user didn't stake lp token");    
        _lpStakedUserInfo[pid][user].rewardAmount = 0;
        _lpStakedUserInfo[pid][user].rewardLastTimestamp = block.timestamp;
        _lpStakedUserInfo[pid][user].lpAmount -= amount / (10**IAsset(lpTokens[pid]).decimals());
        
        _lpStakedUserInfo[0][user].autoBalancePeriod = 0;
        _lpStakedUserInfo[1][user].autoBalancePeriod = 0;
        _lpStakedUserInfo[2][user].autoBalancePeriod = 0;

        bool isLPStaked = false;
        for (uint i=0;i<lpTokens.length;i++) {
            if (isExistLPStakedUserInfo(i, user)) isLPStaked = true;
        }

        if (!isLPStaked) AddressArray.deleteAddr(_lpStakers, user);
    }

    struct Amounts {
        uint256 amt1;
        uint256 amt2;
        uint256 amt3;
    }

    function _setAmounts (
        uint256 a1,
        uint256 a2,
        uint256 a3
    ) private pure returns (Amounts memory amounts) {
        amounts = Amounts(a1, a2, a3);
    }

    function _isAutoBalance (address user) private view returns (bool) {
        return _lpStakedUserInfo[0][user].autoBalancePeriod > 0;
    }

    function isAutoBalance (address user) public view returns (bool) {
        return _isAutoBalance(user);
    }

    function autoBalanceForLPStakers () public {
        
        uint256 autoBalancedUserCount = 0;
        
        for (uint i=0;i<_lpStakers.length;i++) {            
            bool isOverPeriod = block.timestamp - _lpStakedUserInfo[0][_lpStakers[i]].autoBalanceLastTimestamp >= _lpStakedUserInfo[0][_lpStakers[i]].autoBalancePeriod;
            if (_isAutoBalance(_lpStakers[i]) && isOverPeriod) {
                Amounts memory tAPRs = _setAmounts (_totalAPR(0, _lpStakers[i]), _totalAPR(1, _lpStakers[i]), _totalAPR(2, _lpStakers[i]));
                uint256 tAPR = tAPRs.amt1 + tAPRs.amt2 + tAPRs.amt3;

                if (tAPR > 0) {
                    uint256 totalLPAmount = _lpStakedUserInfo[0][_lpStakers[i]].lpAmount + _lpStakedUserInfo[1][_lpStakers[i]].lpAmount + _lpStakedUserInfo[2][_lpStakers[i]].lpAmount;
                    Amounts memory newLPAmounts = _setAmounts (totalLPAmount * tAPRs.amt1 / tAPR, totalLPAmount * tAPRs.amt2 / tAPR, totalLPAmount * tAPRs.amt3 / tAPR);
                    
                    _lpStakedUserInfo[0][_lpStakers[i]].lpAmount = newLPAmounts.amt1;
                    _lpStakedUserInfo[1][_lpStakers[i]].lpAmount = newLPAmounts.amt2;
                    _lpStakedUserInfo[2][_lpStakers[i]].lpAmount = newLPAmounts.amt3;

                    _lpStakedUserInfo[0][_lpStakers[i]].autoBalanceLastTimestamp = block.timestamp;
                    _lpStakedUserInfo[1][_lpStakers[i]].autoBalanceLastTimestamp = block.timestamp;
                    _lpStakedUserInfo[2][_lpStakers[i]].autoBalanceLastTimestamp = block.timestamp;
                    autoBalancedUserCount ++;
                }
            }
        }

        emit AutoBalanced(autoBalancedUserCount);
    }

    function setAutoBalanceForLPStaker (address user, uint256 autoBalancePeriod) public {
        for (uint i=0;i<lpTokens.length;i++) {
            _lpStakedUserInfo[i][user].autoBalancePeriod = autoBalancePeriod;
            _lpStakedUserInfo[i][user].autoBalanceLastTimestamp = block.timestamp;
        }

        if (autoBalancePeriod > 0) {
            emit SetAutoBalanceUser(user, true, autoBalancePeriod);
        } else {
            emit SetAutoBalanceUser(user, false, autoBalancePeriod);
        }
    }

    function autoBalanceForLPStaker (address user) public {
        Amounts memory tAPRs = _setAmounts (_totalAPR(0, user), _totalAPR(1, user), _totalAPR(2, user));
        uint256 tAPR = tAPRs.amt1 + tAPRs.amt2 + tAPRs.amt3;

        if (tAPR > 0) {
            uint256 totalLPAmount = _lpStakedUserInfo[0][user].lpAmount + _lpStakedUserInfo[1][user].lpAmount + _lpStakedUserInfo[2][user].lpAmount;
            Amounts memory newLPAmounts = _setAmounts (totalLPAmount * tAPRs.amt1 / tAPR, totalLPAmount * tAPRs.amt2 / tAPR, totalLPAmount * tAPRs.amt3 / tAPR);
            
            emit AutoBalancedUser(
                user, 
                _lpStakedUserInfo[0][user].lpAmount, 
                newLPAmounts.amt1,
                _lpStakedUserInfo[1][user].lpAmount, 
                newLPAmounts.amt2,
                _lpStakedUserInfo[2][user].lpAmount, 
                newLPAmounts.amt3
            );

            _lpStakedUserInfo[0][user].lpAmount = newLPAmounts.amt1;
            _lpStakedUserInfo[1][user].lpAmount = newLPAmounts.amt2;
            _lpStakedUserInfo[2][user].lpAmount = newLPAmounts.amt3;            

            _lpStakedUserInfo[0][user].autoBalanceLastTimestamp = block.timestamp;
            _lpStakedUserInfo[1][user].autoBalanceLastTimestamp = block.timestamp;
            _lpStakedUserInfo[2][user].autoBalanceLastTimestamp = block.timestamp;            
        }        
    }

    function stakingLP (uint256 pid, uint256 amount) public { 
        require(address(PTP) != address(0), "stakingLP: PTP does not set");        
        require(IERC20(lpTokens[pid]).balanceOf(msg.sender) >= amount, "stakingLP: insufficient amount");
        IERC20(lpTokens[pid]).transferFrom(msg.sender, address(this), amount);
        _updateLPStakedUserInfoForStaking(pid, msg.sender, amount);
        emit LPStaked(msg.sender, lpTokens[pid], amount);
    }

    function stakingLPFromOther (address from, uint256 pid, uint256 amount, uint256 autoBalancePeriod) external override { 
        require(address(PTP) != address(0), "stakingLP: PTP does not set");        
        require(IERC20(lpTokens[pid]).balanceOf(from) >= amount, "stakingLP: insufficient amount");
        IERC20(lpTokens[pid]).transferFrom(from, address(this), amount);
        _updateLPStakedUserInfoForStakingFromOther(pid, from, amount, autoBalancePeriod);
        emit LPStaked(from, lpTokens[pid], amount);
    }    

    // whenever unstaking LP token, reward token should be transferred to msg sender
    function unStakingLP(uint256 pid, uint256 amount) public {
        require(address(PTP) != address(0), "unStakingLP: PTP does not set");
        require(isExistLPStakedUserInfo(pid, msg.sender), "unStakingLP: user didn't stake lp token");
        LPStakedUserInfo storage userinfo = _lpStakedUserInfo[pid][msg.sender];
        require(userinfo.lpAmount >= amount / (10**IAsset(lpTokens[pid]).decimals()), "unStakingLP: insufficient amount");
        IERC20(lpTokens[pid]).transfer(msg.sender, amount);
        uint256 rewardAmount = _calcPTPReward(pid, msg.sender, userinfo);        
        PTP.transferWithoutFee(msg.sender, rewardAmount);
        _updateLPStakedUserInfoForUnStaking(pid, msg.sender, amount);
        emit LPUnStaked(msg.sender, lpTokens[pid], amount);
    }

    // PTP Staking / Unstaking
    function isExistPTPStakedUserInfo(address user) private view returns (bool) {
        return _ptpStakedUserInfo[user].ptpAmount > 0;
    }

    function _calcIncreasedVePTPReward (address user, PTPStakedUserInfo storage userinfo) private view returns (uint256) {
        if (block.timestamp - userinfo.rewardLastTimestamp > 60) {            
            uint256 nReward = _rfVePTP * userinfo.totalPtpAmount * (block.timestamp - userinfo.rewardLastTimestamp) / (10**18); // normal reward
            uint256 lockReward = PTP.calcLockReward(user, _rfVePTP, userinfo.rewardLastTimestamp);
            return nReward + lockReward;            
        } else return 0;
    }

    function _calcVePTPReward (address user, PTPStakedUserInfo storage userinfo) private view returns (uint256) {                
        uint256 rAmount = userinfo.rewardAmount + _calcIncreasedVePTPReward(user, userinfo);
        if (rAmount + VePTP.balanceOf(user) > userinfo.totalPtpAmount * _rfVePTPMultiple) {
            if (userinfo.totalPtpAmount * _rfVePTPMultiple > VePTP.balanceOf(user)) {
                rAmount = userinfo.totalPtpAmount * _rfVePTPMultiple - VePTP.balanceOf(user);
            } else return 0;
        }
        return rAmount;
    }

    function calcVePTPReward (address user, uint256 ptpAmount, uint256 stakingTimeSecond) public view returns (uint256) {
        uint256 rAmount = _rfVePTP * ptpAmount * stakingTimeSecond / (10**18) + PTP.calcLockRewardAtMoment(user, _rfVePTP); 
        if (rAmount + VePTP.balanceOf(user) > ptpAmount * _rfVePTPMultiple) {
            if(ptpAmount * _rfVePTPMultiple > VePTP.balanceOf(user)) {
                rAmount = ptpAmount * _rfVePTPMultiple - VePTP.balanceOf(user);
            } else return 0;
        }
        return rAmount;
    }

    function calcVePTPRewardPub (address user) public override view returns (uint256) {
        return _calcVePTPReward(user, _ptpStakedUserInfo[user]);
    }
    
    function updatePTPStakedUserInfoForStaking (address user, uint256 amount) public override {
        return _updatePTPStakedUserInfoForStaking(user, amount);
    }

    function updatePTPStakedUserInfoForStakingFirstInvest (address user, uint256 amount, uint256 totalAmount) public {
        _ptpStakedUserInfo[user].rewardAmount = 0;
        _ptpStakedUserInfo[user].rewardLastTimestamp = block.timestamp;
        _ptpStakedUserInfo[user].ptpAmount += amount;
        _ptpStakedUserInfo[user].totalPtpAmount += totalAmount;
    }

    function updatePTPStakedUserInfoForStakingStepInvest (address user, uint256 unitAmount, uint256 prevUnitAmount, uint256 investCount, uint256 investedCount) public {
        _ptpStakedUserInfo[user].rewardAmount = 0;
        _ptpStakedUserInfo[user].rewardLastTimestamp = block.timestamp;
        _ptpStakedUserInfo[user].ptpAmount += unitAmount;
        _ptpStakedUserInfo[user].totalPtpAmount = _ptpStakedUserInfo[user].totalPtpAmount - prevUnitAmount*(investCount-investedCount) + unitAmount*(investCount-investedCount);
    }

    function _updatePTPStakedUserInfoForStaking (address user, uint256 amount) private {
        _ptpStakedUserInfo[user].rewardAmount = 0;
        _ptpStakedUserInfo[user].rewardLastTimestamp = block.timestamp;
        _ptpStakedUserInfo[user].ptpAmount += amount;
        _ptpStakedUserInfo[user].totalPtpAmount += amount;
    }

    function _updatePTPStakedUserInfoForUnStaking (address user, uint256 amount) private {
        require(isExistPTPStakedUserInfo(user), "_updatePTPStakedUserInfoForUnStaking: user didn't stake PTP token");    
        _ptpStakedUserInfo[user].rewardAmount = 0;
        _ptpStakedUserInfo[user].rewardLastTimestamp = block.timestamp;
        if(_ptpStakedUserInfo[user].ptpAmount >= amount)
            _ptpStakedUserInfo[user].ptpAmount -= amount;
        else _ptpStakedUserInfo[user].ptpAmount = 0;
        if(_ptpStakedUserInfo[user].totalPtpAmount >= amount)
            _ptpStakedUserInfo[user].totalPtpAmount -= amount;
    }

    function stakingPTP (uint256 amount) public {
        require(address(VePTP) != address(0), "stakingPTP: VePTP does not set");        
        require(PTP.balanceOf(msg.sender) >= amount, "stakingPTP: insufficient amount");
        PTP.transferFromWithoutFee(msg.sender, address(this), amount);        
        VePTP.mint(msg.sender, _calcVePTPReward(msg.sender, _ptpStakedUserInfo[msg.sender]));
        _updatePTPStakedUserInfoForStaking(msg.sender, amount);
        emit PTPStaked(msg.sender, address(PTP), amount);
    }    

    function unStakingPTP(uint256 amount) public {
        require(address(VePTP) != address(0), "unStakingPTP: PTP does not set");
        require(isExistPTPStakedUserInfo(msg.sender), "unStakingPTP: user didn't stake ptp token");        
        PTP.transferWithoutFee(msg.sender, amount);
        VePTP.deleteBalance(msg.sender);
        _updatePTPStakedUserInfoForUnStaking(msg.sender, amount);
        emit PTPUnStaked(msg.sender, address(PTP), amount);
    }

    function directStakingPTP (address user) public override {
        uint256 rewardAmount;
        for (uint256 i=0;i<lpTokens.length;i++) {
            LPStakedUserInfo storage userinfo = _lpStakedUserInfo[i][user];
            rewardAmount += _calcPTPReward(i, user, userinfo);                      
        }
        PTP.transferWithoutFee(address(this), rewardAmount*10**PTP.decimals());
        if (PTP.lockedTimestamp(user) + PTP.lockedDeadline(user) > block.timestamp && PTP.isRelocked(user)) 
            PTP.setLockInfo(user, rewardAmount*10**PTP.decimals(), PTP.lockedDeadline(user), true);
        _updateLPStakedUserInfoForMultiClaim(user);
        _updatePTPStakedUserInfoForStaking(user, rewardAmount*10**PTP.decimals());        
    }

    // Claim PTP
    function _updateLPStakedUserInfoForClaim (uint256 pid, address user) private {        
        _lpStakedUserInfo[pid][user].rewardAmount = 0;
        _lpStakedUserInfo[pid][user].rewardLastTimestamp = block.timestamp;
    }

    function _updateLPStakedUserInfoForMultiClaim (address user) private {    
        for (uint256 i=0;i<lpTokens.length;i++) {
            _updateLPStakedUserInfoForClaim(i, user);
        }            
    }

    function claimPTP(uint256 pid) external {
        LPStakedUserInfo storage userinfo = _lpStakedUserInfo[pid][msg.sender];
        uint256 rewardAmount = _calcPTPReward(pid, msg.sender, userinfo);
        PTP.transferWithoutFee(msg.sender, rewardAmount*10**PTP.decimals());
        _updateLPStakedUserInfoForClaim(pid, msg.sender);
        emit PTPClaimed(msg.sender, rewardAmount*10**PTP.decimals());
    }

    function multiClaimPTP() external {
        return _multiClaimPTP(msg.sender);
    }

    function _multiClaimPTP(address user) private {
        uint256 rewardAmount;
        for (uint256 i=0;i<lpTokens.length;i++) {
            LPStakedUserInfo storage userinfo = _lpStakedUserInfo[i][user];
            rewardAmount += _calcPTPReward(i, user, userinfo);                      
        }
        PTP.transferWithoutFee(user, rewardAmount*10**PTP.decimals());
        _updateLPStakedUserInfoForMultiClaim(user);
        emit PTPClaimed(user, rewardAmount*10**PTP.decimals());
    }

    // Claim vePTP
    function _updatePTPStakedUserInfoForClaim (address user) private {        
        _ptpStakedUserInfo[user].rewardAmount = 0;
        _ptpStakedUserInfo[user].rewardLastTimestamp = block.timestamp;
    }

    function claimVePTP() external {
        _claimVePTP(msg.sender);
    }

    function claimVePTPFrom(address user) public override {
        _claimVePTP(user);
    }
    
    function _claimVePTP(address user) private {
        PTPStakedUserInfo storage userinfo = _ptpStakedUserInfo[user];
        uint256 rewardAmount = _calcVePTPReward(user, userinfo);
        VePTP.mint(user, rewardAmount);
        _updatePTPStakedUserInfoForClaim(user);
        emit VePTPClaimed(user, rewardAmount);
    }

    function updatePTP(IMARKET newPtp) public onlyOwner {
        require(address(newPtp) != address(0), "updatePTP: zero address");
        require(Address.isContract(address(newPtp)), "updatePTP: invalied contract");
        emit PTPUpdated(msg.sender, address(PTP), address(newPtp));
        PTP = newPtp;        
    }

    function updateVePTP(IveMARKET newVePtp) public onlyOwner {
        require(address(newVePtp) != address(0), "updateVePTP: zero address");
        require(Address.isContract(address(newVePtp)), "updateVePTP: invalied contract");        
        emit VePTPUpdated(msg.sender, address(VePTP), address(newVePtp));
        VePTP = newVePtp;        
    }

    function lpStakedInfo(uint256 pid, address user) 
        public 
        view 
        override 
        returns (
            uint256 lpAmount, 
            uint256 rewardAmount,
            uint256 rewardLastTimestamp,
            uint256 autoBalancePeriod,
            uint256 autoBalanceLastTimestamp
        ) 
    {
        LPStakedUserInfo storage userinfo = _lpStakedUserInfo[pid][user];
        rewardAmount = _calcPTPReward(pid, user, userinfo);
        lpAmount = userinfo.lpAmount * (10**IAsset(lpTokens[pid]).decimals());
        rewardLastTimestamp = userinfo.rewardLastTimestamp;
        autoBalancePeriod = userinfo.autoBalancePeriod;
        autoBalanceLastTimestamp = userinfo.autoBalanceLastTimestamp;
    }

    function multiLpStakedInfo(address user) 
        public 
        view 
        returns (
            uint256,
            uint256[] memory, 
            uint256[] memory
        ) 
    {        
        uint256 totalRewardAmount;
        uint256[] memory lpAmounts = new uint256[](lpTokens.length);
        uint256[] memory rewardAmounts = new uint256[](lpTokens.length);
        for (uint i = 0; i<lpTokens.length; i++) {   
            LPStakedUserInfo storage userinfo = _lpStakedUserInfo[i][user];
            uint256 rAmount = _calcPTPReward(i, user, userinfo);
            totalRewardAmount += rAmount;
            lpAmounts[i] = userinfo.lpAmount * (10**IAsset(lpTokens[i]).decimals());
            rewardAmounts[i] = rAmount;
        }
        return (totalRewardAmount, lpAmounts, rewardAmounts);
    }

    function ptpStakedInfo(address user) public view returns (uint256 ptpAmount, uint256 totalPtpAmount, uint256 rewardAmount) {
        PTPStakedUserInfo storage userinfo = _ptpStakedUserInfo[user];
        rewardAmount = _calcVePTPReward(user, userinfo);
        totalPtpAmount = userinfo.totalPtpAmount;
        ptpAmount = userinfo.ptpAmount;
    }  

    function coverageRatio (uint256 pid) public view returns (uint256) {
        return _coverageRatio(pid);
    }

    function _baseAPR (uint256 pid) private view returns (uint256) {     
        if (IAsset(lpTokens[pid]).totalSupply() > 0)   
            return _rfBasePTP * (365 * 24 * 60 * 60) * _coverageRatio(pid) * _totalLPAmount() * 100 * 10**18 / (lpTokens.length * (IAsset(lpTokens[pid]).totalSupply() / (10**IAsset(lpTokens[pid]).decimals())) * 10**18 * 100000);
        else return 0;
    }

    function _boostedAPR (uint256 pid, address user) private view returns (uint256) {
        uint256 sum = _sumSqrtLPVe(pid);
        if (isExistLPStakedUserInfo(pid, user) && sum > 0) {   
            LPStakedUserInfo storage userinfo = _lpStakedUserInfo[pid][user];
            return _rfBoostPTP * Math.sqrt(VePTP.balanceOf(user)) * (365 * 24 * 60 * 60) * 100 * 10**18 / (Math.sqrt(userinfo.lpAmount) * sum * 10**18);      
        }
        return 0;
    }

    function _totalAPR (uint256 pid, address user) private view returns (uint256) {
        return _baseAPR(pid) + _boostedAPR(pid, user);
    }

    function baseAPR (uint256 pid) external view override returns (uint256) {     
        return _baseAPR(pid);
    }

    function boostedAPR (uint256 pid, address user) external view override returns (uint256) {
        return _boostedAPR(pid, user);
    }

    function totalAPR (uint256 pid, address user) external view override returns (uint256) {
        return _totalAPR(pid, user);
    }

    function estimatedBoostedAPRFromVePTP (uint256 pid, address user, uint256 lpAmount, uint256 vePTPAmount) public view returns (uint256) {
        uint256 sum = _sumSqrtLPVe(pid) - Math.sqrt(_lpStakedUserInfo[pid][user].lpAmount * VePTP.balanceOf(user)) + Math.sqrt(lpAmount * vePTPAmount);
        if (sum > 0 && lpAmount > 0) {            
            return _rfBoostPTP * Math.sqrt(vePTPAmount) * (365 * 24 * 60 * 60) * 100 * 10**18 / (Math.sqrt(lpAmount) * sum * 10**18);                       
        }
        return 0;
    }

    function estimatedBoostedAPRFromPTP (uint256 pid, address user, uint256 lpAmount, uint256 ptpAmount, uint256 stakingTimeSecond) public view returns (uint256) {        
        uint256 vePTPAmount = _rfVePTP * ptpAmount * stakingTimeSecond / (10**18) + VePTP.balanceOf(user);
        
        if (vePTPAmount > ptpAmount * _rfVePTPMultiple) {
            vePTPAmount = ptpAmount * _rfVePTPMultiple;
        }

        uint256 sum = _sumSqrtLPVe(pid) - Math.sqrt(_lpStakedUserInfo[pid][user].lpAmount * VePTP.balanceOf(user)) + Math.sqrt(lpAmount * vePTPAmount);
        if (sum > 0 && lpAmount > 0) {            
            return _rfBoostPTP * Math.sqrt(vePTPAmount) * (365 * 24 * 60 * 60) * 100 * 10**18 / (Math.sqrt(lpAmount) * sum * 10**18);                       
        } 
        return 0;
    }

    function medianBoostedAPR (uint256 pid) external view override returns (uint256) {
        uint256 sum = _sumSqrtLPVe(pid);
        uint256 sumAPR;
        uint256 holdersCount = VePTP.holders().length;
        uint256 boostingUserCount;
        for (uint256 i=0;i<holdersCount;i++) {
            address user = VePTP.holders()[i];
            if (isExistLPStakedUserInfo(pid, user) && sum > 0) {            
                LPStakedUserInfo storage userinfo = _lpStakedUserInfo[pid][user];
                sumAPR += _rfBoostPTP * Math.sqrt(VePTP.balanceOf(user)) * (365 * 24 * 60 * 60) * 100 * 10**18 / (Math.sqrt(userinfo.lpAmount) * sum * 10**18); 
                boostingUserCount++;          
            }
        }
        
        if (boostingUserCount > 0) {
            return sumAPR / boostingUserCount;
        }

        return 0;
    }
}

File 2 of 9 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

File 3 of 9 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 4 of 9 : IMasterPlatypusV3.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

interface IMasterPlatypusV3 {        

    function stakingLPFromOther (
        address from, 
        uint256 pid, 
        uint256 amount, 
        uint256 autoBalancePeriod) external;       

    // function stakingPTPFromOther (address from, uint256 amount, uint256 investCount, uint256 investDeadline) external;

    function baseAPR (uint256 pid) external view returns (uint256);

    function boostedAPR (uint256 pid, address user) external view returns (uint256);

    function totalAPR (uint256 pid, address user) external view returns (uint256);

    function medianBoostedAPR (uint256 pid) external view returns (uint256);

    function lpStakedInfo(uint256 pid, address user) 
        external 
        view 
        returns (
            uint256 lpAmount, 
            uint256 rewardAmount, 
            uint256 rewardLastTimestamp,
            uint256 autoBalancePeriod,
            uint256 autoBalanceLastTimestamp
        );
    
    function calcVePTPRewardPub (address user) external view returns (uint256);

    function updatePTPStakedUserInfoForStaking (address user, uint256 amount) external;

    function updatePTPStakedUserInfoForStakingFirstInvest (address user, uint256 amount, uint256 totalAmount) external;

    function updatePTPStakedUserInfoForStakingStepInvest (address user, uint256 unitAmount, uint256 prevUnitAmount, uint256 investCount, uint256 investedCount) external;

    function ptp() external view returns (address);

    function veptp() external view returns (address);

    function claimVePTPFrom(address user) external;

    function directStakingPTP (address user) external;
}

File 5 of 9 : IMARKET.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

/**
 * @dev Interface of the VePtp
 */
interface IMARKET {    

    function transferWithoutFee(address to, uint256 amount) external;

    function transferFromWithoutFee(address from, address to, uint256 amount) external;

    function decimals() external view returns (uint8);

    function balanceOf(address account) external view returns (uint256);

    function marketWallet() external view returns (address);    

    function lockedTotalAmount(address user) external view returns (uint256);

    function lockedAmount(address user) external view returns (uint256);

    function lockedDeadline(address user) external view returns (uint256);

    function lockedTimestamp(address user) external view returns (uint256);

    function isRelocked(address user) external view returns (bool);

    function lockInfo(address user) external view returns (uint256 totalAmount, uint256 amount, uint256 timestamp, uint256 deadline, bool relock, uint256 curTimestamp);

    function setLockInfo(address user, uint256 amount, uint256 deadline, bool relock) external;

    function setLockInfoForFirstInvest(address user, uint256 totalAmount, uint256 amount, uint256 deadline, bool relock) external;

    function setLockInfoForStepInvest(address user, uint256 amount) external;

    function calcLockReward(address user, uint256 f, uint256 rewardLastTimestamp) external view returns (uint256);

    function calcLockRewardAtMoment(address user, uint256 f) external view returns (uint256);
}

File 6 of 9 : IveMARKET.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

/**
 * @dev Interface of the VePtp
 */
interface IveMARKET {    

    function mint(address dst, uint256 amount) external;

    function balanceOf(address account) external view returns (uint256);

    function deleteBalance(address account) external;

    function holders() external view returns (address[] memory);
}

File 7 of 9 : IAsset.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.9;

interface IAsset {
    function maxSupply() external view returns (uint256);

    function aggregateAccount() external view returns (address);

    function underlyingToken() external view returns (address);

    function decimals() external view returns (uint8);

    function underlyingTokenBalance() external view returns (uint256);

    function cash() external view returns (uint256);

    function liability() external view returns (uint256);

    function totalSupply() external view returns (uint256);
}

File 8 of 9 : Math.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

// a library for performing various math operations

library Math {
    uint256 public constant WAD = 10**18;

    // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            z = y;
            uint256 x = y / 2 + 1;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }

    //rounds to zero if x*y < WAD / 2
    function wmul(uint256 x, uint256 y) internal pure returns (uint256) {
        return ((x * y) + (WAD / 2)) / WAD;
    }

    //rounds to zero if x*y < WAD / 2
    function wdiv(uint256 x, uint256 y) internal pure returns (uint256) {
        return ((x * WAD) + (y / 2)) / y;
    }
}

File 9 of 9 : AddressArray.sol
/// math.sol -- mixin for inline numerical wizardry

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

library AddressArray {

    function _isExist (address[] storage addrs, address adr) private view returns (bool) {
        for (uint i=0;i<addrs.length;i++) {
            if (addrs[i] == adr) return true;
        }
        return false;
    }

    function isExist (address[] storage addrs, address adr) public view returns (bool) {
        return _isExist(addrs, adr);
    }

    function addAddr (address[] storage addrs, address adr) public {
        if (!_isExist(addrs, adr)) addrs.push(adr);
    }

    function deleteAddr (address[] storage addrs, address adr) public {
        uint idx;
        bool is_exist = false;

        for (uint i=0;i<addrs.length;i++) {
            if (adr == addrs[i]) {
                is_exist = true;
                idx = i;
            }
        }

        if (is_exist) {
            addrs[idx] = addrs[addrs.length-1];
            addrs.pop();
        }
    }

    function deleteAddrOrder (address[] storage addrs, address adr) public {
        uint idx;
        bool is_exist = false;
        
        for (uint i=0;i<addrs.length;i++) {
            if (adr == addrs[i]) {
                is_exist = true;
                idx = i;
            }
        }

        if (is_exist) {
            for (uint i=idx;i<addrs.length-1;i++) {
                addrs[i] = addrs[i+1];
            }
            addrs.pop();
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {
    "contracts/libraries/AddressArray.sol": {
      "AddressArray": "0x1f35fb4ba99e9676d2c2ea7b832a91fa24afe1fd"
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"balancedUserCount","type":"uint256"}],"name":"AutoBalanced","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldLPAmount1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLPAmount1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldLPAmount2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLPAmount2","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldLPAmount3","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLPAmount3","type":"uint256"}],"name":"AutoBalancedUser","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"lptoken","type":"address"}],"name":"LPAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"lptoken","type":"address"}],"name":"LPDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"lptoken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LPStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"lptoken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LPUnStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFactor","type":"uint256"}],"name":"PTPBaseFactorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFactor","type":"uint256"}],"name":"PTPBoostFactorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PTPClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"ptptoken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PTPStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"ptptoken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PTPUnStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"oldPtp","type":"address"},{"indexed":true,"internalType":"address","name":"newPtp","type":"address"}],"name":"PTPUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"isAutoBalance","type":"bool"},{"indexed":false,"internalType":"uint256","name":"autoBalancePeriod","type":"uint256"}],"name":"SetAutoBalanceUser","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"VePTPClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFactor","type":"uint256"}],"name":"VePTPFactorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFactor","type":"uint256"}],"name":"VePTPMultipleFactorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"oldVePtp","type":"address"},{"indexed":true,"internalType":"address","name":"newVePtp","type":"address"}],"name":"VePTPUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"addLPToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"autoBalanceForLPStaker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"autoBalanceForLPStakers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"baseAPR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"boostedAPR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"ptpAmount","type":"uint256"},{"internalType":"uint256","name":"stakingTimeSecond","type":"uint256"}],"name":"calcVePTPReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"calcVePTPRewardPub","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"claimPTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimVePTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"claimVePTPFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"coverageRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"}],"name":"deleteLPToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"directStakingPTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"lpAmount","type":"uint256"},{"internalType":"uint256","name":"ptpAmount","type":"uint256"},{"internalType":"uint256","name":"stakingTimeSecond","type":"uint256"}],"name":"estimatedBoostedAPRFromPTP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"lpAmount","type":"uint256"},{"internalType":"uint256","name":"vePTPAmount","type":"uint256"}],"name":"estimatedBoostedAPRFromVePTP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factors","outputs":[{"internalType":"uint256","name":"rfBasePTP","type":"uint256"},{"internalType":"uint256","name":"rfBoostPTP","type":"uint256"},{"internalType":"uint256","name":"rfVePTP","type":"uint256"},{"internalType":"uint256","name":"rfVePTPMultiple","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isAutoBalance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"lpStakedInfo","outputs":[{"internalType":"uint256","name":"lpAmount","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"uint256","name":"rewardLastTimestamp","type":"uint256"},{"internalType":"uint256","name":"autoBalancePeriod","type":"uint256"},{"internalType":"uint256","name":"autoBalanceLastTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lpTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"medianBoostedAPR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multiClaimPTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"multiLpStakedInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ptp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"ptpStakedInfo","outputs":[{"internalType":"uint256","name":"ptpAmount","type":"uint256"},{"internalType":"uint256","name":"totalPtpAmount","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"autoBalancePeriod","type":"uint256"}],"name":"setAutoBalanceForLPStaker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stakingLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"autoBalancePeriod","type":"uint256"}],"name":"stakingLPFromOther","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stakingPTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"totalAPR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unStakingLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unStakingPTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFactor","type":"uint256"}],"name":"updateBaseRewardFactorPTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFactor","type":"uint256"}],"name":"updateBoostRewardFactorPTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMARKET","name":"newPtp","type":"address"}],"name":"updatePTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"updatePTPStakedUserInfoForStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"updatePTPStakedUserInfoForStakingFirstInvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"unitAmount","type":"uint256"},{"internalType":"uint256","name":"prevUnitAmount","type":"uint256"},{"internalType":"uint256","name":"investCount","type":"uint256"},{"internalType":"uint256","name":"investedCount","type":"uint256"}],"name":"updatePTPStakedUserInfoForStakingStepInvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFactor","type":"uint256"}],"name":"updateRewardFactorVePTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFactor","type":"uint256"}],"name":"updateRewardFactorVePTPMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IveMARKET","name":"newVePtp","type":"address"}],"name":"updateVePTP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"veptp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6080604052600380546001600160a01b031990811673d0e8f96191d3ee2392d7780c85f7103d4e2335d61790915560048054821673248e0900f1e6b0a5e364a103e24bb5c49a71757717905560058054909116734daf18138e7b1620f141b6baa76a60cdcbd02b411790556344fc85c0600a5566868a9079a4e000600b5565038248ae1500600c556064600d5534801561009857600080fd5b50600080546001600160a01b0319908116331782556003546006805460018181018355948290527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f908101805485166001600160a01b039485161790556004548254808701845582018054861691851691909117905560055482549586019092559390930180549092169216919091179055615f42806200013a6000396000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c8063715018a611610151578063b69bd769116100c3578063e1456ed511610087578063e1456ed51461056d578063eb0365ef146105a8578063f2eaf2d0146105bb578063f2fde38b146105ce578063fad9812f146105e1578063fcec048a146105f457600080fd5b8063b69bd76914610519578063bdc886361461052c578063be955d0c1461053f578063bf64c6ad14610552578063cc41631b1461055a57600080fd5b8063a5b5433b11610115578063a5b5433b14610480578063a7187122146104ac578063a72a596b146104b4578063a7b87280146104c5578063aee19b4c146104f3578063b214cc031461050657600080fd5b8063715018a61461042c57806371628ba01461043457806380defc0014610447578063994c94bc1461045a5780639b7e9d801461046d57600080fd5b80633c192cfe116101ea578063551fca58116101ae578063551fca58146103bc5780635623a04b146103cf5780635d46f7d3146103e25780635dbdc66a146103f55780635de84641146104085780636af667721461041b57600080fd5b80633c192cfe1461035d5780633c3b1d25146103705780633d9a11ee14610383578063485a4ae3146103965780635245656b146103a957600080fd5b80632bc4d462116102315780632bc4d462146103095780632efc5bbe146103115780633053a18114610324578063341a64ca146103375780633476bc581461034a57600080fd5b8063183cccc81461026e57806318ba2686146102945780631bb5e2dc146102b657806328ce27d0146102e1578063291cb4a2146102f6575b600080fd5b61028161027c366004615936565b610617565b6040519081526020015b60405180910390f35b6102a76102a2366004615966565b61062c565b60405161028b939291906159be565b6102c96102c43660046159e9565b610820565b6040516001600160a01b03909116815260200161028b565b6102f46102ef366004615a02565b61084a565b005b6102f4610304366004615966565b610aab565b6102f4610d19565b6102f461031f366004615a3d565b61128d565b6102f4610332366004615966565b61129b565b610281610345366004615a69565b6117b3565b610281610358366004615966565b611a12565b6102f461036b366004615966565b611a35565b6102f461037e3660046159e9565b611a41565b6102f46103913660046159e9565b611b29565b6102f46103a43660046159e9565b611c09565b6102f46103b7366004615966565b611e31565b6102f46103ca366004615ab1565b611f06565b6102f46103dd366004615a3d565b611f75565b6102816103f03660046159e9565b612061565b6102816104033660046159e9565b61206c565b6102f46104163660046159e9565b612331565b6001546001600160a01b03166102c9565b6102f4612425565b6102f4610442366004615ae6565b61245b565b610281610455366004615ab1565b6127a9565b6102f46104683660046159e9565b612a46565b6102f461047b366004615966565b612c1f565b600a54600b54600c54600d5460408051948552602085019390935291830152606082015260800161028b565b6102f4612d54565b6002546001600160a01b03166102c9565b6104d86104d3366004615966565b612d5d565b6040805193845260208401929092529082015260600161028b565b6102816105013660046159e9565b612d95565b6102f4610514366004615966565b612da0565b6102f4610527366004615ae6565b612f8e565b6102f461053a366004615966565b6131e0565b6102f461054d3660046159e9565b613315565b6102f46133f5565b610281610568366004615936565b6133fe565b61058061057b366004615936565b61340a565b604080519586526020860194909452928401919091526060830152608082015260a00161028b565b6102816105b6366004615b08565b613510565b6102f46105c9366004615b45565b61368a565b6102f46105dc366004615966565b613743565b6102f46105ef3660046159e9565b61382f565b610607610602366004615966565b613a93565b604051901515815260200161028b565b60006106238383613a9e565b90505b92915050565b600060608060008060068054905067ffffffffffffffff81111561065257610652615b89565b60405190808252806020026020018201604052801561067b578160200160208202803683370190505b5060065490915060009067ffffffffffffffff81111561069d5761069d615b89565b6040519080825280602002602001820160405280156106c6578160200160208202803683370190505b50905060005b6006548110156108125760008181526008602090815260408083206001600160a01b038c168452909152812090610704838b84613abd565b90506107108187615bb5565b95506006838154811061072557610725615bcd565b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b15801561076e57600080fd5b505afa158015610782573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a69190615be3565b6107b190600a615cea565b82600101546107c09190615cf9565b8584815181106107d2576107d2615bcd565b602002602001018181525050808484815181106107f1576107f1615bcd565b6020026020010181815250505050808061080a90615d18565b9150506106cc565b509196909550909350915050565b6006818154811061083057600080fd5b6000918252602090912001546001600160a01b0316905081565b6001546001600160a01b03166108a75760405162461bcd60e51b815260206004820152601b60248201527f7374616b696e674c503a2050545020646f6573206e6f7420736574000000000060448201526064015b60405180910390fd5b81600684815481106108bb576108bb615bcd565b6000918252602090912001546040516370a0823160e01b81526001600160a01b038781166004830152909116906370a082319060240160206040518083038186803b15801561090957600080fd5b505afa15801561091d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109419190615d33565b101561098f5760405162461bcd60e51b815260206004820152601e60248201527f7374616b696e674c503a20696e73756666696369656e7420616d6f756e740000604482015260640161089e565b600683815481106109a2576109a2615bcd565b6000918252602090912001546040516323b872dd60e01b81526001600160a01b03868116600483015230602483015260448201859052909116906323b872dd90606401602060405180830381600087803b1580156109ff57600080fd5b505af1158015610a13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a379190615d4c565b50610a4483858484613af6565b60068381548110610a5757610a57615bcd565b600091825260209182902001546040518481526001600160a01b0391821692918716917e8bfa58790ca176ab7c8a54d2fa2a44b1b1c883248e56849845d29a6e944aa491015b60405180910390a350505050565b6000610ad6610abb600084613a9e565b610ac6600185613a9e565b610ad1600286613a9e565b613d7e565b90506000816040015182602001518360000151610af39190615bb5565b610afd9190615bb5565b90508015610d14576001600160a01b0383166000908152600080516020615ead83398151915260209081526040808320600190810154600080516020615ecd8339815191528452828520820154600080516020615eed83398151915290945291842001549091610b6c91615bb5565b610b769190615bb5565b90506000610bce83856000015184610b8e9190615cf9565b610b989190615d6e565b84866020015185610ba99190615cf9565b610bb39190615d6e565b85876040015186610bc49190615cf9565b610ad19190615d6e565b6001600160a01b0386166000818152600080516020615eed833981519152602090815260408083206001908101548651600080516020615ecd833981519152855283862083015488860151600080516020615ead8339815191528752968590209093015488850151855198895295880192909252928601929092526060850152608084019290925260a083019190915260c08201529091507fc674bc8393b38b9632c28399ad5da9407a6f32025a9caf926fbd532e69a1ed199060e00160405180910390a180516001600160a01b0386166000908152600080516020615eed8339815191526020908152604080832060018082019590955582860151600080516020615ecd83398151915284528285208087019190915595820151600080516020615ead8339815191529093529220928301554260059182018190559281018390550155505b505050565b6000805b600754811015611256576000808052600860205260078054600080516020615eed83398151915291839185908110610d5757610d57615bcd565b60009182526020808320909101546001600160a01b03168352828101939093526040909101812060040154818052600890925260078054600080516020615eed83398151915292919086908110610db057610db0615bcd565b60009182526020808320909101546001600160a01b03168352820192909252604001902060050154610de29042615d90565b10159050610e1660078381548110610dfc57610dfc615bcd565b6000918252602090912001546001600160a01b0316613dbf565b8015610e1f5750805b15611243576000610e8b610e5b600060078681548110610e4157610e41615bcd565b6000918252602090912001546001600160a01b0316613a9e565b610e73600160078781548110610e4157610e41615bcd565b610ad1600260078881548110610e4157610e41615bcd565b90506000816040015182602001518360000151610ea89190615bb5565b610eb29190615bb5565b905080156112405760026000908152600860205260078054600080516020615ead83398151915291839188908110610eec57610eec615bcd565b60009182526020808320909101546001600160a01b031683528281019390935260409091018120600190810154908252600890925260078054600080516020615ecd83398151915292919089908110610f4757610f47615bcd565b60009182526020808320909101546001600160a01b03168352828101939093526040909101812060010154818052600890925260078054600080516020615eed8339815191529291908a908110610fa057610fa0615bcd565b60009182526020808320909101546001600160a01b03168352820192909252604001902060010154610fd29190615bb5565b610fdc9190615bb5565b90506000610ff483856000015184610b8e9190615cf9565b805160008080526008602052600780549394509192600080516020615eed83398151915292908a90811061102a5761102a615bcd565b60009182526020808320909101546001600160a01b03168352828101939093526040909101812060019081019390935583820151928152600890915260078054600080516020615ecd8339815191529291908a90811061108c5761108c615bcd565b60009182526020808320909101546001600160a01b03168352828101939093526040918201812060010193909355830151600283526008909152600780549192600080516020615ead833981519152929091908a9081106110ef576110ef615bcd565b60009182526020808320909101546001600160a01b0316835282810193909352604090910181206001019290925581805260089052600780544292600080516020615eed8339815191529290918a90811061114c5761114c615bcd565b60009182526020808320909101546001600160a01b031683528281019390935260409091018120600501929092556001825260089052600780544292600080516020615ecd8339815191529290918a9081106111aa576111aa615bcd565b60009182526020808320909101546001600160a01b031683528281019390935260409091018120600501929092556002825260089052600780544292600080516020615ead8339815191529290918a90811061120857611208615bcd565b60009182526020808320909101546001600160a01b031683528201929092526040019020600501558661123a81615d18565b97505050505b50505b508061124e81615d18565b915050610d1d565b506040518181527f9b81650883c3357b81aca2dc3e1f9e266c1c06387fb83c90300628086581bdbb9060200160405180910390a150565b6112978282613dec565b5050565b6000805b6006548110156112f65760008181526008602090815260408083206001600160a01b038716845290915290206112d6828583613abd565b6112e09084615bb5565b92505080806112ee90615d18565b91505061129f565b506001546040805163313ce56760e01b815290516001600160a01b0390921691637a2bbf65913091849163313ce567916004808301926020929190829003018186803b15801561134557600080fd5b505afa158015611359573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137d9190615be3565b61138890600a615cea565b6113929085615cf9565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156113d857600080fd5b505af11580156113ec573d6000803e3d6000fd5b5050600154604051639645c71960e01b81526001600160a01b0386811660048301524294509091169150639645c7199060240160206040518083038186803b15801561143757600080fd5b505afa15801561144b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146f9190615d33565b60015460405163149501dd60e01b81526001600160a01b0386811660048301529091169063149501dd9060240160206040518083038186803b1580156114b457600080fd5b505afa1580156114c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ec9190615d33565b6114f69190615bb5565b11801561157b57506001546040516307e6c85160e21b81526001600160a01b03848116600483015290911690631f9b21449060240160206040518083038186803b15801561154357600080fd5b505afa158015611557573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157b9190615d4c565b15611706576001546040805163313ce56760e01b815290516001600160a01b039092169163300fc70e918591849163313ce567916004808301926020929190829003018186803b1580156115ce57600080fd5b505afa1580156115e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116069190615be3565b61161190600a615cea565b61161b9085615cf9565b600154604051639645c71960e01b81526001600160a01b03888116600483015290911690639645c7199060240160206040518083038186803b15801561166057600080fd5b505afa158015611674573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116989190615d33565b6040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260016064820152608401600060405180830381600087803b1580156116ed57600080fd5b505af1158015611701573d6000803e3d6000fd5b505050505b61170f82613e5a565b61129782600160009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561176157600080fd5b505afa158015611775573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117999190615be3565b6117a490600a615cea565b6117ae9084615cf9565b613dec565b6002546040516370a0823160e01b81526001600160a01b03868116600483015260009283929116906370a082319060240160206040518083038186803b1580156117fc57600080fd5b505afa158015611810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118349190615d33565b670de0b6b3a76400008486600c5461184c9190615cf9565b6118569190615cf9565b6118609190615d6e565b61186a9190615bb5565b9050600d548461187a9190615cf9565b81111561189157600d5461188e9085615cf9565b90505b60006118a56118a08388615cf9565b613eaa565b6002546040516370a0823160e01b81526001600160a01b038a811660048301526119549216906370a082319060240160206040518083038186803b1580156118ec57600080fd5b505afa158015611900573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119249190615d33565b60008b81526008602090815260408083206001600160a01b038e1684529091529020600101546118a09190615cf9565b61195d8a613f1a565b6119679190615d90565b6119719190615bb5565b90506000811180156119835750600086115b15611a02578061199287613eaa565b61199c9190615cf9565b6119ae90670de0b6b3a7640000615cf9565b6119b783613eaa565b600b546119c49190615cf9565b6119d2906301e13380615cf9565b6119dd906064615cf9565b6119ef90670de0b6b3a7640000615cf9565b6119f99190615d6e565b92505050611a09565b6000925050505b95945050505050565b6001600160a01b03811660009081526009602052604081206106269083906141cc565b611a3e816143c8565b50565b6000546001600160a01b03163314611a6b5760405162461bcd60e51b815260040161089e90615da7565b60008111611ae15760405162461bcd60e51b815260206004820152603a60248201527f757064617465526577617264466163746f7256655054503a207265776172642060448201527f666163746f722063616e206e6f74206265206e65676174697665000000000000606482015260840161089e565b600c805490829055604080518281526020810184905233917f855fafca51225522ad6c1f4e1fb696cd1bb58bc66ad33a5de6e02b934502142e91015b60405180910390a25050565b6000546001600160a01b03163314611b535760405162461bcd60e51b815260040161089e90615da7565b60008111611bc95760405162461bcd60e51b815260206004820152603c60248201527f75706461746542617365526577617264466163746f725054503a20726577617260448201527f6420666163746f722063616e206e6f74206265206e6567617469766500000000606482015260840161089e565b600a805490829055604080518281526020810184905233917fae5089270565bef52c1a493092d1431a1d394e72e982bb041495fc75aae23bb69101611b1d565b600081815260086020908152604080832033808552925282209190611c3090849084613abd565b6001546040805163313ce56760e01b815290519293506001600160a01b0390911691637a2bbf65913391849163313ce567916004808301926020929190829003018186803b158015611c8157600080fd5b505afa158015611c95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cb99190615be3565b611cc490600a615cea565b611cce9085615cf9565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611d1457600080fd5b505af1158015611d28573d6000803e3d6000fd5b5050506000848152600860209081526040808320338452909152812060028101919091554260039091015550336001600160a01b03167f05c2f7336f6158057f2b7e5b2559481d65df933d79a841e734b28ae9a2ef0a10600160009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015611dcd57600080fd5b505afa158015611de1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e059190615be3565b611e1090600a615cea565b611e1a9084615cf9565b6040519081526020015b60405180910390a2505050565b6000546001600160a01b03163314611e5b5760405162461bcd60e51b815260040161089e90615da7565b60405163830a8f4b60e01b8152600660048201526001600160a01b0382166024820152731f35fb4ba99e9676d2c2ea7b832a91fa24afe1fd9063830a8f4b9060440160006040518083038186803b158015611eb557600080fd5b505af4158015611ec9573d6000803e3d6000fd5b50506040516001600160a01b03841692503391507f2068c352541b73092815d052027fd5f39528c36d23fbe5d405a1a5bf6e8946e390600090a350565b6001600160a01b0383166000908152600960205260408120600281018290554260038201558054849290611f3b908490615bb5565b90915550506001600160a01b03831660009081526009602052604081206001018054839290611f6b908490615bb5565b9091555050505050565b60005b600654811015611fc45760008181526008602090815260408083206001600160a01b03871684529091529020600481018390554260059091015580611fbc81615d18565b915050611f78565b50801561201a57604080516001600160a01b0384168152600160208201529081018290527fea5a67858f0e1921590f3f71202bf7f73f93ba64a38d778192c616fa0c5cf9e1906060015b60405180910390a15050565b604080516001600160a01b0384168152600060208201529081018290527fea5a67858f0e1921590f3f71202bf7f73f93ba64a38d778192c616fa0c5cf9e19060600161200e565b6000610626826144ba565b60008061207883613f1a565b9050600080600260009054906101000a90046001600160a01b03166001600160a01b0316638188f71c6040518163ffffffff1660e01b815260040160006040518083038186803b1580156120cb57600080fd5b505afa1580156120df573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526121079190810190615de7565b5190506000805b8281101561230a57600254604080516320623dc760e21b815290516000926001600160a01b031691638188f71c9160048083019286929190829003018186803b15801561215a57600080fd5b505afa15801561216e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526121969190810190615de7565b82815181106121a7576121a7615bcd565b602002602001015190506121bb8882614725565b80156121c75750600086115b156122f75760008881526008602090815260408083206001600160a01b03851684529091529020600181015487906121fe90613eaa565b6122089190615cf9565b61221a90670de0b6b3a7640000615cf9565b6002546040516370a0823160e01b81526001600160a01b03858116600483015261229a9216906370a08231906024015b60206040518083038186803b15801561226257600080fd5b505afa158015612276573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118a09190615d33565b600b546122a79190615cf9565b6122b5906301e13380615cf9565b6122c0906064615cf9565b6122d290670de0b6b3a7640000615cf9565b6122dc9190615d6e565b6122e69087615bb5565b9550836122f281615d18565b945050505b508061230281615d18565b91505061210e565b5080156123255761231b8184615d6e565b9695505050505050565b50600095945050505050565b6000546001600160a01b0316331461235b5760405162461bcd60e51b815260040161089e90615da7565b600081116123e55760405162461bcd60e51b815260206004820152604b60248201527f757064617465526577617264466163746f7256655054504d756c7469706c653a60448201527f206d756c7469706c652072657761726420666163746f722063616e206e6f742060648201526a6265206e6567617469766560a81b608482015260a40161089e565b600d805490829055604080518281526020810184905233917fef0f5113bf020e52eeb7cb60d31cef7f6172f18e5d8fc1951447b75e1fb334979101611b1d565b6000546001600160a01b0316331461244f5760405162461bcd60e51b815260040161089e90615da7565b6124596000614752565b565b6001546001600160a01b03166124b35760405162461bcd60e51b815260206004820152601d60248201527f756e5374616b696e674c503a2050545020646f6573206e6f7420736574000000604482015260640161089e565b6124bd8233614725565b6125195760405162461bcd60e51b815260206004820152602760248201527f756e5374616b696e674c503a2075736572206469646e2774207374616b65206c60448201526638103a37b5b2b760c91b606482015260840161089e565b60008281526008602090815260408083203384529091529020600680548490811061254657612546615bcd565b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b15801561258f57600080fd5b505afa1580156125a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c79190615be3565b6125d290600a615cea565b6125dc9083615d6e565b8160010154101561262f5760405162461bcd60e51b815260206004820181905260248201527f756e5374616b696e674c503a20696e73756666696369656e7420616d6f756e74604482015260640161089e565b6006838154811061264257612642615bcd565b60009182526020909120015460405163a9059cbb60e01b8152336004820152602481018490526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b15801561269757600080fd5b505af11580156126ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126cf9190615d4c565b5060006126dd843384613abd565b600154604051637a2bbf6560e01b8152336004820152602481018390529192506001600160a01b031690637a2bbf6590604401600060405180830381600087803b15801561272a57600080fd5b505af115801561273e573d6000803e3d6000fd5b5050505061274d8433856147a2565b6006848154811061276057612760615bcd565b600091825260209182902001546040518581526001600160a01b039091169133917f295642eb60c93ad2e0958a0a833ea991a2fa186dac1efabaeea400dfa57a77ba9101610a9d565b600154600c5460405163692bdb0f60e11b81526001600160a01b03868116600483015260248201929092526000928392169063d257b61e9060440160206040518083038186803b1580156127fc57600080fd5b505afa158015612810573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128349190615d33565b670de0b6b3a76400008486600c5461284c9190615cf9565b6128569190615cf9565b6128609190615d6e565b61286a9190615bb5565b9050600d548461287a9190615cf9565b6002546040516370a0823160e01b81526001600160a01b038881166004830152909116906370a082319060240160206040518083038186803b1580156128bf57600080fd5b505afa1580156128d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f79190615d33565b6129019083615bb5565b1115612a3c576002546040516370a0823160e01b81526001600160a01b038781166004830152909116906370a082319060240160206040518083038186803b15801561294c57600080fd5b505afa158015612960573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129849190615d33565b600d546129919086615cf9565b1115612a32576002546040516370a0823160e01b81526001600160a01b038781166004830152909116906370a082319060240160206040518083038186803b1580156129dc57600080fd5b505afa1580156129f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a149190615d33565b600d54612a219086615cf9565b612a2b9190615d90565b9050612a3c565b6000915050612a3f565b90505b9392505050565b6002546001600160a01b0316612a9e5760405162461bcd60e51b815260206004820152601e60248201527f756e5374616b696e675054503a2050545020646f6573206e6f74207365740000604482015260640161089e565b33600090815260096020526040902054612b0c5760405162461bcd60e51b815260206004820152602960248201527f756e5374616b696e675054503a2075736572206469646e2774207374616b6520604482015268383a38103a37b5b2b760b91b606482015260840161089e565b600154604051637a2bbf6560e01b8152336004820152602481018390526001600160a01b0390911690637a2bbf6590604401600060405180830381600087803b158015612b5857600080fd5b505af1158015612b6c573d6000803e3d6000fd5b5050600254604051630e5d43eb60e11b81523360048201526001600160a01b039091169250631cba87d69150602401600060405180830381600087803b158015612bb557600080fd5b505af1158015612bc9573d6000803e3d6000fd5b50505050612bd73382614a46565b6001546040518281526001600160a01b039091169033907fc21f4b84fb67c9100fc782530fcc6f20b61603248cf33c77041c1c312651c097906020015b60405180910390a350565b6000546001600160a01b03163314612c495760405162461bcd60e51b815260040161089e90615da7565b6001600160a01b038116612c9f5760405162461bcd60e51b815260206004820152601760248201527f7570646174655054503a207a65726f2061646472657373000000000000000000604482015260640161089e565b6001600160a01b0381163b612cf65760405162461bcd60e51b815260206004820152601c60248201527f7570646174655054503a20696e76616c69656420636f6e747261637400000000604482015260640161089e565b6001546040516001600160a01b0380841692169033907f9cac633b87aec5e32b69476a4d4973d71e48dcf0b67d40212abcf6151447e1a390600090a4600180546001600160a01b0319166001600160a01b0392909216919091179055565b612459336143c8565b6001600160a01b038116600090815260096020526040812081908190612d8385826141cc565b60018201549154969195509350915050565b600061062682614ba2565b6000546001600160a01b03163314612dca5760405162461bcd60e51b815260040161089e90615da7565b6001600160a01b038116612e205760405162461bcd60e51b815260206004820152601860248201527f6164644c50546f6b656e3a207a65726f20616464726573730000000000000000604482015260640161089e565b6001600160a01b0381163b612e8d5760405162461bcd60e51b815260206004820152602d60248201527f6164644c50546f6b656e3a204c5020746f6b656e206d7573742062652061207660448201526c185b1a590818dbdb9d1c9858dd609a1b606482015260840161089e565b612e9681614d74565b15612ee35760405162461bcd60e51b815260206004820152601960248201527f6164644c50546f6b656e3a20616c726561647920657869737400000000000000604482015260640161089e565b60405163e6e9237160e01b8152600660048201526001600160a01b0382166024820152731f35fb4ba99e9676d2c2ea7b832a91fa24afe1fd9063e6e923719060440160006040518083038186803b158015612f3d57600080fd5b505af4158015612f51573d6000803e3d6000fd5b50506040516001600160a01b03841692503391507fb2dd942974aa9d06f7fae2f438a80db55a98647e1771ab931d9762fccd7fc37b90600090a350565b6001546001600160a01b0316612fe65760405162461bcd60e51b815260206004820152601b60248201527f7374616b696e674c503a2050545020646f6573206e6f74207365740000000000604482015260640161089e565b8060068381548110612ffa57612ffa615bcd565b6000918252602090912001546040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561304657600080fd5b505afa15801561305a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061307e9190615d33565b10156130cc5760405162461bcd60e51b815260206004820152601e60248201527f7374616b696e674c503a20696e73756666696369656e7420616d6f756e740000604482015260640161089e565b600682815481106130df576130df615bcd565b6000918252602090912001546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd90606401602060405180830381600087803b15801561313a57600080fd5b505af115801561314e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131729190615d4c565b5061317e823383614e09565b6006828154811061319157613191615bcd565b600091825260209182902001546040518381526001600160a01b039091169133917e8bfa58790ca176ab7c8a54d2fa2a44b1b1c883248e56849845d29a6e944aa4910160405180910390a35050565b6000546001600160a01b0316331461320a5760405162461bcd60e51b815260040161089e90615da7565b6001600160a01b0381166132605760405162461bcd60e51b815260206004820152601960248201527f75706461746556655054503a207a65726f206164647265737300000000000000604482015260640161089e565b6001600160a01b0381163b6132b75760405162461bcd60e51b815260206004820152601e60248201527f75706461746556655054503a20696e76616c69656420636f6e74726163740000604482015260640161089e565b6002546040516001600160a01b0380841692169033907f87ca55db885429bc10a1bea82e34b81bee09696cf6845fcac8e71ec9b4981bb790600090a4600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331461333f5760405162461bcd60e51b815260040161089e90615da7565b600081116133b55760405162461bcd60e51b815260206004820152603d60248201527f757064617465426f6f7374526577617264466163746f725054503a207265776160448201527f726420666163746f722063616e206e6f74206265206e65676174697665000000606482015260840161089e565b600b805490829055604080518281526020810184905233917f45c42099d03fb2430bb8a9bb0c59a2f19a6f6c8b4b11af7f66734e191ed3981d9101611b1d565b61245933614feb565b6000610623838361521d565b60008281526008602090815260408083206001600160a01b03851684529091528120819081908190819061343f888883613abd565b94506006888154811061345457613454615bcd565b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b15801561349d57600080fd5b505afa1580156134b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d59190615be3565b6134e090600a615cea565b81600101546134ef9190615cf9565b60038201546004830154600590930154919a96995097509095509392505050565b6000806135206118a08486615cf9565b6002546040516370a0823160e01b81526001600160a01b0388811660048301526135cf9216906370a082319060240160206040518083038186803b15801561356757600080fd5b505afa15801561357b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061359f9190615d33565b60008981526008602090815260408083206001600160a01b038c1684529091529020600101546118a09190615cf9565b6135d888613f1a565b6135e29190615d90565b6135ec9190615bb5565b90506000811180156135fe5750600084115b1561367c578061360d85613eaa565b6136179190615cf9565b61362990670de0b6b3a7640000615cf9565b61363284613eaa565b600b5461363f9190615cf9565b61364d906301e13380615cf9565b613658906064615cf9565b61366a90670de0b6b3a7640000615cf9565b6136749190615d6e565b915050613682565b60009150505b949350505050565b6001600160a01b03851660009081526009602052604081206002810182905542600382015580548692906136bf908490615bb5565b909155506136cf90508183615d90565b6136d99085615cf9565b6136e38284615d90565b6136ed9085615cf9565b6001600160a01b0387166000908152600960205260409020600101546137139190615d90565b61371d9190615bb5565b6001600160a01b0390951660009081526009602052604090206001019490945550505050565b6000546001600160a01b0316331461376d5760405162461bcd60e51b815260040161089e90615da7565b6001600160a01b0381166137d25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161089e565b6000546001600160a01b03828116911614156138265760405162461bcd60e51b815260206004820152601360248201527227bbb730b136329d1039b0b6b29037bbb732b960691b604482015260640161089e565b611a3e81614752565b6002546001600160a01b03166138875760405162461bcd60e51b815260206004820152601e60248201527f7374616b696e675054503a20566550545020646f6573206e6f74207365740000604482015260640161089e565b6001546040516370a0823160e01b815233600482015282916001600160a01b0316906370a082319060240160206040518083038186803b1580156138ca57600080fd5b505afa1580156138de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139029190615d33565b10156139505760405162461bcd60e51b815260206004820152601f60248201527f7374616b696e675054503a20696e73756666696369656e7420616d6f756e7400604482015260640161089e565b600154604051637f92366f60e01b8152336004820152306024820152604481018390526001600160a01b0390911690637f92366f90606401600060405180830381600087803b1580156139a257600080fd5b505af11580156139b6573d6000803e3d6000fd5b50506002543360008181526009602052604090206001600160a01b0390921693506340c10f199250906139ea9082906141cc565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015613a3057600080fd5b505af1158015613a44573d6000803e3d6000fd5b50505050613a523382613dec565b6001546040518281526001600160a01b039091169033907f69cac3b0665489073c5a8caab5801cc1f2f7e21f46194269fce3f6486d77cd5a90602001612c14565b600061062682613dbf565b6000613aaa838361521d565b613ab3846144ba565b6106239190615bb5565b600080613aca858461531d565b90506000613ad98686866155a8565b905080828560020154613aec9190615bb5565b61231b9190615bb5565b60008481526008602090815260408083206001600160a01b03871684529091529020613b228585614725565b15613b5d57613b32858583613abd565b60008681526008602090815260408083206001600160a01b0389168452909152902060020155613b84565b60008581526008602090815260408083206001600160a01b03881684529091528120600201555b60008581526008602090815260408083206001600160a01b03881684529091529020426003909101556006805486908110613bc157613bc1615bcd565b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b158015613c0a57600080fd5b505afa158015613c1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c429190615be3565b613c4d90600a615cea565b613c579084615d6e565b60008681526008602090815260408083206001600160a01b038916845290915281206001018054909190613c8c908490615bb5565b909155505060008581526008602090815260408083206001600160a01b03881680855290835281842042600590910155600080516020615eed83398151915283528184206004908101879055600080516020615ecd83398151915284528285208101879055600080516020615ead8339815191529093529281902082018590555163e6e9237160e01b81526007918101919091526024810191909152731f35fb4ba99e9676d2c2ea7b832a91fa24afe1fd9063e6e923719060440160006040518083038186803b158015613d5f57600080fd5b505af4158015613d73573d6000803e3d6000fd5b505050505050505050565b613da260405180606001604052806000815260200160008152602001600081525090565b506040805160608101825293845260208401929092529082015290565b6001600160a01b03166000908152600080516020615eed8339815191526020526040902060040154151590565b6001600160a01b0382166000908152600960205260408120600281018290554260038201558054839290613e21908490615bb5565b90915550506001600160a01b03821660009081526009602052604081206001018054839290613e51908490615bb5565b90915550505050565b60005b6006548110156112975760008181526008602090815260408083206001600160a01b0386168452909152812060028101919091554260039091015580613ea281615d18565b915050613e5d565b60006003821115613f0b5750806000613ec4600283615d6e565b613ecf906001615bb5565b90505b81811015613f0557905080600281613eea8186615d6e565b613ef49190615bb5565b613efe9190615d6e565b9050613ed2565b50919050565b8115613f15575060015b919050565b60008060005b600260009054906101000a90046001600160a01b03166001600160a01b0316638188f71c6040518163ffffffff1660e01b815260040160006040518083038186803b158015613f6e57600080fd5b505afa158015613f82573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613faa9190810190615de7565b518110156141c557600254604080516320623dc760e21b815290516141a7926001600160a01b0316916370a08231918391638188f71c916004808301926000929190829003018186803b15801561400057600080fd5b505afa158015614014573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261403c9190810190615de7565b848151811061404d5761404d615bcd565b60200260200101516040518263ffffffff1660e01b815260040161408091906001600160a01b0391909116815260200190565b60206040518083038186803b15801561409857600080fd5b505afa1580156140ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140d09190615d33565b60008681526008602052604080822060025482516320623dc760e21b815292519193926001600160a01b0390911691638188f71c916004808201928692909190829003018186803b15801561412457600080fd5b505afa158015614138573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526141609190810190615de7565b858151811061417157614171615bcd565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600101546118a09190615cf9565b6141b19083615bb5565b9150806141bd81615d18565b915050613f20565b5092915050565b6000806141d984846156b5565b83600201546141e89190615bb5565b9050600d5483600101546141fc9190615cf9565b6002546040516370a0823160e01b81526001600160a01b038781166004830152909116906370a082319060240160206040518083038186803b15801561424157600080fd5b505afa158015614255573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142799190615d33565b6142839083615bb5565b1115610623576002546040516370a0823160e01b81526001600160a01b038681166004830152909116906370a082319060240160206040518083038186803b1580156142ce57600080fd5b505afa1580156142e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143069190615d33565b600d5484600101546143189190615cf9565b11156143be576002546040516370a0823160e01b81526001600160a01b038681166004830152909116906370a082319060240160206040518083038186803b15801561436357600080fd5b505afa158015614377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061439b9190615d33565b600d5484600101546143ad9190615cf9565b6143b79190615d90565b9050610623565b6000915050610626565b6001600160a01b0381166000908152600960205260408120906143eb83836141cc565b6002546040516340c10f1960e01b81526001600160a01b038681166004830152602482018490529293509116906340c10f1990604401600060405180830381600087803b15801561443b57600080fd5b505af115801561444f573d6000803e3d6000fd5b5050505061447f836001600160a01b03166000908152600960205260408120600281019190915542600390910155565b826001600160a01b03167fbd1da3a93464848c0958e6d817b73d077330849f7ca68019a7c5d2a318bbdcae82604051611e2491815260200190565b600080600683815481106144d0576144d0615bcd565b60009182526020918290200154604080516318160ddd60e01b815290516001600160a01b03909216926318160ddd92600480840193829003018186803b15801561451957600080fd5b505afa15801561452d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145519190615d33565b111561471d576006828154811061456a5761456a615bcd565b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b1580156145b357600080fd5b505afa1580156145c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145eb9190615be3565b6145f690600a615cea565b6006838154811061460957614609615bcd565b60009182526020918290200154604080516318160ddd60e01b815290516001600160a01b03909216926318160ddd92600480840193829003018186803b15801561465257600080fd5b505afa158015614666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061468a9190615d33565b6146949190615d6e565b6006546146a19190615cf9565b6146b390670de0b6b3a7640000615cf9565b6146c090620186a0615cf9565b6146c86157b6565b6146d184614ba2565b600a546146e2906301e13380615cf9565b6146ec9190615cf9565b6146f69190615cf9565b614701906064615cf9565b61471390670de0b6b3a7640000615cf9565b6106269190615d6e565b506000919050565b60009182526008602090815260408084206001600160a01b03939093168452919052902060010154151590565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6147ac8383614725565b61481e5760405162461bcd60e51b815260206004820152603f60248201527f5f7570646174654c505374616b656455736572496e666f466f72556e5374616b60448201527f696e673a2075736572206469646e2774207374616b65206c7020746f6b656e00606482015260840161089e565b60008381526008602090815260408083206001600160a01b03861684529091528120600281019190915542600390910155600680548490811061486357614863615bcd565b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b1580156148ac57600080fd5b505afa1580156148c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148e49190615be3565b6148ef90600a615cea565b6148f99082615d6e565b60008481526008602090815260408083206001600160a01b03871684529091528120600101805490919061492e908490615d90565b90915550506001600160a01b0382166000908152600080516020615eed833981519152602090815260408083206004908101849055600080516020615ecd83398151915283528184208101849055600080516020615ead833981519152909252822001819055805b6006548110156149c6576149aa8185614725565b156149b457600191505b806149be81615d18565b915050614996565b5080614a40576040516306297c5f60e51b8152600760048201526001600160a01b0384166024820152731f35fb4ba99e9676d2c2ea7b832a91fa24afe1fd9063c52f8be0906044015b60006040518083038186803b158015614a2757600080fd5b505af4158015614a3b573d6000803e3d6000fd5b505050505b50505050565b6001600160a01b038216600090815260096020526040902054614adb5760405162461bcd60e51b815260206004820152604160248201527f5f7570646174655054505374616b656455736572496e666f466f72556e53746160448201527f6b696e673a2075736572206469646e2774207374616b652050545020746f6b656064820152603760f91b608482015260a40161089e565b6001600160a01b03821660009081526009602052604081206002810191909155426003820155548111614b3b576001600160a01b03821660009081526009602052604081208054839290614b30908490615d90565b90915550614b559050565b6001600160a01b0382166000908152600960205260408120555b6001600160a01b0382166000908152600960205260409020600101548111611297576001600160a01b03821660009081526009602052604081206001018054839290613e51908490615d90565b60008060068381548110614bb857614bb8615bcd565b600091825260209182902001546040805163705727b560e01b815290516001600160a01b039092169263705727b592600480840193829003018186803b158015614c0157600080fd5b505afa158015614c15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c399190615d33565b111561471d5760068281548110614c5257614c52615bcd565b600091825260209182902001546040805163705727b560e01b815290516001600160a01b039092169263705727b592600480840193829003018186803b158015614c9b57600080fd5b505afa158015614caf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cd39190615d33565b60068381548110614ce657614ce6615bcd565b600091825260209182902001546040805163961be39160e01b815290516001600160a01b039092169263961be39192600480840193829003018186803b158015614d2f57600080fd5b505afa158015614d43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614d679190615d33565b61471390620186a0615cf9565b604051635bfd6bb960e11b8152600660048201526001600160a01b0382166024820152600090731f35fb4ba99e9676d2c2ea7b832a91fa24afe1fd9063b7fad7729060440160206040518083038186803b158015614dd157600080fd5b505af4158015614de5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106269190615d4c565b60008381526008602090815260408083206001600160a01b03861684529091529020614e358484614725565b15614e7057614e45848483613abd565b60008581526008602090815260408083206001600160a01b0388168452909152902060020155614e97565b60008481526008602090815260408083206001600160a01b03871684529091528120600201555b60008481526008602090815260408083206001600160a01b03871684529091529020426003909101556006805485908110614ed457614ed4615bcd565b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b158015614f1d57600080fd5b505afa158015614f31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614f559190615be3565b614f6090600a615cea565b614f6a9083615d6e565b60008581526008602090815260408083206001600160a01b038816845290915281206001018054909190614f9f908490615bb5565b909155505060405163e6e9237160e01b8152600760048201526001600160a01b0384166024820152731f35fb4ba99e9676d2c2ea7b832a91fa24afe1fd9063e6e9237190604401614a0f565b6000805b6006548110156150465760008181526008602090815260408083206001600160a01b03871684529091529020615026828583613abd565b6150309084615bb5565b925050808061503e90615d18565b915050614fef565b506001546040805163313ce56760e01b815290516001600160a01b0390921691637a2bbf65918591849163313ce567916004808301926020929190829003018186803b15801561509557600080fd5b505afa1580156150a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906150cd9190615be3565b6150d890600a615cea565b6150e29085615cf9565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561512857600080fd5b505af115801561513c573d6000803e3d6000fd5b5050505061514982613e5a565b816001600160a01b03167f05c2f7336f6158057f2b7e5b2559481d65df933d79a841e734b28ae9a2ef0a10600160009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156151c257600080fd5b505afa1580156151d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906151fa9190615be3565b61520590600a615cea565b61520f9084615cf9565b604051908152602001611b1d565b60008061522984613f1a565b90506152358484614725565b80156152415750600081115b156153135760008481526008602090815260408083206001600160a01b038716845290915290206001810154829061527890613eaa565b6152829190615cf9565b61529490670de0b6b3a7640000615cf9565b6002546040516370a0823160e01b81526001600160a01b0387811660048301526152c89216906370a082319060240161224a565b600b546152d59190615cf9565b6152e3906301e13380615cf9565b6152ee906064615cf9565b61530090670de0b6b3a7640000615cf9565b61530a9190615d6e565b92505050610626565b5060009392505050565b6000603c8260030154426153319190615d90565b1180156153d1575060006006848154811061534e5761534e615bcd565b60009182526020918290200154604080516318160ddd60e01b815290516001600160a01b03909216926318160ddd92600480840193829003018186803b15801561539757600080fd5b505afa1580156153ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906153cf9190615d33565b115b156155a057600683815481106153e9576153e9615bcd565b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b15801561543257600080fd5b505afa158015615446573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061546a9190615be3565b61547590600a615cea565b6006848154811061548857615488615bcd565b60009182526020918290200154604080516318160ddd60e01b815290516001600160a01b03909216926318160ddd92600480840193829003018186803b1580156154d157600080fd5b505afa1580156154e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906155099190615d33565b6155139190615d6e565b6006546155209190615cf9565b61553290670de0b6b3a7640000615cf9565b61553f90620186a0615cf9565b6155476157b6565b61555085614ba2565b600385015461555f9042615d90565b8560010154600a546155719190615cf9565b61557b9190615cf9565b6155859190615cf9565b61558f9190615cf9565b6155999190615d6e565b9050610626565b506000610626565b6000603c8260030154426155bc9190615d90565b11156156ad5760006155cd85613f1a565b90508015612a32576155e781670de0b6b3a7640000615cf9565b60038401546155f69042615d90565b6002546040516370a0823160e01b81526001600160a01b0388811660048301526156849216906370a082319060240160206040518083038186803b15801561563d57600080fd5b505afa158015615651573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906156759190615d33565b86600101546118a09190615cf9565b600b546156919190615cf9565b61569b9190615cf9565b6156a59190615d6e565b915050612a3f565b506000612a3f565b6000603c8260030154426156c99190615d90565b11156155a0576000670de0b6b3a76400008360030154426156ea9190615d90565b8460010154600c546156fc9190615cf9565b6157069190615cf9565b6157109190615d6e565b600154600c546003860154604051638faaf34760e01b81526001600160a01b03898116600483015260248201939093526044810191909152929350600092911690638faaf3479060640160206040518083038186803b15801561577257600080fd5b505afa158015615786573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906157aa9190615d33565b905061530a8183615bb5565b60008060005b600654811015613f0557600681815481106157d9576157d9615bcd565b600091825260209182902001546040805163313ce56760e01b815290516001600160a01b039092169263313ce56792600480840193829003018186803b15801561582257600080fd5b505afa158015615836573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061585a9190615be3565b61586590600a615cea565b6006828154811061587857615878615bcd565b60009182526020918290200154604080516318160ddd60e01b815290516001600160a01b03909216926318160ddd92600480840193829003018186803b1580156158c157600080fd5b505afa1580156158d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906158f99190615d33565b6159039190615d6e565b61590d9083615bb5565b91508061591981615d18565b9150506157bc565b6001600160a01b0381168114611a3e57600080fd5b6000806040838503121561594957600080fd5b82359150602083013561595b81615921565b809150509250929050565b60006020828403121561597857600080fd5b813561062381615921565b600081518084526020808501945080840160005b838110156159b357815187529582019590820190600101615997565b509495945050505050565b8381526060602082015260006159d76060830185615983565b828103604084015261231b8185615983565b6000602082840312156159fb57600080fd5b5035919050565b60008060008060808587031215615a1857600080fd5b8435615a2381615921565b966020860135965060408601359560600135945092505050565b60008060408385031215615a5057600080fd5b8235615a5b81615921565b946020939093013593505050565b600080600080600060a08688031215615a8157600080fd5b853594506020860135615a9381615921565b94979496505050506040830135926060810135926080909101359150565b600080600060608486031215615ac657600080fd5b8335615ad181615921565b95602085013595506040909401359392505050565b60008060408385031215615af957600080fd5b50508035926020909101359150565b60008060008060808587031215615b1e57600080fd5b843593506020850135615b3081615921565b93969395505050506040820135916060013590565b600080600080600060a08688031215615b5d57600080fd5b8535615b6881615921565b97602087013597506040870135966060810135965060800135945092505050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115615bc857615bc8615b9f565b500190565b634e487b7160e01b600052603260045260246000fd5b600060208284031215615bf557600080fd5b815160ff8116811461062357600080fd5b600181815b80851115615c41578160001904821115615c2757615c27615b9f565b80851615615c3457918102915b93841c9390800290615c0b565b509250929050565b600082615c5857506001610626565b81615c6557506000610626565b8160018114615c7b5760028114615c8557615ca1565b6001915050610626565b60ff841115615c9657615c96615b9f565b50506001821b610626565b5060208310610133831016604e8410600b8410161715615cc4575081810a610626565b615cce8383615c06565b8060001904821115615ce257615ce2615b9f565b029392505050565b600061062360ff841683615c49565b6000816000190483118215151615615d1357615d13615b9f565b500290565b6000600019821415615d2c57615d2c615b9f565b5060010190565b600060208284031215615d4557600080fd5b5051919050565b600060208284031215615d5e57600080fd5b8151801515811461062357600080fd5b600082615d8b57634e487b7160e01b600052601260045260246000fd5b500490565b600082821015615da257615da2615b9f565b500390565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b8051613f1581615921565b60006020808385031215615dfa57600080fd5b825167ffffffffffffffff80821115615e1257600080fd5b818501915085601f830112615e2657600080fd5b815181811115615e3857615e38615b89565b8060051b604051601f19603f83011681018181108582111715615e5d57615e5d615b89565b604052918252848201925083810185019188831115615e7b57600080fd5b938501935b82851015615ea057615e9185615ddc565b84529385019392850192615e80565b9897505050505050505056fe6add646517a5b0f6793cd5891b7937d28a5b2981a5d88ebc7cd776088fea9041ad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f5eff886ea0ce6ca488a3d6e336d6c0f75f46d19b42c06ce5ee98e42c96d256c7a26469706673582212209c601003357ea1c63098279df1c4662a386c884efe4a9456bfe4ce1e9da37ea264736f6c63430008090033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Validator ID :
0 FTM

Amount Staked
0

Amount Delegated
0

Staking Total
0

Staking Start Epoch
0

Staking Start Time
0

Proof of Importance
0

Origination Score
0

Validation Score
0

Active
0

Online
0

Downtime
0 s
Address Amount claimed Rewards Created On Epoch Created On
Block Uncle Number Difficulty Gas Used Reward
Loading