ETH Price: $2,052.31 (-2.91%)

Contract

0x00DF2622d7B8a7BdAcD9b22D16d8FF56F2dEEFD9
 

Overview

ETH Balance

1 wei

Eth Value

Less Than $0.01 (@ $2,052.31/ETH)

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw Stake179554352023-08-20 10:43:35945 days ago1692528215IN
0x00DF2622...6F2dEEFD9
0 ETH0.0010427111.85992586
Withdraw Return179554242023-08-20 10:41:23945 days ago1692528083IN
0x00DF2622...6F2dEEFD9
0 ETH0.0011051312.5821896
Begin Stake168411752023-03-16 15:03:471102 days ago1678979027IN
0x00DF2622...6F2dEEFD9
1.2 ETH0.0150783737.00442082
Migrate Stakes168097842023-03-12 5:10:591106 days ago1678597859IN
0x00DF2622...6F2dEEFD9
0 ETH0.0052635518.2945149
Withdraw Stake168097662023-03-12 5:07:231106 days ago1678597643IN
0x00DF2622...6F2dEEFD9
0 ETH0.0017867220.43447261
Migrate Stakes168097602023-03-12 5:06:111106 days ago1678597571IN
0x00DF2622...6F2dEEFD9
0 ETH0.0061399721.33982492
Withdraw Stake168097522023-03-12 5:04:351106 days ago1678597475IN
0x00DF2622...6F2dEEFD9
0 ETH0.0016505118.87659699
Migrate Stakes168097292023-03-12 4:59:111106 days ago1678597151IN
0x00DF2622...6F2dEEFD9
0 ETH0.0053932418.74529487
Migrate Stakes168078362023-03-11 22:35:111107 days ago1678574111IN
0x00DF2622...6F2dEEFD9
0 ETH0.0083224926.05167358
Migrate Stakes168069532023-03-11 19:36:231107 days ago1678563383IN
0x00DF2622...6F2dEEFD9
0 ETH0.0107973436.0765471
Begin Stake168069112023-03-11 19:27:351107 days ago1678562855IN
0x00DF2622...6F2dEEFD9
8 ETH0.0167156136.48095646
Migrate Stakes168009692023-03-10 23:24:111108 days ago1678490651IN
0x00DF2622...6F2dEEFD9
0 ETH0.0119668839.7375421
Migrate Stakes167992442023-03-10 17:35:351108 days ago1678469735IN
0x00DF2622...6F2dEEFD9
0 ETH0.0242868181.14809231
Begin Stake167979262023-03-10 13:08:231108 days ago1678453703IN
0x00DF2622...6F2dEEFD9
4 ETH0.0099637624.45245973
Migrate Stakes167976062023-03-10 12:03:351108 days ago1678449815IN
0x00DF2622...6F2dEEFD9
0 ETH0.0118636939.63944992
Migrate Stakes167934542023-03-09 21:56:591109 days ago1678399019IN
0x00DF2622...6F2dEEFD9
0 ETH0.0143259747.86654398
Exec_begin Stake167923282023-03-09 18:07:591109 days ago1678385279IN
0x00DF2622...6F2dEEFD9
0 ETH0.0098475238.93519062
Exec_begin Stake167923052023-03-09 18:03:231109 days ago1678385003IN
0x00DF2622...6F2dEEFD9
0 ETH0.0100581939.76625056
Migrate Stakes167911342023-03-09 14:06:471109 days ago1678370807IN
0x00DF2622...6F2dEEFD9
0 ETH0.011238637.55089796
Begin Stake167904172023-03-09 11:40:591109 days ago1678362059IN
0x00DF2622...6F2dEEFD9
9 ETH0.0088877721.81182752
Begin Stake167901902023-03-09 10:54:591109 days ago1678359299IN
0x00DF2622...6F2dEEFD9
5 ETH0.0095179923.35846921
Migrate Stakes167900402023-03-09 10:24:591109 days ago1678357499IN
0x00DF2622...6F2dEEFD9
0 ETH0.0055113421.89829498
Withdraw Stake167900372023-03-09 10:24:231109 days ago1678357463IN
0x00DF2622...6F2dEEFD9
0 ETH0.0020442423.37965979
Migrate Stakes167900342023-03-09 10:23:471109 days ago1678357427IN
0x00DF2622...6F2dEEFD9
0 ETH0.0064712222.51227297
Withdraw Stake167900312023-03-09 10:23:111109 days ago1678357391IN
0x00DF2622...6F2dEEFD9
0 ETH0.0019502822.89147346
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer224944572025-05-16 8:29:23310 days ago1747384163
0x00DF2622...6F2dEEFD9
30 ETH
Transfer224944572025-05-16 8:29:23310 days ago1747384163
0x00DF2622...6F2dEEFD9
25.4126 ETH
Transfer224944122025-05-16 8:20:23310 days ago1747383623
0x00DF2622...6F2dEEFD9
30 ETH
Transfer224944122025-05-16 8:20:23310 days ago1747383623
0x00DF2622...6F2dEEFD9
25.4126 ETH
Transfer168411752023-03-16 15:03:471102 days ago1678979027
0x00DF2622...6F2dEEFD9
0.36 ETH
Transfer168097662023-03-12 5:07:231106 days ago1678597643
0x00DF2622...6F2dEEFD9
12 ETH
Transfer168097522023-03-12 5:04:351106 days ago1678597475
0x00DF2622...6F2dEEFD9
15 ETH
Transfer168069112023-03-11 19:27:351107 days ago1678562855
0x00DF2622...6F2dEEFD9
2.4 ETH
Transfer167979262023-03-10 13:08:231108 days ago1678453703
0x00DF2622...6F2dEEFD9
1.2 ETH
Transfer167904172023-03-09 11:40:591109 days ago1678362059
0x00DF2622...6F2dEEFD9
2.7 ETH
Transfer167901902023-03-09 10:54:591109 days ago1678359299
0x00DF2622...6F2dEEFD9
1.5 ETH
Transfer167900372023-03-09 10:24:231109 days ago1678357463
0x00DF2622...6F2dEEFD9
15 ETH
Transfer167900312023-03-09 10:23:111109 days ago1678357391
0x00DF2622...6F2dEEFD9
10 ETH
Transfer167887762023-03-09 6:10:111109 days ago1678342211
0x00DF2622...6F2dEEFD9
9 ETH
Transfer167865942023-03-08 22:47:591110 days ago1678315679
0x00DF2622...6F2dEEFD9
1.333 ETH
Transfer167858462023-03-08 20:15:591110 days ago1678306559
0x00DF2622...6F2dEEFD9
1.74 ETH
Transfer167852272023-03-08 18:10:231110 days ago1678299023
0x00DF2622...6F2dEEFD9
6 ETH
Transfer167849812023-03-08 17:20:471110 days ago1678296047
0x00DF2622...6F2dEEFD9
20 ETH
Transfer167849532023-03-08 17:15:111110 days ago1678295711
0x00DF2622...6F2dEEFD9
5.67 ETH
Transfer167849252023-03-08 17:09:351110 days ago1678295375
0x00DF2622...6F2dEEFD9
3.72 ETH
Transfer167848282023-03-08 16:49:471110 days ago1678294187
0x00DF2622...6F2dEEFD9
14 ETH
Transfer167846002023-03-08 16:02:471110 days ago1678291367
0x00DF2622...6F2dEEFD9
1.5 ETH
Transfer167834322023-03-08 12:07:231110 days ago1678277243
0x00DF2622...6F2dEEFD9
10 ETH
Transfer167829912023-03-08 10:37:111110 days ago1678271831
0x00DF2622...6F2dEEFD9
2.847 ETH
Transfer167789412023-03-07 20:57:591111 days ago1678222679
0x00DF2622...6F2dEEFD9
2.49179999 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code Verified (Exact Match)

Contract Name:
FlippingClubStakingContract

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Flipping Club - flippingclub.xyz
/**
 *  ______ _ _             _                _____ _       _
 * |  ____| (_)           (_)              / ____| |     | |
 * | |__  | |_ _ __  _ __  _ _ __   __ _  | |    | |_   _| |__
 * |  __| | | | '_ \| '_ \| | '_ \ / _` | | |    | | | | | '_ \
 * | |    | | | |_) | |_) | | | | | (_| | | |____| | |_| | |_) |
 * |_|    |_|_| .__/| .__/|_|_| |_|\__, |  \_____|_|\__,_|_.__/
 *            | |   | |             __/ |
 *   _____ _  |_|   |_|  _         |___/  _____            _                  _
 *  / ____| |      | |  (_)              / ____|          | |                | |
 * | (___ | |_ __ _| | ___ _ __   __ _  | |     ___  _ __ | |_ _ __ __ _  ___| |_
 *  \___ \| __/ _` | |/ / | '_ \ / _` | | |    / _ \| '_ \| __| '__/ _` |/ __| __|
 *  ____) | || (_| |   <| | | | | (_| | | |___| (_) | | | | |_| | | (_| | (__| |_
 * |_____/ \__\__,_|_|\_\_|_| |_|\__, |  \_____\___/|_| |_|\__|_|  \__,_|\___|\__|
 *                                __/ |
 *                               |___/
 *
 * @title Flipping Club Staking Contract v4.1.1 - flippingclub.xyz
 * @author Flipping Club Team - (Team B)
 */

pragma solidity 0.8.17;

import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./stakeable.sol";
import "./NFTContractFunctions.sol";
import "./burnFunctions.sol";

contract FlippingClubStakingContract is Stakeable, Pausable, Ownable {
    using SafeMath for uint256;
    uint256 private maxAllowancePerKey = 5000000000000000000;
    bytes32 private constant ADMIN = keccak256(abi.encodePacked("ADMIN"));
    bytes32 private constant EXEC = keccak256(abi.encodePacked("EXEC"));
    bytes32 private constant CLAIM = keccak256(abi.encodePacked("CLAIM"));
    address private __checkKeys;
    address private __burnKeys;
    address private __migratingContract;
    event Claimed(uint256 indexed amount, address indexed payee);
    NFTContractFunctions private ERC721KeyCards;
    burnFunctions private ERC721KeyBurn;
    migratingSourceFunctions private MigratingStakes;
    struct StakePackage {
        uint256 duration;
        uint256 percentage;
        uint256 min;
        uint256 max;
        bytes32 token;
    }

    mapping(uint256 => StakePackage[]) private Packages;

    constructor(address payable _newAdmin) {
        _grantRole(ADMIN, _newAdmin);
        _grantRole(ADMIN, msg.sender);
        _grantRole(EXEC, _newAdmin);
        _grantRole(EXEC, msg.sender);
    }

    receive() external payable {}

    function addPackage(
        uint256 _name,
        uint256 duration,
        uint256 percentage,
        uint256 min,
        uint256 max
    ) external onlyRole(ADMIN) {
        Packages[_name].push(
            StakePackage(
                duration,
                percentage,
                min,
                max,
                keccak256(abi.encodePacked(duration, percentage, min, max))
            )
        );
    }

    function getPackage(uint256 packageName)
        private
        view
        returns (StakePackage memory)
    {
        require(Packages[packageName].length > 0, "No Package");
        StakePackage memory package = Packages[packageName][0];
        return package;
    }

    function deletePackage(uint256 packageName) external onlyRole(ADMIN) {
        require(Packages[packageName].length > 0, "No Package");
        delete Packages[packageName];
    }

    function beginStake(
        uint256 _amount,
        uint256 _package,
        uint256[] memory _keysToBeUsed,
        bytes32 token,
        uint256 poolID
    ) external payable nonReentrant whenNotPaused {
        _beginStake(
            _amount,
            _package,
            _keysToBeUsed,
            msg.sender,
            token,
            poolID
        );
    }

    function exec_beginStake(
        uint256 _amount,
        uint256 _package,
        uint256 _startTime,
        address _spender,
        uint256 _numKeys,
        uint256 rewards,
        uint256 poolID
    ) external nonReentrant onlyRole(EXEC) whenNotPaused {
        StakePackage memory package = getPackage(_package);
        uint256 percentage = package.percentage;
        uint256 _timePeriodInSeconds = package.duration;
        uint256 _minStakeValue = package.min;
        uint256 _maxStakeValue = package.max;
        require(
            _amount >= _minStakeValue && _amount <= _maxStakeValue,
            "Value not in range"
        );
        require(enoughKeys(_amount, percentage, _numKeys), "Not enough Keys.");
        _admin_stake(
            _amount,
            percentage,
            _timePeriodInSeconds,
            _spender,
            _startTime,
            _numKeys,
            rewards,
            poolID
        );
    }

    function _beginStake(
        uint256 _amount,
        uint256 _package,
        uint256[] memory _keysToBeUsed,
        address _spender,
        bytes32 token,
        uint256 poolID
    ) private {
        StakePackage memory package = getPackage(_package);
        uint256 percentage = package.percentage;
        uint256 _timePeriodInSeconds = package.duration;
        uint256 _minStakeValue = package.min;
        uint256 _maxStakeValue = package.max;
        require(token == package.token, "Package is not authorized.");
        require(
            _amount >= _minStakeValue && _amount <= _maxStakeValue,
            "Stake value not in range"
        );
        require(msg.value == _amount, "Invalid amount sent.");
        require(
            checkTokens(_keysToBeUsed, _spender) == true,
            "Not all Keys owned by address."
        );
        require(checkKey() >= 1, "Address have no Key.");
        require(
            enoughKeys(_amount, percentage, _keysToBeUsed.length),
            "Not enough Keys."
        );
        burnKeys(_keysToBeUsed, _spender);

        _stake(
            _amount,
            percentage,
            _timePeriodInSeconds,
            _spender,
            _keysToBeUsed.length,
            poolID
        );
    }

    function enoughKeys(
        uint256 _amount,
        uint256 percentage,
        uint256 _numKeys
    ) private view returns (bool) {
        if (
            _amount.mul(percentage).div(100) <= _numKeys.mul(maxAllowancePerKey)
        ) {
            return true;
        }
        return false;
    }

    function migrateStakes(
        uint256 poolID,
        uint256 _securityAddedTime,
        uint256 index
    ) external nonReentrant whenNotPaused {
        (
            uint256 _amount,
            uint256 _startTime,
            uint256 percentage,
            uint256 _timePeriodInSeconds,
            uint256 _curReturn,
            uint256 _numKeys
        ) = getMigratingStake(msg.sender, index);
        _timePeriodInSeconds = _timePeriodInSeconds.add(_securityAddedTime);
        _migrateStake(
            _amount,
            percentage,
            _timePeriodInSeconds,
            _startTime,
            _numKeys,
            _curReturn,
            poolID
        );
    }



    function withdrawStake(uint256 index) external nonReentrant whenNotPaused {
        require(_hasStake(msg.sender, index), "No active positions.");
        _withdrawStake(index);
    }

    function withdrawReturn(uint256 index) external nonReentrant whenNotPaused {
        require(_hasStake(msg.sender, index), "No active positions.");
        _withdrawReturn(index);
    }

    function _withdraw_close(
        uint256 stake_index,
        address payable _spender,
        bool refund
    ) external onlyRole(EXEC) {
        require(_hasStake(_spender, stake_index), "Nothing available.");
        _admin_withdraw_close(stake_index, _spender, refund);
    }

    function hasEnoughKeys(
        uint256 _amount,
        uint256 percentage,
        uint256 _numKeys
    ) private view returns (bool) {
        if (
            _amount.mul(percentage).div(100) <= _numKeys.mul(maxAllowancePerKey)
        ) {
            return true;
        }
        return false;
    }

    function isValidAmount(
        uint256 _amount,
        uint256 _minStakeValue,
        uint256 _maxStakeValue
    ) private pure returns (bool) {
        if (_amount >= _minStakeValue && _amount <= _maxStakeValue) {
            return true;
        }
        return false;
    }

    function checkTokens(uint256[] memory _tokenList, address _msgSender)
        private
        view
        returns (bool)
    {
        require(__checkKeys != address(0), "Key Contract not set.");
        for (uint256 i = 0; i < _tokenList.length; i++) {
            if (ERC721KeyCards.ownerOf(_tokenList[i]) != _msgSender) {
                return false;
            }
        }
        return true;
    }

    function burnKeys(uint256[] memory _keysToBeUsed, address _spender)
        public
        whenNotPaused
    {
        require(__burnKeys != address(0), "Delegated Burn not set.");
        ERC721KeyBurn.burnKeys(_keysToBeUsed, _spender);
    }

    function checkKey() private view returns (uint256) {
        require(__checkKeys != address(0), "Key Contract not set.");
        return ERC721KeyCards.balanceOf(msg.sender);
    }

    function initPool(uint256 _amount, address _payee)
        external
        nonReentrant
        onlyRole(ADMIN)
    {
        payable(_payee).transfer(_amount);
    }

    function getBalance() external view returns (uint256) {
        return address(this).balance;
    }

    function setCheckKeysContractAddress(address KeysContract)
        external
        onlyRole(ADMIN)
    {
        __checkKeys = KeysContract;
        ERC721KeyCards = NFTContractFunctions(__checkKeys);
    }

    function setBurnContractAddress(address BurnContract)
        external
        onlyRole(ADMIN)
    {
        __burnKeys = BurnContract;
        ERC721KeyBurn = burnFunctions(__burnKeys);
    }

    function setmaxAllowancePerKey(uint256 _maxAllowancePerKey)
        external
        onlyRole(ADMIN)
    {
        maxAllowancePerKey = _maxAllowancePerKey;
    }

    function pause() external whenNotPaused onlyRole(ADMIN) {
        _pause();
    }

    function unPause() external whenPaused onlyRole(ADMIN) {
        _unpause();
    }

    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external pure returns (bytes4) {
        return this.onERC721Received.selector;
    }

    function setMigratingSourceContractAddress(address migratingSourceContract)
        external
        onlyRole(ADMIN)
    {
        __migratingContract = migratingSourceContract;
        MigratingStakes = migratingSourceFunctions(__migratingContract);
    }

    function getMigratingStake(address _staker, uint256 index)
        private
        view
        returns (
            uint256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        return MigratingStakes.getSingleStake(_staker, index);
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

interface burnFunctions {
    function burnKeys(uint256[] memory _keysToBeUsed, address _spender)
        external;
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

interface NFTContractFunctions {
    function balanceOf(address owner) external view returns (uint256);

    function ownerOf(uint256 tokenId) external view returns (address owner);

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    function setApprovalForAll(address operator, bool _approved) external;

    function isApprovedForAll(address owner, address operator)
        external
        view
        returns (bool);

    function approve(address to, uint256 tokenId) external;
}

File 4 of 11 : stakeable.sol
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 Flipping Club - flippingclub.xyz
/**
 *  ______ _ _             _                _____ _       _
 * |  ____| (_)           (_)              / ____| |     | |
 * | |__  | |_ _ __  _ __  _ _ __   __ _  | |    | |_   _| |__
 * |  __| | | | '_ \| '_ \| | '_ \ / _` | | |    | | | | | '_ \
 * | |    | | | |_) | |_) | | | | | (_| | | |____| | |_| | |_) |
 * |_|    |_|_| .__/| .__/|_|_| |_|\__, |  \_____|_|\__,_|_.__/
 *            | |   | |             __/ |
 *   _____ _  |_|   |_|  _         |___/  _____            _                  _
 *  / ____| |      | |  (_)              / ____|          | |                | |
 * | (___ | |_ __ _| | ___ _ __   __ _  | |     ___  _ __ | |_ _ __ __ _  ___| |_
 *  \___ \| __/ _` | |/ / | '_ \ / _` | | |    / _ \| '_ \| __| '__/ _` |/ __| __|
 *  ____) | || (_| |   <| | | | | (_| | | |___| (_) | | | | |_| | | (_| | (__| |_
 * |_____/ \__\__,_|_|\_\_|_| |_|\__, |  \_____\___/|_| |_|\__|_|  \__,_|\___|\__|
 *                                __/ |
 *                               |___/
 *
 * @title Flipping Club Staking Contract - Dependency v4.1.1 - flippingclub.xyz
 * @author Flipping Club Team - (Team B)
 */

pragma solidity 0.8.17;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./migratingSourceFunctions.sol";

contract Stakeable is ReentrancyGuard {
    using SafeMath for uint256;
    uint256 private initialTimestamp;
    uint256 private _maxAllowancePerKey = 5000000000000000000;
    uint256 private timePeriod;
    uint256 private maxPositions = 4;
    uint256 private MinStakeValueToClosePosition = 100000000000000000;
    uint256 private MovePercentageBasisNumber = 50;
    uint256 private minWithdraw = 100000000000000000;
    address private StakingAccount;
    bool private MoveFundsUponReceipt;
    bool private partialWithdraw = true;
    bool private lockdown = false;
    bool private MovePercentageOfFundsUponReceipt = true;
    bytes32 private constant ADMIN = keccak256(abi.encodePacked("ADMIN"));
    bytes32 private constant EXEC = keccak256(abi.encodePacked("EXEC"));
    bytes32 private constant CLAIM = keccak256(abi.encodePacked("CLAIM"));
    Stakeholder[] internal stakeholders;
    mapping(bytes32 => mapping(address => bool)) public roles;
    mapping(address => uint256) internal stakes;
    mapping(uint256 => poolGroup[]) private poolGroups;
    event GrantRole(bytes32 indexed role, address indexed account);
    event RevokeRole(bytes32 indexed role, address indexed account);
    event Withdrawn(address indexed, uint256 amount, uint256 timestamp);
    event Extended(
        address user,
        uint256 amount,
        uint256 since,
        uint256 reward,
        uint256 timePeriod,
        uint256 usedKeys
    );
    event Staked(
        address indexed user,
        uint256 amount,
        uint256 index,
        uint256 timestamp,
        uint256 _plan,
        uint256 timePeriod,
        uint256 usedKeys
    );
    event Migrated(
        address indexed user,
        uint256 amount,
        uint256 index,
        uint256 timestamp,
        uint256 _plan,
        uint256 timePeriod,
        uint256 usedKeys
    );
    struct Stake {
        address user;
        uint256 amount;
        uint256 since;
        uint256 percentage;
        uint256 timePeriod;
        uint256 reward;
        uint256 usedKeys;
        bool paused;
        uint256 poolID;
    }
    struct Stakeholder {
        address user;
        Stake[] address_stakes;
    }
    struct poolGroup {
        uint256 id;
        bool active;
    }
    struct StakingSummary {
        Stake[] stakes;
    }

    constructor() {
        stakeholders.push();
    }

    function _addStakeholder(address staker) private returns (uint256) {
        stakeholders.push();
        uint256 userIndex = stakeholders.length - 1;
        stakeholders[userIndex].user = staker;
        stakes[staker] = userIndex;
        return userIndex;
    }

    function _stake(
        uint256 _amount,
        uint256 _percentage,
        uint256 _timePeriodInSeconds,
        address _Sender,
        uint256 usedKeys,
        uint256 poolID
    ) internal {
        require(poolGroups[poolID].length > 0, "No Pool");
        require(StakingAccount != address(0), "Staking account not set.");
        require(canStake(_Sender, _percentage), "Max open positions.");
        if (MoveFundsUponReceipt) {
            payable(StakingAccount).transfer(_amount);
        }
        if (MovePercentageOfFundsUponReceipt) {
            payable(StakingAccount).transfer(
                (_amount.mul(MovePercentageBasisNumber)).div(100)
            );
        }
        uint256 index = stakes[_Sender];
        uint256 timestamp = block.timestamp;
        if (index == 0) {
            index = _addStakeholder(_Sender);
        }
        initialTimestamp = block.timestamp;
        timePeriod = initialTimestamp.add(_timePeriodInSeconds);
        stakeholders[index].address_stakes.push(
            Stake(
                payable(_Sender),
                _amount,
                timestamp,
                _percentage,
                timePeriod,
                0,
                usedKeys,
                false,
                poolID
            )
        );
        emit Staked(
            _Sender,
            _amount,
            index,
            timestamp,
            _percentage,
            timePeriod,
            usedKeys
        );
    }

    function _admin_stake(
        uint256 _amount,
        uint256 _percentage,
        uint256 _timePeriodInSeconds,
        address _Sender,
        uint256 _startTime,
        uint256 usedKeys,
        uint256 rewards,
        uint256 poolID
    ) internal {
        require(canStake(_Sender, _percentage), "Max open positions.");
        require(poolGroups[poolID].length > 0, "No Pool");
        uint256 index = stakes[_Sender];
        uint256 timestamp = _startTime;
        if (index == 0) {
            index = _addStakeholder(_Sender);
        }
        initialTimestamp = _startTime;
        timePeriod = initialTimestamp.add(_timePeriodInSeconds);
        stakeholders[index].address_stakes.push(
            Stake(
                payable(_Sender),
                _amount,
                timestamp,
                _percentage,
                timePeriod,
                rewards,
                usedKeys,
                false,
                poolID
            )
        );
        emit Staked(
            _Sender,
            _amount,
            index,
            timestamp,
            _percentage,
            timePeriod,
            usedKeys
        );
    }

    function _migrateStake(
        uint256 _amount,
        uint256 _percentage,
        uint256 _timePeriodInSeconds,
        uint256 _startTime,
        uint256 usedKeys,
        uint256 _reward,
        uint256 poolID
    ) internal {
        require(poolGroups[poolID].length > 0, "No Pool");
        require(canStake(msg.sender, _percentage), "Max open positions.");
        uint256 index = stakes[msg.sender];
        if (index == 0) {
            index = _addStakeholder(msg.sender);
        }
        stakeholders[index].address_stakes.push(
            Stake(
                msg.sender,
                _amount,
                _startTime,
                _percentage,
                _timePeriodInSeconds,
                _reward,
                usedKeys,
                false,
                poolID
            )
        );
        emit Migrated(
            msg.sender,
            _amount,
            index,
            _startTime,
            _percentage,
            _timePeriodInSeconds,
            usedKeys
        );
    }

    function calculateStakeReward(Stake memory _current_stake)
        private
        view
        returns (uint256)
    {
        if (block.timestamp > _current_stake.timePeriod) {
            return
                (_current_stake.amount.mul(_current_stake.percentage)).div(100);
        }
        return 0;
    }

    function toggleStakeStatus(
        address _staker,
        bool _status,
        uint256 index
    ) external onlyRole(EXEC) {
        uint256 user_index = stakes[_staker];
        require(user_index > 0, "Address not registered.");
        Stake memory current_stake = stakeholders[user_index].address_stakes[
            index
        ];
        require(current_stake.amount > 0, "No active positions.");
        stakeholders[user_index].address_stakes[index].paused = _status;
    }

    function _withdrawStake(uint256 index) internal {
        require(lockdown == false, "Contract Locked.");
        uint256 user_index = stakes[msg.sender];
        require(user_index > 0, "Address not registered.");
        require(index <= maxPositions - 1, "Index out of range.");
        Stake memory current_stake = stakeholders[user_index].address_stakes[
            index
        ];
        require(
            poolGroups[current_stake.poolID][0].active,
            "Pool Temporary Suspended"
        );
        require(current_stake.amount > 0, "No active positions.");
        require(
            block.timestamp >= current_stake.timePeriod,
            "Not matured yet."
        );
        uint256 reward = current_stake.reward.add(
            calculateStakeReward(current_stake)
        );
        require(reward > 0, "Claim not ready.");
        uint256 _amount = current_stake.amount.add(reward);
        require(_amount >= minWithdraw, "Amount is less than minimum");
        require(address(this).balance > _amount, "Not enough balance.");
        delete stakeholders[user_index].address_stakes[index];
        stakeholders[user_index].address_stakes[index] = stakeholders[
            user_index
        ].address_stakes[stakeholders[user_index].address_stakes.length - 1];
        stakeholders[user_index].address_stakes.pop();
        payable(msg.sender).transfer(_amount);
        emit Withdrawn(msg.sender, _amount, block.timestamp);
    }

    function _withdrawReturn(uint256 index) internal {
        require(lockdown == false, "Contract Locked.");
        uint256 user_index = stakes[msg.sender];
        require(user_index > 0, "Address not registered.");
        require(partialWithdraw, "Partial withdraw is not enabled.");
        require(index <= maxPositions - 1, "Index out of range.");
        Stake memory current_stake = stakeholders[user_index].address_stakes[
            index
        ];
        require(
            poolGroups[current_stake.poolID][0].active,
            "Pool Temporary Suspended"
        );
        require(current_stake.amount > 0, "No active positions.");

        require(
            block.timestamp >= current_stake.timePeriod,
            "Not matured yet."
        );
        uint256 reward = current_stake.reward.add(
            calculateStakeReward(current_stake)
        );
        require(reward > 0, "Claim not ready.");
        uint256 _amount = reward;
        require(_amount >= minWithdraw, "Amount is less than minimum");
        require(address(this).balance > _amount, "Not enough balance.");

        if (
            _enoughKeys(
                stakeholders[user_index].address_stakes[index].amount,
                stakeholders[user_index].address_stakes[index].percentage,
                reward,
                stakeholders[user_index].address_stakes[index].usedKeys
            )
        ) {
            uint256 timeDiff = (
                stakeholders[user_index].address_stakes[index].timePeriod
            ).sub(stakeholders[user_index].address_stakes[index].since);
            stakeholders[user_index].address_stakes[index].since = block
                .timestamp;
            stakeholders[user_index].address_stakes[index].timePeriod = block
                .timestamp
                .add(timeDiff);
            stakeholders[user_index].address_stakes[index].reward = 0;
            payable(msg.sender).transfer(_amount);
            emit Withdrawn(msg.sender, _amount, block.timestamp);
            emit Extended(
                stakeholders[user_index].address_stakes[index].user,
                stakeholders[user_index].address_stakes[index].amount,
                stakeholders[user_index].address_stakes[index].since,
                stakeholders[user_index].address_stakes[index].reward,
                stakeholders[user_index].address_stakes[index].timePeriod,
                stakeholders[user_index].address_stakes[index].usedKeys
            );
        } else {
            _amount = current_stake.amount.add(reward);
            delete stakeholders[user_index].address_stakes[index];
            stakeholders[user_index].address_stakes[index] = stakeholders[
                user_index
            ].address_stakes[
                    stakeholders[user_index].address_stakes.length - 1
                ];
            stakeholders[user_index].address_stakes.pop();
            payable(msg.sender).transfer(_amount);
            emit Withdrawn(msg.sender, _amount, block.timestamp);
        }
    }

    function _admin_withdraw_close(
        uint256 index,
        address payable _spender,
        bool refund
    ) internal {
        uint256 user_index = stakes[_spender];
        Stake memory current_stake = stakeholders[user_index].address_stakes[
            index
        ];
        uint256 reward = current_stake.reward.add(
            calculateStakeReward(current_stake)
        );

        uint256 claimable = current_stake.amount.add(reward);
        delete stakeholders[user_index].address_stakes[index];
        stakeholders[user_index].address_stakes[index] = stakeholders[
            user_index
        ].address_stakes[stakeholders[user_index].address_stakes.length - 1];
        stakeholders[user_index].address_stakes.pop();
        if (refund) {
            require(address(this).balance >= claimable, "Not enough balance.");
            payable(_spender).transfer(claimable);
        }
    }

    function _extendStake(uint256 index) public {
        require(lockdown == false, "Contract Locked.");
        uint256 user_index = stakes[msg.sender];
        require(user_index > 0, "Address not registered.");
        require(index <= maxPositions - 1, "Index out of range.");
        Stake memory current_stake = stakeholders[user_index].address_stakes[
            index
        ];
        require(current_stake.amount > 0, "No active positions.");
        uint256 reward = current_stake.reward.add(
            calculateStakeReward(current_stake)
        );
        require(
            poolGroups[current_stake.poolID][0].active,
            "Pool Temporary Suspended"
        );
        require(reward > 0, "Extend not Possible.");
        require(
            _enoughKeys(
                stakeholders[user_index].address_stakes[index].amount,
                stakeholders[user_index].address_stakes[index].percentage,
                reward,
                stakeholders[user_index].address_stakes[index].usedKeys
            ),
            "Not enough allowance left."
        );
        uint256 timeDiff = (
            stakeholders[user_index].address_stakes[index].timePeriod
        ).sub(stakeholders[user_index].address_stakes[index].since);
        stakeholders[user_index].address_stakes[index].since = block.timestamp;
        stakeholders[user_index].address_stakes[index].timePeriod = block
            .timestamp
            .add(timeDiff);
        stakeholders[user_index].address_stakes[index].reward = reward;
        emit Extended(
            stakeholders[user_index].address_stakes[index].user,
            stakeholders[user_index].address_stakes[index].amount,
            stakeholders[user_index].address_stakes[index].since,
            stakeholders[user_index].address_stakes[index].reward,
            stakeholders[user_index].address_stakes[index].timePeriod,
            stakeholders[user_index].address_stakes[index].usedKeys
        );
    }

    function _changeEndTime(
        uint256 index,
        address staker,
        uint256 newTime
    ) public onlyRole(EXEC){
        require(lockdown == false, "Contract Locked.");
        uint256 user_index = stakes[staker];
        require(user_index > 0, "Address not registered.");
        require(index <= maxPositions - 1, "Index out of range.");
        Stake memory current_stake = stakeholders[user_index].address_stakes[
            index
        ];
        require(current_stake.amount > 0, "No active positions.");
        stakeholders[user_index].address_stakes[index].timePeriod = newTime;
    }

    function _enoughKeys(
        uint256 _amount,
        uint256 _PlanReward,
        uint256 _FutReward,
        uint256 _numKeys
    ) internal view returns (bool) {
        if (
            _amount.mul(_PlanReward).div(100).add(_FutReward) <=
            _numKeys.mul(_maxAllowancePerKey)
        ) {
            return true;
        }
        return false;
    }

    function _stakeLength(address _staker) external view returns (uint256) {
        StakingSummary memory summary = StakingSummary(
            stakeholders[stakes[_staker]].address_stakes
        );
        return summary.stakes.length;
    }

    function getAllStakes(address _staker)
        external
        view
        returns (StakingSummary memory)
    {
        StakingSummary memory summary = StakingSummary(
            stakeholders[stakes[_staker]].address_stakes
        );
        for (uint256 s = 0; s < summary.stakes.length; s += 1) {
            uint256 availableReward = calculateStakeReward(summary.stakes[s]);
            summary.stakes[s].reward = summary.stakes[s].reward.add(
                availableReward
            );
        }
        return summary;
    }

    function getSingleStake(address _staker, uint256 index)
        external
        view
        returns (
            uint256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        )
    {
        require(index <= maxPositions - 1, "Index out of range.");
        StakingSummary memory summary = StakingSummary(
            stakeholders[stakes[_staker]].address_stakes
        );
        require(summary.stakes.length > 0, "No active positions.");
        require(summary.stakes.length > index, "Index not valid.");

        for (uint256 s = 0; s < summary.stakes.length; s += 1) {
            uint256 availableReward = calculateStakeReward(summary.stakes[s]);
            summary.stakes[s].reward = summary.stakes[s].reward.add(
                availableReward
            );
        }
        return (
            summary.stakes[index].amount,
            summary.stakes[index].since,
            summary.stakes[index].percentage,
            summary.stakes[index].timePeriod,
            summary.stakes[index].reward,
            summary.stakes[index].usedKeys
        );
    }

    function _hasStake(address _staker, uint256 index)
        internal
        view
        returns (bool)
    {
        require(index <= maxPositions - 1, "Index out of range.");
        StakingSummary memory summary = StakingSummary(
            stakeholders[stakes[_staker]].address_stakes
        );
        if (summary.stakes.length > 0 && summary.stakes.length > index) {
            return true;
        }
        return false;
    }

    function canStake(address _staker, uint256 _percentage)
        private
        view
        returns (bool result)
    {
        StakingSummary memory summary = StakingSummary(
            stakeholders[stakes[_staker]].address_stakes
        );
        if (summary.stakes.length >= maxPositions) {
            return false;
        }

        for (uint256 s = 0; s < summary.stakes.length; s += 1) {
            if (summary.stakes[s].percentage == _percentage) {
                return false;
            }
        }
        return true;
    }

    function setMaxPositions(uint256 _maxPositions) external onlyRole(ADMIN) {
        maxPositions = _maxPositions;
    }

    function setMinStakeValueToClosePosition(
        uint256 _MinStakeValueToClosePosition
    ) external onlyRole(ADMIN) {
        MinStakeValueToClosePosition = _MinStakeValueToClosePosition;
    }

    function setStakingAccount(address _StakingAccount)
        external
        onlyRole(ADMIN)
    {
        StakingAccount = _StakingAccount;
    }

    function setMoveFundsUponReceipt(bool _MoveFundsUponReceipt)
        external
        onlyRole(ADMIN)
    {
        MoveFundsUponReceipt = _MoveFundsUponReceipt;
    }

    function setMovePercentageBasisNumber(uint256 _MovePercentageBasisNumber)
        external
        onlyRole(ADMIN)
    {
        MovePercentageBasisNumber = _MovePercentageBasisNumber;
    }

    function setPartialWithdraw(bool _partialWithdraw)
        external
        onlyRole(ADMIN)
    {
        partialWithdraw = _partialWithdraw;
    }

    function setMovePercentageOfFundsUponReceipt(
        bool _MovePercentageOfFundsUponReceipt
    ) external onlyRole(ADMIN) {
        MovePercentageOfFundsUponReceipt = _MovePercentageOfFundsUponReceipt;
    }
    function _onlyRole(bytes32 _role) public view {
        require(roles[_role][msg.sender], "Not authorized.");
    }
    modifier onlyRole(bytes32 _role) {
        _onlyRole(_role);
        _;
    }

    function _grantRole(bytes32 _role, address _account) internal {
        roles[_role][_account] = true;
        emit GrantRole(_role, _account);
    }

    function grantRole(bytes32 _role, address _account)
        external
        onlyRole(ADMIN)
    {
        _grantRole(_role, _account);
    }

    function _revokeRole(bytes32 _role, address _account) internal {
        roles[_role][_account] = false;
        emit RevokeRole(_role, _account);
    }

    function revokeRole(bytes32 _role, address _account)
        external
        onlyRole(ADMIN)
    {
        _revokeRole(_role, _account);
    }

    function set_maxAllowancePerKey(uint256 __maxAllowancePerKey)
        external
        onlyRole(ADMIN)
    {
        _maxAllowancePerKey = __maxAllowancePerKey;
    }

    function setMinWithdraw(uint256 _minWithdraw) external onlyRole(ADMIN) {
        minWithdraw = _minWithdraw;
    }

    function toggleLockdown(bool _status) external onlyRole(EXEC) {
        lockdown = _status;
    }

    function addPoolGroup(uint256 id, bool active) external onlyRole(ADMIN) {
        poolGroups[id].push(poolGroup(id, active));
    }

    function getPoolGroup(uint256 poolID)
        public
        view
        returns (poolGroup memory)
    {
        require(poolGroups[poolID].length > 0, "No Pool");
        poolGroup memory pool = poolGroups[poolID][0];
        return pool;
    }

    function deletePoolGroup(uint256 poolID) external onlyRole(ADMIN) {
        require(poolGroups[poolID].length > 0, "No Pool");
        delete poolGroups[poolID];
    }

    function togglePoolGroupStatus(uint256 poolID, bool _status)
        external
        onlyRole(EXEC)
    {
        poolGroups[poolID][0].active = _status;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

File 10 of 11 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

interface migratingSourceFunctions {
    function getSingleStake(address _staker, uint256 index)
        external
        view
        returns (
            uint256,
            uint256,
            uint256,
            uint256,
            uint256,
            uint256
        );
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address payable","name":"_newAdmin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"payee","type":"address"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"since","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timePeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usedKeys","type":"uint256"}],"name":"Extended","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"GrantRole","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_plan","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timePeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usedKeys","type":"uint256"}],"name":"Migrated","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"RevokeRole","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_plan","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timePeriod","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usedKeys","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"staker","type":"address"},{"internalType":"uint256","name":"newTime","type":"uint256"}],"name":"_changeEndTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"_extendStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_role","type":"bytes32"}],"name":"_onlyRole","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"}],"name":"_stakeLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stake_index","type":"uint256"},{"internalType":"address payable","name":"_spender","type":"address"},{"internalType":"bool","name":"refund","type":"bool"}],"name":"_withdraw_close","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_name","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"uint256","name":"min","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"addPackage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"name":"addPoolGroup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_package","type":"uint256"},{"internalType":"uint256[]","name":"_keysToBeUsed","type":"uint256[]"},{"internalType":"bytes32","name":"token","type":"bytes32"},{"internalType":"uint256","name":"poolID","type":"uint256"}],"name":"beginStake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_keysToBeUsed","type":"uint256[]"},{"internalType":"address","name":"_spender","type":"address"}],"name":"burnKeys","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"packageName","type":"uint256"}],"name":"deletePackage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolID","type":"uint256"}],"name":"deletePoolGroup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_package","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_numKeys","type":"uint256"},{"internalType":"uint256","name":"rewards","type":"uint256"},{"internalType":"uint256","name":"poolID","type":"uint256"}],"name":"exec_beginStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"}],"name":"getAllStakes","outputs":[{"components":[{"components":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"since","type":"uint256"},{"internalType":"uint256","name":"percentage","type":"uint256"},{"internalType":"uint256","name":"timePeriod","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"usedKeys","type":"uint256"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"uint256","name":"poolID","type":"uint256"}],"internalType":"struct Stakeable.Stake[]","name":"stakes","type":"tuple[]"}],"internalType":"struct Stakeable.StakingSummary","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolID","type":"uint256"}],"name":"getPoolGroup","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct Stakeable.poolGroup","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getSingleStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_role","type":"bytes32"},{"internalType":"address","name":"_account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_payee","type":"address"}],"name":"initPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolID","type":"uint256"},{"internalType":"uint256","name":"_securityAddedTime","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"migrateStakes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_role","type":"bytes32"},{"internalType":"address","name":"_account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"roles","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"BurnContract","type":"address"}],"name":"setBurnContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"KeysContract","type":"address"}],"name":"setCheckKeysContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxPositions","type":"uint256"}],"name":"setMaxPositions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"migratingSourceContract","type":"address"}],"name":"setMigratingSourceContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MinStakeValueToClosePosition","type":"uint256"}],"name":"setMinStakeValueToClosePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minWithdraw","type":"uint256"}],"name":"setMinWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_MoveFundsUponReceipt","type":"bool"}],"name":"setMoveFundsUponReceipt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_MovePercentageBasisNumber","type":"uint256"}],"name":"setMovePercentageBasisNumber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_MovePercentageOfFundsUponReceipt","type":"bool"}],"name":"setMovePercentageOfFundsUponReceipt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_partialWithdraw","type":"bool"}],"name":"setPartialWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_StakingAccount","type":"address"}],"name":"setStakingAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"__maxAllowancePerKey","type":"uint256"}],"name":"set_maxAllowancePerKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxAllowancePerKey","type":"uint256"}],"name":"setmaxAllowancePerKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"toggleLockdown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolID","type":"uint256"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"togglePoolGroupStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"},{"internalType":"bool","name":"_status","type":"bool"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"toggleStakeStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"withdrawReturn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"withdrawStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052674563918244f4000060028190556004805567016345785d8a0000600581905560326006556007556008805462ffffff60a81b19166201000160a81b179055600e553480156200005357600080fd5b506040516200576f3803806200576f83398101604081905262000076916200020e565b6001600081815560098054909201825552600d805460ff191690556200009c3362000159565b6040516420a226a4a760d91b6020820152620000d9906025015b6040516020818303038152906040528051906020012082620001b360201b60201c565b6040516420a226a4a760d91b602082015262000116906025015b6040516020818303038152906040528051906020012033620001b360201b60201c565b604051634558454360e01b60208201526200013490602401620000b6565b604051634558454360e01b60208201526200015290602401620000f3565b5062000240565b600d80546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f5a06360d65acf95e98445dc834f205063424c636e65418d928cdfabc33a953999190a35050565b6000602082840312156200022157600080fd5b81516001600160a01b03811681146200023957600080fd5b9392505050565b61551f80620002506000396000f3fe6080604052600436106102805760003560e01c8063744a80681161014f578063a4ca8c7a116100c1578063d547741f1161007a578063d547741f14610807578063d71c100814610827578063ec5a82e414610847578063f2fde38b14610867578063f7b188a514610887578063f8fc08b91461089c57600080fd5b8063a4ca8c7a14610747578063a865e8ce14610767578063a93e052314610787578063b06113fe146107a7578063bb32fbb1146107c7578063d0c4cab6146107e757600080fd5b80638da5cb5b116101135780638da5cb5b1461067e5780638e699bc8146106b457806399b1d958146106d457806399d9af52146106f4578063a2e30f1514610714578063a48963611461073457600080fd5b8063744a8068146105e957806381cdf7661461060957806382d0fd4a146106295780638456cb59146106495780638c4477231461065e57600080fd5b80632edbb1f9116101f35780635c975abb116101ac5780635c975abb14610530578063654a3c7c1461055457806368888dc3146105745780636c12eb1c14610594578063715018a6146105b457806371dad42f146105c957600080fd5b80632edbb1f9146104705780632f2ff15d1461049057806335aa134a146104b05780633b289665146104d05780634a493cb6146104f057806350690fc01461051057600080fd5b806312065fe01161024557806312065fe014610361578063150b7a021461037e57806315914247146103c35780631c8050c7146104105780632514f5301461043057806325d5971f1461045057600080fd5b8062b7e5261461028c57806304238994146102ae57806305a2308b146102e457806309e933961461030457806311a859f11461034157600080fd5b3661028757005b600080fd5b34801561029857600080fd5b506102ac6102a7366004614cbf565b6108d7565b005b3480156102ba57600080fd5b506102ce6102c9366004614d1b565b610a02565b6040516102db9190614d38565b60405180910390f35b3480156102f057600080fd5b506102ac6102ff366004614de7565b610bc0565b34801561031057600080fd5b5061032461031f366004614e13565b610c28565b6040805182518152602092830151151592810192909252016102db565b34801561034d57600080fd5b506102ac61035c366004614e41565b610cbb565b34801561036d57600080fd5b50475b6040519081526020016102db565b34801561038a57600080fd5b506103aa610399366004614e7f565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016102db565b3480156103cf57600080fd5b506103e36103de366004614f1e565b610e57565b604080519687526020870195909552938501929092526060840152608083015260a082015260c0016102db565b34801561041c57600080fd5b506102ac61042b366004614d1b565b611155565b34801561043c57600080fd5b506102ac61044b366004614d1b565b6111a6565b34801561045c57600080fd5b506102ac61046b366004614e13565b611201565b34801561047c57600080fd5b506102ac61048b366004614f4a565b61124d565b34801561049c57600080fd5b506102ac6104ab366004614f82565b611434565b3480156104bc57600080fd5b506102ac6104cb366004614e13565b61146c565b3480156104dc57600080fd5b506102ac6104eb366004614d1b565b6114a0565b3480156104fc57600080fd5b506102ac61050b366004614fb2565b6114fb565b34801561051c57600080fd5b506102ac61052b36600461507e565b611548565b34801561053c57600080fd5b50600d5460ff165b60405190151581526020016102db565b34801561056057600080fd5b506102ac61056f366004614e13565b611610565b34801561058057600080fd5b506102ac61058f366004614e13565b61164f565b3480156105a057600080fd5b506102ac6105af3660046150c5565b611683565b3480156105c057600080fd5b506102ac6116f7565b3480156105d557600080fd5b506102ac6105e4366004614e13565b61170b565b3480156105f557600080fd5b506102ac6106043660046150f1565b611766565b34801561061557600080fd5b506102ac610624366004614d1b565b6117f0565b34801561063557600080fd5b506102ac6106443660046150c5565b61184b565b34801561065557600080fd5b506102ac6118d0565b34801561066a57600080fd5b506102ac610679366004614e13565b61190e565b34801561068a57600080fd5b50600d5461010090046001600160a01b03166040516001600160a01b0390911681526020016102db565b3480156106c057600080fd5b506102ac6106cf366004614e13565b611982565b3480156106e057600080fd5b506102ac6106ef366004614e13565b612066565b34801561070057600080fd5b506102ac61070f366004614fb2565b61209a565b34801561072057600080fd5b506102ac61072f36600461512f565b6120e7565b6102ac61074236600461516a565b6121df565b34801561075357600080fd5b506102ac610762366004614fb2565b61220e565b34801561077357600080fd5b506102ac610782366004614e13565b61225b565b34801561079357600080fd5b506102ac6107a2366004614f82565b61228f565b3480156107b357600080fd5b506102ac6107c2366004614fb2565b612307565b3480156107d357600080fd5b506102ac6107e2366004614e13565b612354565b3480156107f357600080fd5b50610370610802366004614d1b565b612388565b34801561081357600080fd5b506102ac610822366004614f82565b6124a4565b34801561083357600080fd5b506102ac610842366004614e13565b6124dc565b34801561085357600080fd5b506102ac610862366004614e13565b612569565b34801561087357600080fd5b506102ac610882366004614d1b565b61259d565b34801561089357600080fd5b506102ac612613565b3480156108a857600080fd5b506105446108b7366004614f82565b600a60209081526000928352604080842090915290825290205460ff1681565b6108df612651565b6040516020016108ee906151cc565b6040516020818303038152906040528051906020012061090d8161170b565b6109156126aa565b6000610920886126f0565b60208101518151604083015160608401519394509192909190818d108015906109495750808d11155b61098f5760405162461bcd60e51b815260206004820152601260248201527156616c7565206e6f7420696e2072616e676560701b60448201526064015b60405180910390fd5b61099a8d858b6127e1565b6109d95760405162461bcd60e51b815260206004820152601060248201526f2737ba1032b737bab3b41025b2bcb99760811b6044820152606401610986565b6109e98d85858d8f8e8e8e612825565b5050505050506109f96001600055565b50505050505050565b60408051602081019091526060815260408051602080820183526001600160a01b0385166000908152600b90915291822054600980548392908110610a4957610a496151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b82821015610b1057600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e0840152600801546101008301529083529092019101610a7a565b505050915250905060005b815151811015610bb9576000610b4d83600001518381518110610b4057610b406151dc565b6020026020010151612a65565b9050610b838184600001518481518110610b6957610b696151dc565b602002602001015160a00151612aa190919063ffffffff16565b8351805184908110610b9757610b976151dc565b602090810291909101015160a0015250610bb2600182615208565b9050610b1b565b5092915050565b610bc8612651565b610bd06126aa565b600080600080600080610be33388612aad565b955095509550955095509550610c028884612aa190919063ffffffff16565b9250610c138685858885878f612b44565b505050505050610c236001600055565b505050565b60408051808201909152600080825260208201526000828152600c6020526040902054610c675760405162461bcd60e51b81526004016109869061521b565b6000828152600c6020526040812080548290610c8557610c856151dc565b600091825260209182902060408051808201909152600290920201805482526001015460ff161515918101919091529392505050565b604051602001610cca906151cc565b60405160208183030381529060405280519060200120610ce98161170b565b6001600160a01b0384166000908152600b602052604090205480610d1f5760405162461bcd60e51b81526004016109869061523c565b600060098281548110610d3457610d346151dc565b90600052602060002090600202016001018481548110610d5657610d566151dc565b60009182526020918290206040805161012081018252600990930290910180546001600160a01b0316835260018101549383018490526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff16151560e0830152600801546101008201529150610df75760405162461bcd60e51b815260040161098690615273565b8460098381548110610e0b57610e0b6151dc565b90600052602060002090600202016001018581548110610e2d57610e2d6151dc565b60009182526020909120600990910201600701805460ff1916911515919091179055505050505050565b6000806000806000806001600454610e6f91906152a1565b871115610e8e5760405162461bcd60e51b8152600401610986906152b4565b60408051602080820183526001600160a01b038b166000908152600b90915291822054600980548392908110610ec657610ec66151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b82821015610f8d57600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e0840152600801546101008301529083529092019101610ef7565b505050915250805151909150610fb55760405162461bcd60e51b815260040161098690615273565b8051518810610ff95760405162461bcd60e51b815260206004820152601060248201526f24b73232bc103737ba103b30b634b21760811b6044820152606401610986565b60005b81515181101561107357600061102183600001518381518110610b4057610b406151dc565b905061103d8184600001518481518110610b6957610b696151dc565b8351805184908110611051576110516151dc565b602090810291909101015160a001525061106c600182615208565b9050610ffc565b508051805189908110611088576110886151dc565b602002602001015160200151816000015189815181106110aa576110aa6151dc565b60200260200101516040015182600001518a815181106110cc576110cc6151dc565b60200260200101516060015183600001518b815181106110ee576110ee6151dc565b60200260200101516080015184600001518c81518110611110576111106151dc565b602002602001015160a0015185600001518d81518110611132576111326151dc565b602002602001015160c00151965096509650965096509650509295509295509295565b604051602001611164906152e1565b604051602081830303815290604052805190602001206111838161170b565b50600880546001600160a01b0319166001600160a01b0392909216919091179055565b6040516020016111b5906152e1565b604051602081830303815290604052805190602001206111d48161170b565b50601180546001600160a01b039092166001600160a01b0319928316811790915560148054909216179055565b611209612651565b6112116126aa565b61121b3382612d60565b6112375760405162461bcd60e51b815260040161098690615273565b61124081612eb9565b61124a6001600055565b50565b60405160200161125c906151cc565b6040516020818303038152906040528051906020012061127b8161170b565b600854600160b01b900460ff16156112a55760405162461bcd60e51b8152600401610986906152f2565b6001600160a01b0383166000908152600b6020526040902054806112db5760405162461bcd60e51b81526004016109869061523c565b60016004546112ea91906152a1565b8511156113095760405162461bcd60e51b8152600401610986906152b4565b60006009828154811061131e5761131e6151dc565b90600052602060002090600202016001018681548110611340576113406151dc565b60009182526020918290206040805161012081018252600990930290910180546001600160a01b0316835260018101549383018490526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff16151560e08301526008015461010082015291506113e15760405162461bcd60e51b815260040161098690615273565b83600983815481106113f5576113f56151dc565b90600052602060002090600202016001018781548110611417576114176151dc565b906000526020600020906009020160040181905550505050505050565b604051602001611443906152e1565b604051602081830303815290604052805190602001206114628161170b565b610c238383613456565b60405160200161147b906152e1565b6040516020818303038152906040528051906020012061149a8161170b565b50600755565b6040516020016114af906152e1565b604051602081830303815290604052805190602001206114ce8161170b565b50600f80546001600160a01b039092166001600160a01b0319928316811790915560128054909216179055565b60405160200161150a906151cc565b604051602081830303815290604052805190602001206115298161170b565b5060088054911515600160b01b0260ff60b01b19909216919091179055565b6115506126aa565b6010546001600160a01b03166115a85760405162461bcd60e51b815260206004820152601760248201527f44656c656761746564204275726e206e6f74207365742e0000000000000000006044820152606401610986565b601354604051630141a43f60e61b81526001600160a01b03909116906350690fc0906115da908590859060040161531c565b600060405180830381600087803b1580156115f457600080fd5b505af1158015611608573d6000803e3d6000fd5b505050505050565b611618612651565b6116206126aa565b61162a3382612d60565b6116465760405162461bcd60e51b815260040161098690615273565b611240816134b1565b60405160200161165e906152e1565b6040516020818303038152906040528051906020012061167d8161170b565b50600455565b604051602001611692906151cc565b604051602081830303815290604052805190602001206116b18161170b565b6000838152600c6020526040812080548492906116d0576116d06151dc565b60009182526020909120600290910201600101805460ff1916911515919091179055505050565b6116ff613ca0565b6117096000613d00565b565b6000818152600a6020908152604080832033845290915290205460ff1661124a5760405162461bcd60e51b815260206004820152600f60248201526e2737ba1030baba3437b934bd32b21760891b6044820152606401610986565b604051602001611775906151cc565b604051602081830303815290604052805190602001206117948161170b565b61179e8385612d60565b6117df5760405162461bcd60e51b81526020600482015260126024820152712737ba3434b7339030bb30b4b630b136329760711b6044820152606401610986565b6117ea848484613d5a565b50505050565b6040516020016117ff906152e1565b6040516020818303038152906040528051906020012061181e8161170b565b50601080546001600160a01b039092166001600160a01b0319928316811790915560138054909216179055565b60405160200161185a906152e1565b604051602081830303815290604052805190602001206118798161170b565b506000828152600c6020908152604080832081518083019092529481529215158382019081528454600180820187559584529190922092516002909102909201918255519101805460ff1916911515919091179055565b6118d86126aa565b6040516020016118e7906152e1565b604051602081830303815290604052805190602001206119068161170b565b61124a61411e565b60405160200161191d906152e1565b6040516020818303038152906040528051906020012061193c8161170b565b6000828152600c60205260409020546119675760405162461bcd60e51b81526004016109869061521b565b6000828152600c6020526040812061197e91614c13565b5050565b600854600160b01b900460ff16156119ac5760405162461bcd60e51b8152600401610986906152f2565b336000908152600b6020526040902054806119d95760405162461bcd60e51b81526004016109869061523c565b60016004546119e891906152a1565b821115611a075760405162461bcd60e51b8152600401610986906152b4565b600060098281548110611a1c57611a1c6151dc565b90600052602060002090600202016001018381548110611a3e57611a3e6151dc565b60009182526020918290206040805161012081018252600990930290910180546001600160a01b0316835260018101549383018490526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff16151560e0830152600801546101008201529150611adf5760405162461bcd60e51b815260040161098690615273565b6000611af8611aed83612a65565b60a084015190612aa1565b6101008301516000908152600c60205260408120805492935091611b1e57611b1e6151dc565b600091825260209091206001600290920201015460ff16611b515760405162461bcd60e51b815260040161098690615370565b60008111611b985760405162461bcd60e51b815260206004820152601460248201527322bc3a32b732103737ba102837b9b9b4b136329760611b6044820152606401610986565b611c7660098481548110611bae57611bae6151dc565b90600052602060002090600202016001018581548110611bd057611bd06151dc565b90600052602060002090600902016001015460098581548110611bf557611bf56151dc565b90600052602060002090600202016001018681548110611c1757611c176151dc565b9060005260206000209060090201600301548360098781548110611c3d57611c3d6151dc565b90600052602060002090600202016001018881548110611c5f57611c5f6151dc565b906000526020600020906009020160060154614178565b611cc25760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820616c6c6f77616e6365206c6566742e0000000000006044820152606401610986565b6000611d6360098581548110611cda57611cda6151dc565b90600052602060002090600202016001018681548110611cfc57611cfc6151dc565b90600052602060002090600902016002015460098681548110611d2157611d216151dc565b90600052602060002090600202016001018781548110611d4357611d436151dc565b9060005260206000209060090201600401546141c190919063ffffffff16565b90504260098581548110611d7957611d796151dc565b90600052602060002090600202016001018681548110611d9b57611d9b6151dc565b6000918252602090912060026009909202010155611db94282612aa1565b60098581548110611dcc57611dcc6151dc565b90600052602060002090600202016001018681548110611dee57611dee6151dc565b9060005260206000209060090201600401819055508160098581548110611e1757611e176151dc565b90600052602060002090600202016001018681548110611e3957611e396151dc565b9060005260206000209060090201600501819055507fd0dbdf5a9c6f6230b05ec9279bf9c69ad874fceb6c427e3a79ad9d08951abe2760098581548110611e8257611e826151dc565b90600052602060002090600202016001018681548110611ea457611ea46151dc565b600091825260209091206009918202015481546001600160a01b03909116919087908110611ed457611ed46151dc565b90600052602060002090600202016001018781548110611ef657611ef66151dc565b90600052602060002090600902016001015460098781548110611f1b57611f1b6151dc565b90600052602060002090600202016001018881548110611f3d57611f3d6151dc565b90600052602060002090600902016002015460098881548110611f6257611f626151dc565b90600052602060002090600202016001018981548110611f8457611f846151dc565b90600052602060002090600902016005015460098981548110611fa957611fa96151dc565b90600052602060002090600202016001018a81548110611fcb57611fcb6151dc565b90600052602060002090600902016004015460098a81548110611ff057611ff06151dc565b90600052602060002090600202016001018b81548110612012576120126151dc565b600091825260209182902060066009909202010154604080516001600160a01b039098168852918701959095528501929092526060840152608083015260a082015260c00160405180910390a15050505050565b604051602001612075906152e1565b604051602081830303815290604052805190602001206120948161170b565b50600255565b6040516020016120a9906152e1565b604051602081830303815290604052805190602001206120c88161170b565b5060088054911515600160b81b0260ff60b81b19909216919091179055565b6040516020016120f6906152e1565b604051602081830303815290604052805190602001206121158161170b565b601560008781526020019081526020016000206040518060a0016040528087815260200186815260200185815260200184815260200187878787604051602001612178949392919093845260208401929092526040830152606082015260800190565b60408051601f1981840301815291815281516020928301209092528354600181810186556000958652948290208451600590920201908155908301519381019390935581015160028301556060810151600383015560800151600490910155505050505050565b6121e7612651565b6121ef6126aa565b6121fd8585853386866141cd565b6122076001600055565b5050505050565b60405160200161221d906152e1565b6040516020818303038152906040528051906020012061223c8161170b565b5060088054911515600160a81b0260ff60a81b19909216919091179055565b60405160200161226a906152e1565b604051602081830303815290604052805190602001206122898161170b565b50600555565b612297612651565b6040516020016122a6906152e1565b604051602081830303815290604052805190602001206122c58161170b565b6040516001600160a01b0383169084156108fc029085906000818181858888f193505050501580156122fb573d6000803e3d6000fd5b505061197e6001600055565b604051602001612316906152e1565b604051602081830303815290604052805190602001206123358161170b565b5060088054911515600160a01b0260ff60a01b19909216919091179055565b604051602001612363906152e1565b604051602081830303815290604052805190602001206123828161170b565b50600e55565b60008060405180602001604052806009600b6000876001600160a01b03166001600160a01b0316815260200190815260200160002054815481106123ce576123ce6151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b8282101561249557600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e08401526008015461010083015290835290920191016123ff565b50505091525051519392505050565b6040516020016124b3906152e1565b604051602081830303815290604052805190602001206124d28161170b565b610c238383614402565b6040516020016124eb906152e1565b6040516020818303038152906040528051906020012061250a8161170b565b6000828152601560205260409020546125525760405162461bcd60e51b815260206004820152600a6024820152694e6f205061636b61676560b01b6044820152606401610986565b600082815260156020526040812061197e91614c34565b604051602001612578906152e1565b604051602081830303815290604052805190602001206125978161170b565b50600655565b6125a5613ca0565b6001600160a01b03811661260a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610986565b61124a81613d00565b61261b61445a565b60405160200161262a906152e1565b604051602081830303815290604052805190602001206126498161170b565b61124a6144a3565b6002600054036126a35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610986565b6002600055565b600d5460ff16156117095760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610986565b6127256040518060a0016040528060008152602001600081526020016000815260200160008152602001600080191681525090565b60008281526015602052604090205461276d5760405162461bcd60e51b815260206004820152600a6024820152694e6f205061636b61676560b01b6044820152606401610986565b60008281526015602052604081208054829061278b5761278b6151dc565b90600052602060002090600502016040518060a001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905080915050919050565b60006127f8600e54836144dc90919063ffffffff16565b61280d606461280787876144dc565b906144e8565b1161281a5750600161281e565b5060005b9392505050565b61282f85886144f4565b61284b5760405162461bcd60e51b8152600401610986906153a7565b6000818152600c60205260409020546128765760405162461bcd60e51b81526004016109869061521b565b6001600160a01b0385166000908152600b60205260408120549085908290036128a5576128a28761467c565b91505b60018690556128b48689612aa1565b60035560098054839081106128cb576128cb6151dc565b9060005260206000209060020201600101604051806101200160405280896001600160a01b031681526020018c81526020018381526020018b8152602001600354815260200186815260200187815260200160001515815260200185815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff02191690831515021790555061010082015181600801555050866001600160a01b03167fc16be9a586414a157dd46b4d023aa9997a025dd1cbbaa67ac0c1b8273a5eaf558b84848d6003548b604051612a5196959493929190958652602086019490945260408501929092526060840152608083015260a082015260c00190565b60405180910390a250505050505050505050565b60008160800151421115612a9957612a936064612807846060015185602001516144dc90919063ffffffff16565b92915050565b506000919050565b600061281e8284615208565b601454604051631591424760e01b81526001600160a01b03848116600483015260248201849052600092839283928392839283929091169063159142479060440160c060405180830381865afa158015612b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2f91906153d4565b949d939c50919a509850965090945092505050565b6000818152600c6020526040902054612b6f5760405162461bcd60e51b81526004016109869061521b565b612b7933876144f4565b612b955760405162461bcd60e51b8152600401610986906153a7565b336000908152600b602052604081205490819003612bb957612bb63361467c565b90505b60098181548110612bcc57612bcc6151dc565b9060005260206000209060020201600101604051806101200160405280336001600160a01b031681526020018a815260200187815260200189815260200188815260200185815260200186815260200160001515815260200184815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff02191690831515021790555061010082015181600801555050336001600160a01b03167f688a9a6d7e6c28841e769ec90973dd6816080c4e9f9d6894c4a86403b0264e548983888b8b8a604051612d4e96959493929190958652602086019490945260408501929092526060840152608083015260a082015260c00190565b60405180910390a25050505050505050565b60006001600454612d7191906152a1565b821115612d905760405162461bcd60e51b8152600401610986906152b4565b60408051602080820183526001600160a01b0386166000908152600b90915291822054600980548392908110612dc857612dc86151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b82821015612e8f57600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e0840152600801546101008301529083529092019101612df9565b50505091525080515190915015801590612eaa575080515183105b1561281a576001915050612a93565b600854600160b01b900460ff1615612ee35760405162461bcd60e51b8152600401610986906152f2565b336000908152600b602052604090205480612f105760405162461bcd60e51b81526004016109869061523c565b6001600454612f1f91906152a1565b821115612f3e5760405162461bcd60e51b8152600401610986906152b4565b600060098281548110612f5357612f536151dc565b90600052602060002090600202016001018381548110612f7557612f756151dc565b600091825260208083206040805161012081018252600990940290910180546001600160a01b031684526001810154848401526002810154848301526003810154606085015260048101546080850152600581015460a0850152600681015460c0850152600781015460ff16151560e08501526008015461010084018190528452600c909152822080549193509190613010576130106151dc565b600091825260209091206001600290920201015460ff166130435760405162461bcd60e51b815260040161098690615370565b60008160200151116130675760405162461bcd60e51b815260040161098690615273565b80608001514210156130ae5760405162461bcd60e51b815260206004820152601060248201526f2737ba1036b0ba3ab932b2103cb2ba1760811b6044820152606401610986565b60006130bc611aed83612a65565b9050600081116131015760405162461bcd60e51b815260206004820152601060248201526f21b630b4b6903737ba103932b0b23c9760811b6044820152606401610986565b60208201516000906131139083612aa1565b90506007548110156131675760405162461bcd60e51b815260206004820152601b60248201527f416d6f756e74206973206c657373207468616e206d696e696d756d00000000006044820152606401610986565b8047116131865760405162461bcd60e51b81526004016109869061541e565b60098481548110613199576131996151dc565b906000526020600020906002020160010185815481106131bb576131bb6151dc565b60009182526020822060099182020180546001600160a01b031916815560018101839055600281018390556003810183905560048101839055600581018390556006810183905560078101805460ff1916905560080191909155805485908110613227576132276151dc565b906000526020600020906002020160010160016009868154811061324d5761324d6151dc565b90600052602060002090600202016001018054905061326c91906152a1565b8154811061327c5761327c6151dc565b90600052602060002090600902016009858154811061329d5761329d6151dc565b906000526020600020906002020160010186815481106132bf576132bf6151dc565b600091825260209091208254600992830290910180546001600160a01b0319166001600160a01b03909216919091178155600180840154908201556002808401549082015560038084015490820155600480840154908201556005808401549082015560068084015490820155600780840154908201805460ff909216151560ff19909216919091179055600892830154920191909155805485908110613368576133686151dc565b90600052602060002090600202016001018054806133885761338861544b565b60008281526020812060096000199093019283020180546001600160a01b031916815560018101829055600281018290556003810182905560048101829055600581018290556006810182905560078101805460ff191690556008018190559155604051339183156108fc02918491818181858888f19350505050158015613414573d6000803e3d6000fd5b506040805182815242602082015233917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc6910160405180910390a25050505050565b6000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f5a06360d65acf95e98445dc834f205063424c636e65418d928cdfabc33a953999190a35050565b600854600160b01b900460ff16156134db5760405162461bcd60e51b8152600401610986906152f2565b336000908152600b6020526040902054806135085760405162461bcd60e51b81526004016109869061523c565b600854600160a81b900460ff166135615760405162461bcd60e51b815260206004820181905260248201527f5061727469616c207769746864726177206973206e6f7420656e61626c65642e6044820152606401610986565b600160045461357091906152a1565b82111561358f5760405162461bcd60e51b8152600401610986906152b4565b6000600982815481106135a4576135a46151dc565b906000526020600020906002020160010183815481106135c6576135c66151dc565b600091825260208083206040805161012081018252600990940290910180546001600160a01b031684526001810154848401526002810154848301526003810154606085015260048101546080850152600581015460a0850152600681015460c0850152600781015460ff16151560e08501526008015461010084018190528452600c909152822080549193509190613661576136616151dc565b600091825260209091206001600290920201015460ff166136945760405162461bcd60e51b815260040161098690615370565b60008160200151116136b85760405162461bcd60e51b815260040161098690615273565b80608001514210156136ff5760405162461bcd60e51b815260206004820152601060248201526f2737ba1036b0ba3ab932b2103cb2ba1760811b6044820152606401610986565b600061370d611aed83612a65565b9050600081116137525760405162461bcd60e51b815260206004820152601060248201526f21b630b4b6903737ba103932b0b23c9760811b6044820152606401610986565b60075481908110156137a65760405162461bcd60e51b815260206004820152601b60248201527f416d6f756e74206973206c657373207468616e206d696e696d756d00000000006044820152606401610986565b8047116137c55760405162461bcd60e51b81526004016109869061541e565b61388c600985815481106137db576137db6151dc565b906000526020600020906002020160010186815481106137fd576137fd6151dc565b90600052602060002090600902016001015460098681548110613822576138226151dc565b90600052602060002090600202016001018781548110613844576138446151dc565b906000526020600020906009020160030154846009888154811061386a5761386a6151dc565b90600052602060002090600202016001018981548110611c5f57611c5f6151dc565b15613c7c576000613912600986815481106138a9576138a96151dc565b906000526020600020906002020160010187815481106138cb576138cb6151dc565b906000526020600020906009020160020154600987815481106138f0576138f06151dc565b90600052602060002090600202016001018881548110611d4357611d436151dc565b90504260098681548110613928576139286151dc565b9060005260206000209060020201600101878154811061394a5761394a6151dc565b60009182526020909120600260099092020101556139684282612aa1565b6009868154811061397b5761397b6151dc565b9060005260206000209060020201600101878154811061399d5761399d6151dc565b9060005260206000209060090201600401819055506000600986815481106139c7576139c76151dc565b906000526020600020906002020160010187815481106139e9576139e96151dc565b60009182526020822060056009909202010191909155604051339184156108fc02918591818181858888f19350505050158015613a2a573d6000803e3d6000fd5b506040805183815242602082015233917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc6910160405180910390a27fd0dbdf5a9c6f6230b05ec9279bf9c69ad874fceb6c427e3a79ad9d08951abe2760098681548110613a9957613a996151dc565b90600052602060002090600202016001018781548110613abb57613abb6151dc565b600091825260209091206009918202015481546001600160a01b03909116919088908110613aeb57613aeb6151dc565b90600052602060002090600202016001018881548110613b0d57613b0d6151dc565b90600052602060002090600902016001015460098881548110613b3257613b326151dc565b90600052602060002090600202016001018981548110613b5457613b546151dc565b90600052602060002090600902016002015460098981548110613b7957613b796151dc565b90600052602060002090600202016001018a81548110613b9b57613b9b6151dc565b90600052602060002090600902016005015460098a81548110613bc057613bc06151dc565b90600052602060002090600202016001018b81548110613be257613be26151dc565b90600052602060002090600902016004015460098b81548110613c0757613c076151dc565b90600052602060002090600202016001018c81548110613c2957613c296151dc565b600091825260209182902060066009909202010154604080516001600160a01b039098168852918701959095528501929092526060840152608083015260a082015260c00160405180910390a150612207565b6020830151613c8b9083612aa1565b905060098481548110613199576131996151dc565b600d546001600160a01b036101009091041633146117095760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610986565b600d80546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166000908152600b60205260408120546009805491929183908110613d8a57613d8a6151dc565b90600052602060002090600202016001018581548110613dac57613dac6151dc565b600091825260208083206040805161012081018252600990940290910180546001600160a01b031684526001810154928401929092526002820154908301526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff16151560e0830152600801546101008201529150613e3a611aed83612a65565b90506000613e55828460200151612aa190919063ffffffff16565b905060098481548110613e6a57613e6a6151dc565b90600052602060002090600202016001018781548110613e8c57613e8c6151dc565b60009182526020822060099182020180546001600160a01b031916815560018101839055600281018390556003810183905560048101839055600581018390556006810183905560078101805460ff1916905560080191909155805485908110613ef857613ef86151dc565b9060005260206000209060020201600101600160098681548110613f1e57613f1e6151dc565b906000526020600020906002020160010180549050613f3d91906152a1565b81548110613f4d57613f4d6151dc565b906000526020600020906009020160098581548110613f6e57613f6e6151dc565b90600052602060002090600202016001018881548110613f9057613f906151dc565b600091825260209091208254600992830290910180546001600160a01b0319166001600160a01b03909216919091178155600180840154908201556002808401549082015560038084015490820155600480840154908201556005808401549082015560068084015490820155600780840154908201805460ff909216151560ff19909216919091179055600892830154920191909155805485908110614039576140396151dc565b90600052602060002090600202016001018054806140595761405961544b565b60008281526020812060096000199093019283020180546001600160a01b031916815560018101829055600281018290556003810182905560048101829055600581018290556006810182905560078101805460ff1916905560080155905584156109f957804710156140de5760405162461bcd60e51b81526004016109869061541e565b6040516001600160a01b0387169082156108fc029083906000818181858888f19350505050158015614114573d6000803e3d6000fd5b5050505050505050565b6141266126aa565b600d805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861415b3390565b6040516001600160a01b03909116815260200160405180910390a1565b600061418f600254836144dc90919063ffffffff16565b6141a8846141a260646128078a8a6144dc565b90612aa1565b116141b5575060016141b9565b5060005b949350505050565b600061281e82846152a1565b60006141d8866126f0565b6020810151815160408301516060840151608085015194955092939192909187146142455760405162461bcd60e51b815260206004820152601a60248201527f5061636b616765206973206e6f7420617574686f72697a65642e0000000000006044820152606401610986565b818b101580156142555750808b11155b6142a15760405162461bcd60e51b815260206004820152601860248201527f5374616b652076616c7565206e6f7420696e2072616e676500000000000000006044820152606401610986565b8a34146142e75760405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21030b6b7bab73a1039b2b73a1760611b6044820152606401610986565b6142f189896146f2565b15156001146143425760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420616c6c204b657973206f776e656420627920616464726573732e00006044820152606401610986565b600161434c614817565b10156143915760405162461bcd60e51b815260206004820152601460248201527320b2323932b9b9903430bb329037379025b2bc9760611b6044820152606401610986565b61439d8b858b516127e1565b6143dc5760405162461bcd60e51b815260206004820152601060248201526f2737ba1032b737bab3b41025b2bcb99760811b6044820152606401610986565b6143e68989611548565b6143f58b85858b8d518b6148db565b5050505050505050505050565b6000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916905551909184917f76e6093c136cd7faa5a6d92b2b633f3b4595abd4a529b7a13917398355fea6949190a35050565b600d5460ff166117095760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610986565b6144ab61445a565b600d805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3361415b565b600061281e8284615461565b600061281e8284615478565b60008060405180602001604052806009600b6000886001600160a01b03166001600160a01b03168152602001908152602001600020548154811061453a5761453a6151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b8282101561460157600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e084015260080154610100830152908352909201910161456b565b5050509152506004548151519192501161461f576000915050612a93565b60005b815151811015614671578382600001518281518110614643576146436151dc565b6020026020010151606001510361465f57600092505050612a93565b61466a600182615208565b9050614622565b506001949350505050565b60098054600190810180835560009283528291614698916152a1565b905082600982815481106146ae576146ae6151dc565b6000918252602080832060029290920290910180546001600160a01b0319166001600160a01b03948516179055949091168152600b90935260409092208290555090565b600f546000906001600160a01b03166147455760405162461bcd60e51b815260206004820152601560248201527425b2bc9021b7b73a3930b1ba103737ba1039b2ba1760591b6044820152606401610986565b60005b835181101561480d5760125484516001600160a01b03808616921690636352211e9087908590811061477c5761477c6151dc565b60200260200101516040518263ffffffff1660e01b81526004016147a291815260200190565b602060405180830381865afa1580156147bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147e3919061549a565b6001600160a01b0316146147fb576000915050612a93565b80614805816154b7565b915050614748565b5060019392505050565b600f546000906001600160a01b031661486a5760405162461bcd60e51b815260206004820152601560248201527425b2bc9021b7b73a3930b1ba103737ba1039b2ba1760591b6044820152606401610986565b6012546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156148b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148d691906154d0565b905090565b6000818152600c60205260409020546149065760405162461bcd60e51b81526004016109869061521b565b6008546001600160a01b031661495e5760405162461bcd60e51b815260206004820152601860248201527f5374616b696e67206163636f756e74206e6f74207365742e00000000000000006044820152606401610986565b61496883866144f4565b6149845760405162461bcd60e51b8152600401610986906153a7565b600854600160a01b900460ff16156149d2576008546040516001600160a01b039091169087156108fc029088906000818181858888f193505050501580156149d0573d6000803e3d6000fd5b505b600854600160b81b900460ff1615614a36576008546006546001600160a01b03909116906108fc90614a0c90606490612807908b906144dc565b6040518115909202916000818181858888f19350505050158015614a34573d6000803e3d6000fd5b505b6001600160a01b0383166000908152600b6020526040812054904290829003614a6557614a628561467c565b91505b426001819055614a759087612aa1565b6003556009805483908110614a8c57614a8c6151dc565b9060005260206000209060020201600101604051806101200160405280876001600160a01b031681526020018a815260200183815260200189815260200160035481526020016000815260200186815260200160001515815260200185815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff02191690831515021790555061010082015181600801555050846001600160a01b03167fc16be9a586414a157dd46b4d023aa9997a025dd1cbbaa67ac0c1b8273a5eaf558984848b6003548a604051612d4e96959493929190958652602086019490945260408501929092526060840152608083015260a082015260c00190565b508054600082556002029060005260206000209081019061124a9190614c55565b508054600082556005029060005260206000209081019061124a9190614c7a565b5b80821115614c76576000815560018101805460ff19169055600201614c56565b5090565b5b80821115614c765760008082556001820181905560028201819055600382018190556004820155600501614c7b565b6001600160a01b038116811461124a57600080fd5b600080600080600080600060e0888a031215614cda57600080fd5b8735965060208801359550604088013594506060880135614cfa81614caa565b9699959850939660808101359560a0820135955060c0909101359350915050565b600060208284031215614d2d57600080fd5b813561281e81614caa565b60006020808352604080840185518384870152818151808452606093508388019150858301925060005b81811015614dd957835180516001600160a01b031684528781015188850152868101518785015285810151868501526080808201519085015260a0808201519085015260c0808201519085015260e08082015115159085015261010090810151908401529286019261012090920191600101614d62565b509098975050505050505050565b600080600060608486031215614dfc57600080fd5b505081359360208301359350604090920135919050565b600060208284031215614e2557600080fd5b5035919050565b80358015158114614e3c57600080fd5b919050565b600080600060608486031215614e5657600080fd5b8335614e6181614caa565b9250614e6f60208501614e2c565b9150604084013590509250925092565b600080600080600060808688031215614e9757600080fd5b8535614ea281614caa565b94506020860135614eb281614caa565b935060408601359250606086013567ffffffffffffffff80821115614ed657600080fd5b818801915088601f830112614eea57600080fd5b813581811115614ef957600080fd5b896020828501011115614f0b57600080fd5b9699959850939650602001949392505050565b60008060408385031215614f3157600080fd5b8235614f3c81614caa565b946020939093013593505050565b600080600060608486031215614f5f57600080fd5b833592506020840135614f7181614caa565b929592945050506040919091013590565b60008060408385031215614f9557600080fd5b823591506020830135614fa781614caa565b809150509250929050565b600060208284031215614fc457600080fd5b61281e82614e2c565b634e487b7160e01b600052604160045260246000fd5b600082601f830112614ff457600080fd5b8135602067ffffffffffffffff8083111561501157615011614fcd565b8260051b604051601f19603f8301168101818110848211171561503657615036614fcd565b60405293845285810183019383810192508785111561505457600080fd5b83870191505b848210156150735781358352918301919083019061505a565b979650505050505050565b6000806040838503121561509157600080fd5b823567ffffffffffffffff8111156150a857600080fd5b6150b485828601614fe3565b9250506020830135614fa781614caa565b600080604083850312156150d857600080fd5b823591506150e860208401614e2c565b90509250929050565b60008060006060848603121561510657600080fd5b83359250602084013561511881614caa565b915061512660408501614e2c565b90509250925092565b600080600080600060a0868803121561514757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600080600060a0868803121561518257600080fd5b8535945060208601359350604086013567ffffffffffffffff8111156151a757600080fd5b6151b388828901614fe3565b9598949750949560608101359550608001359392505050565b634558454360e01b815260040190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115612a9357612a936151f2565b602080825260079082015266139bc8141bdbdb60ca1b604082015260600190565b60208082526017908201527f41646472657373206e6f7420726567697374657265642e000000000000000000604082015260600190565b60208082526014908201527327379030b1ba34bb32903837b9b4ba34b7b7399760611b604082015260600190565b81810381811115612a9357612a936151f2565b60208082526013908201527224b73232bc1037baba1037b3103930b733b29760691b604082015260600190565b6420a226a4a760d91b815260050190565b60208082526010908201526f21b7b73a3930b1ba102637b1b5b2b21760811b604082015260600190565b604080825283519082018190526000906020906060840190828701845b8281101561535557815184529284019290840190600101615339565b5050506001600160a01b039490941692019190915250919050565b60208082526018908201527f506f6f6c2054656d706f726172792053757370656e6465640000000000000000604082015260600190565b60208082526013908201527226b0bc1037b832b7103837b9b4ba34b7b7399760691b604082015260600190565b60008060008060008060c087890312156153ed57600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b6020808252601390820152722737ba1032b737bab3b4103130b630b731b29760691b604082015260600190565b634e487b7160e01b600052603160045260246000fd5b8082028115828204841417612a9357612a936151f2565b60008261549557634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156154ac57600080fd5b815161281e81614caa565b6000600182016154c9576154c96151f2565b5060010190565b6000602082840312156154e257600080fd5b505191905056fea2646970667358221220b7928ffcc33c8bd3073b21fc8d9edcc09fda6f1f3e43ef4c5f9391bec4ded02564736f6c634300081100330000000000000000000000005c76eb054b1b06a725be1715fbed9560ce5dba13

Deployed Bytecode

0x6080604052600436106102805760003560e01c8063744a80681161014f578063a4ca8c7a116100c1578063d547741f1161007a578063d547741f14610807578063d71c100814610827578063ec5a82e414610847578063f2fde38b14610867578063f7b188a514610887578063f8fc08b91461089c57600080fd5b8063a4ca8c7a14610747578063a865e8ce14610767578063a93e052314610787578063b06113fe146107a7578063bb32fbb1146107c7578063d0c4cab6146107e757600080fd5b80638da5cb5b116101135780638da5cb5b1461067e5780638e699bc8146106b457806399b1d958146106d457806399d9af52146106f4578063a2e30f1514610714578063a48963611461073457600080fd5b8063744a8068146105e957806381cdf7661461060957806382d0fd4a146106295780638456cb59146106495780638c4477231461065e57600080fd5b80632edbb1f9116101f35780635c975abb116101ac5780635c975abb14610530578063654a3c7c1461055457806368888dc3146105745780636c12eb1c14610594578063715018a6146105b457806371dad42f146105c957600080fd5b80632edbb1f9146104705780632f2ff15d1461049057806335aa134a146104b05780633b289665146104d05780634a493cb6146104f057806350690fc01461051057600080fd5b806312065fe01161024557806312065fe014610361578063150b7a021461037e57806315914247146103c35780631c8050c7146104105780632514f5301461043057806325d5971f1461045057600080fd5b8062b7e5261461028c57806304238994146102ae57806305a2308b146102e457806309e933961461030457806311a859f11461034157600080fd5b3661028757005b600080fd5b34801561029857600080fd5b506102ac6102a7366004614cbf565b6108d7565b005b3480156102ba57600080fd5b506102ce6102c9366004614d1b565b610a02565b6040516102db9190614d38565b60405180910390f35b3480156102f057600080fd5b506102ac6102ff366004614de7565b610bc0565b34801561031057600080fd5b5061032461031f366004614e13565b610c28565b6040805182518152602092830151151592810192909252016102db565b34801561034d57600080fd5b506102ac61035c366004614e41565b610cbb565b34801561036d57600080fd5b50475b6040519081526020016102db565b34801561038a57600080fd5b506103aa610399366004614e7f565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016102db565b3480156103cf57600080fd5b506103e36103de366004614f1e565b610e57565b604080519687526020870195909552938501929092526060840152608083015260a082015260c0016102db565b34801561041c57600080fd5b506102ac61042b366004614d1b565b611155565b34801561043c57600080fd5b506102ac61044b366004614d1b565b6111a6565b34801561045c57600080fd5b506102ac61046b366004614e13565b611201565b34801561047c57600080fd5b506102ac61048b366004614f4a565b61124d565b34801561049c57600080fd5b506102ac6104ab366004614f82565b611434565b3480156104bc57600080fd5b506102ac6104cb366004614e13565b61146c565b3480156104dc57600080fd5b506102ac6104eb366004614d1b565b6114a0565b3480156104fc57600080fd5b506102ac61050b366004614fb2565b6114fb565b34801561051c57600080fd5b506102ac61052b36600461507e565b611548565b34801561053c57600080fd5b50600d5460ff165b60405190151581526020016102db565b34801561056057600080fd5b506102ac61056f366004614e13565b611610565b34801561058057600080fd5b506102ac61058f366004614e13565b61164f565b3480156105a057600080fd5b506102ac6105af3660046150c5565b611683565b3480156105c057600080fd5b506102ac6116f7565b3480156105d557600080fd5b506102ac6105e4366004614e13565b61170b565b3480156105f557600080fd5b506102ac6106043660046150f1565b611766565b34801561061557600080fd5b506102ac610624366004614d1b565b6117f0565b34801561063557600080fd5b506102ac6106443660046150c5565b61184b565b34801561065557600080fd5b506102ac6118d0565b34801561066a57600080fd5b506102ac610679366004614e13565b61190e565b34801561068a57600080fd5b50600d5461010090046001600160a01b03166040516001600160a01b0390911681526020016102db565b3480156106c057600080fd5b506102ac6106cf366004614e13565b611982565b3480156106e057600080fd5b506102ac6106ef366004614e13565b612066565b34801561070057600080fd5b506102ac61070f366004614fb2565b61209a565b34801561072057600080fd5b506102ac61072f36600461512f565b6120e7565b6102ac61074236600461516a565b6121df565b34801561075357600080fd5b506102ac610762366004614fb2565b61220e565b34801561077357600080fd5b506102ac610782366004614e13565b61225b565b34801561079357600080fd5b506102ac6107a2366004614f82565b61228f565b3480156107b357600080fd5b506102ac6107c2366004614fb2565b612307565b3480156107d357600080fd5b506102ac6107e2366004614e13565b612354565b3480156107f357600080fd5b50610370610802366004614d1b565b612388565b34801561081357600080fd5b506102ac610822366004614f82565b6124a4565b34801561083357600080fd5b506102ac610842366004614e13565b6124dc565b34801561085357600080fd5b506102ac610862366004614e13565b612569565b34801561087357600080fd5b506102ac610882366004614d1b565b61259d565b34801561089357600080fd5b506102ac612613565b3480156108a857600080fd5b506105446108b7366004614f82565b600a60209081526000928352604080842090915290825290205460ff1681565b6108df612651565b6040516020016108ee906151cc565b6040516020818303038152906040528051906020012061090d8161170b565b6109156126aa565b6000610920886126f0565b60208101518151604083015160608401519394509192909190818d108015906109495750808d11155b61098f5760405162461bcd60e51b815260206004820152601260248201527156616c7565206e6f7420696e2072616e676560701b60448201526064015b60405180910390fd5b61099a8d858b6127e1565b6109d95760405162461bcd60e51b815260206004820152601060248201526f2737ba1032b737bab3b41025b2bcb99760811b6044820152606401610986565b6109e98d85858d8f8e8e8e612825565b5050505050506109f96001600055565b50505050505050565b60408051602081019091526060815260408051602080820183526001600160a01b0385166000908152600b90915291822054600980548392908110610a4957610a496151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b82821015610b1057600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e0840152600801546101008301529083529092019101610a7a565b505050915250905060005b815151811015610bb9576000610b4d83600001518381518110610b4057610b406151dc565b6020026020010151612a65565b9050610b838184600001518481518110610b6957610b696151dc565b602002602001015160a00151612aa190919063ffffffff16565b8351805184908110610b9757610b976151dc565b602090810291909101015160a0015250610bb2600182615208565b9050610b1b565b5092915050565b610bc8612651565b610bd06126aa565b600080600080600080610be33388612aad565b955095509550955095509550610c028884612aa190919063ffffffff16565b9250610c138685858885878f612b44565b505050505050610c236001600055565b505050565b60408051808201909152600080825260208201526000828152600c6020526040902054610c675760405162461bcd60e51b81526004016109869061521b565b6000828152600c6020526040812080548290610c8557610c856151dc565b600091825260209182902060408051808201909152600290920201805482526001015460ff161515918101919091529392505050565b604051602001610cca906151cc565b60405160208183030381529060405280519060200120610ce98161170b565b6001600160a01b0384166000908152600b602052604090205480610d1f5760405162461bcd60e51b81526004016109869061523c565b600060098281548110610d3457610d346151dc565b90600052602060002090600202016001018481548110610d5657610d566151dc565b60009182526020918290206040805161012081018252600990930290910180546001600160a01b0316835260018101549383018490526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff16151560e0830152600801546101008201529150610df75760405162461bcd60e51b815260040161098690615273565b8460098381548110610e0b57610e0b6151dc565b90600052602060002090600202016001018581548110610e2d57610e2d6151dc565b60009182526020909120600990910201600701805460ff1916911515919091179055505050505050565b6000806000806000806001600454610e6f91906152a1565b871115610e8e5760405162461bcd60e51b8152600401610986906152b4565b60408051602080820183526001600160a01b038b166000908152600b90915291822054600980548392908110610ec657610ec66151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b82821015610f8d57600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e0840152600801546101008301529083529092019101610ef7565b505050915250805151909150610fb55760405162461bcd60e51b815260040161098690615273565b8051518810610ff95760405162461bcd60e51b815260206004820152601060248201526f24b73232bc103737ba103b30b634b21760811b6044820152606401610986565b60005b81515181101561107357600061102183600001518381518110610b4057610b406151dc565b905061103d8184600001518481518110610b6957610b696151dc565b8351805184908110611051576110516151dc565b602090810291909101015160a001525061106c600182615208565b9050610ffc565b508051805189908110611088576110886151dc565b602002602001015160200151816000015189815181106110aa576110aa6151dc565b60200260200101516040015182600001518a815181106110cc576110cc6151dc565b60200260200101516060015183600001518b815181106110ee576110ee6151dc565b60200260200101516080015184600001518c81518110611110576111106151dc565b602002602001015160a0015185600001518d81518110611132576111326151dc565b602002602001015160c00151965096509650965096509650509295509295509295565b604051602001611164906152e1565b604051602081830303815290604052805190602001206111838161170b565b50600880546001600160a01b0319166001600160a01b0392909216919091179055565b6040516020016111b5906152e1565b604051602081830303815290604052805190602001206111d48161170b565b50601180546001600160a01b039092166001600160a01b0319928316811790915560148054909216179055565b611209612651565b6112116126aa565b61121b3382612d60565b6112375760405162461bcd60e51b815260040161098690615273565b61124081612eb9565b61124a6001600055565b50565b60405160200161125c906151cc565b6040516020818303038152906040528051906020012061127b8161170b565b600854600160b01b900460ff16156112a55760405162461bcd60e51b8152600401610986906152f2565b6001600160a01b0383166000908152600b6020526040902054806112db5760405162461bcd60e51b81526004016109869061523c565b60016004546112ea91906152a1565b8511156113095760405162461bcd60e51b8152600401610986906152b4565b60006009828154811061131e5761131e6151dc565b90600052602060002090600202016001018681548110611340576113406151dc565b60009182526020918290206040805161012081018252600990930290910180546001600160a01b0316835260018101549383018490526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff16151560e08301526008015461010082015291506113e15760405162461bcd60e51b815260040161098690615273565b83600983815481106113f5576113f56151dc565b90600052602060002090600202016001018781548110611417576114176151dc565b906000526020600020906009020160040181905550505050505050565b604051602001611443906152e1565b604051602081830303815290604052805190602001206114628161170b565b610c238383613456565b60405160200161147b906152e1565b6040516020818303038152906040528051906020012061149a8161170b565b50600755565b6040516020016114af906152e1565b604051602081830303815290604052805190602001206114ce8161170b565b50600f80546001600160a01b039092166001600160a01b0319928316811790915560128054909216179055565b60405160200161150a906151cc565b604051602081830303815290604052805190602001206115298161170b565b5060088054911515600160b01b0260ff60b01b19909216919091179055565b6115506126aa565b6010546001600160a01b03166115a85760405162461bcd60e51b815260206004820152601760248201527f44656c656761746564204275726e206e6f74207365742e0000000000000000006044820152606401610986565b601354604051630141a43f60e61b81526001600160a01b03909116906350690fc0906115da908590859060040161531c565b600060405180830381600087803b1580156115f457600080fd5b505af1158015611608573d6000803e3d6000fd5b505050505050565b611618612651565b6116206126aa565b61162a3382612d60565b6116465760405162461bcd60e51b815260040161098690615273565b611240816134b1565b60405160200161165e906152e1565b6040516020818303038152906040528051906020012061167d8161170b565b50600455565b604051602001611692906151cc565b604051602081830303815290604052805190602001206116b18161170b565b6000838152600c6020526040812080548492906116d0576116d06151dc565b60009182526020909120600290910201600101805460ff1916911515919091179055505050565b6116ff613ca0565b6117096000613d00565b565b6000818152600a6020908152604080832033845290915290205460ff1661124a5760405162461bcd60e51b815260206004820152600f60248201526e2737ba1030baba3437b934bd32b21760891b6044820152606401610986565b604051602001611775906151cc565b604051602081830303815290604052805190602001206117948161170b565b61179e8385612d60565b6117df5760405162461bcd60e51b81526020600482015260126024820152712737ba3434b7339030bb30b4b630b136329760711b6044820152606401610986565b6117ea848484613d5a565b50505050565b6040516020016117ff906152e1565b6040516020818303038152906040528051906020012061181e8161170b565b50601080546001600160a01b039092166001600160a01b0319928316811790915560138054909216179055565b60405160200161185a906152e1565b604051602081830303815290604052805190602001206118798161170b565b506000828152600c6020908152604080832081518083019092529481529215158382019081528454600180820187559584529190922092516002909102909201918255519101805460ff1916911515919091179055565b6118d86126aa565b6040516020016118e7906152e1565b604051602081830303815290604052805190602001206119068161170b565b61124a61411e565b60405160200161191d906152e1565b6040516020818303038152906040528051906020012061193c8161170b565b6000828152600c60205260409020546119675760405162461bcd60e51b81526004016109869061521b565b6000828152600c6020526040812061197e91614c13565b5050565b600854600160b01b900460ff16156119ac5760405162461bcd60e51b8152600401610986906152f2565b336000908152600b6020526040902054806119d95760405162461bcd60e51b81526004016109869061523c565b60016004546119e891906152a1565b821115611a075760405162461bcd60e51b8152600401610986906152b4565b600060098281548110611a1c57611a1c6151dc565b90600052602060002090600202016001018381548110611a3e57611a3e6151dc565b60009182526020918290206040805161012081018252600990930290910180546001600160a01b0316835260018101549383018490526002810154918301919091526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff16151560e0830152600801546101008201529150611adf5760405162461bcd60e51b815260040161098690615273565b6000611af8611aed83612a65565b60a084015190612aa1565b6101008301516000908152600c60205260408120805492935091611b1e57611b1e6151dc565b600091825260209091206001600290920201015460ff16611b515760405162461bcd60e51b815260040161098690615370565b60008111611b985760405162461bcd60e51b815260206004820152601460248201527322bc3a32b732103737ba102837b9b9b4b136329760611b6044820152606401610986565b611c7660098481548110611bae57611bae6151dc565b90600052602060002090600202016001018581548110611bd057611bd06151dc565b90600052602060002090600902016001015460098581548110611bf557611bf56151dc565b90600052602060002090600202016001018681548110611c1757611c176151dc565b9060005260206000209060090201600301548360098781548110611c3d57611c3d6151dc565b90600052602060002090600202016001018881548110611c5f57611c5f6151dc565b906000526020600020906009020160060154614178565b611cc25760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820616c6c6f77616e6365206c6566742e0000000000006044820152606401610986565b6000611d6360098581548110611cda57611cda6151dc565b90600052602060002090600202016001018681548110611cfc57611cfc6151dc565b90600052602060002090600902016002015460098681548110611d2157611d216151dc565b90600052602060002090600202016001018781548110611d4357611d436151dc565b9060005260206000209060090201600401546141c190919063ffffffff16565b90504260098581548110611d7957611d796151dc565b90600052602060002090600202016001018681548110611d9b57611d9b6151dc565b6000918252602090912060026009909202010155611db94282612aa1565b60098581548110611dcc57611dcc6151dc565b90600052602060002090600202016001018681548110611dee57611dee6151dc565b9060005260206000209060090201600401819055508160098581548110611e1757611e176151dc565b90600052602060002090600202016001018681548110611e3957611e396151dc565b9060005260206000209060090201600501819055507fd0dbdf5a9c6f6230b05ec9279bf9c69ad874fceb6c427e3a79ad9d08951abe2760098581548110611e8257611e826151dc565b90600052602060002090600202016001018681548110611ea457611ea46151dc565b600091825260209091206009918202015481546001600160a01b03909116919087908110611ed457611ed46151dc565b90600052602060002090600202016001018781548110611ef657611ef66151dc565b90600052602060002090600902016001015460098781548110611f1b57611f1b6151dc565b90600052602060002090600202016001018881548110611f3d57611f3d6151dc565b90600052602060002090600902016002015460098881548110611f6257611f626151dc565b90600052602060002090600202016001018981548110611f8457611f846151dc565b90600052602060002090600902016005015460098981548110611fa957611fa96151dc565b90600052602060002090600202016001018a81548110611fcb57611fcb6151dc565b90600052602060002090600902016004015460098a81548110611ff057611ff06151dc565b90600052602060002090600202016001018b81548110612012576120126151dc565b600091825260209182902060066009909202010154604080516001600160a01b039098168852918701959095528501929092526060840152608083015260a082015260c00160405180910390a15050505050565b604051602001612075906152e1565b604051602081830303815290604052805190602001206120948161170b565b50600255565b6040516020016120a9906152e1565b604051602081830303815290604052805190602001206120c88161170b565b5060088054911515600160b81b0260ff60b81b19909216919091179055565b6040516020016120f6906152e1565b604051602081830303815290604052805190602001206121158161170b565b601560008781526020019081526020016000206040518060a0016040528087815260200186815260200185815260200184815260200187878787604051602001612178949392919093845260208401929092526040830152606082015260800190565b60408051601f1981840301815291815281516020928301209092528354600181810186556000958652948290208451600590920201908155908301519381019390935581015160028301556060810151600383015560800151600490910155505050505050565b6121e7612651565b6121ef6126aa565b6121fd8585853386866141cd565b6122076001600055565b5050505050565b60405160200161221d906152e1565b6040516020818303038152906040528051906020012061223c8161170b565b5060088054911515600160a81b0260ff60a81b19909216919091179055565b60405160200161226a906152e1565b604051602081830303815290604052805190602001206122898161170b565b50600555565b612297612651565b6040516020016122a6906152e1565b604051602081830303815290604052805190602001206122c58161170b565b6040516001600160a01b0383169084156108fc029085906000818181858888f193505050501580156122fb573d6000803e3d6000fd5b505061197e6001600055565b604051602001612316906152e1565b604051602081830303815290604052805190602001206123358161170b565b5060088054911515600160a01b0260ff60a01b19909216919091179055565b604051602001612363906152e1565b604051602081830303815290604052805190602001206123828161170b565b50600e55565b60008060405180602001604052806009600b6000876001600160a01b03166001600160a01b0316815260200190815260200160002054815481106123ce576123ce6151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b8282101561249557600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e08401526008015461010083015290835290920191016123ff565b50505091525051519392505050565b6040516020016124b3906152e1565b604051602081830303815290604052805190602001206124d28161170b565b610c238383614402565b6040516020016124eb906152e1565b6040516020818303038152906040528051906020012061250a8161170b565b6000828152601560205260409020546125525760405162461bcd60e51b815260206004820152600a6024820152694e6f205061636b61676560b01b6044820152606401610986565b600082815260156020526040812061197e91614c34565b604051602001612578906152e1565b604051602081830303815290604052805190602001206125978161170b565b50600655565b6125a5613ca0565b6001600160a01b03811661260a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610986565b61124a81613d00565b61261b61445a565b60405160200161262a906152e1565b604051602081830303815290604052805190602001206126498161170b565b61124a6144a3565b6002600054036126a35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610986565b6002600055565b600d5460ff16156117095760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610986565b6127256040518060a0016040528060008152602001600081526020016000815260200160008152602001600080191681525090565b60008281526015602052604090205461276d5760405162461bcd60e51b815260206004820152600a6024820152694e6f205061636b61676560b01b6044820152606401610986565b60008281526015602052604081208054829061278b5761278b6151dc565b90600052602060002090600502016040518060a001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481525050905080915050919050565b60006127f8600e54836144dc90919063ffffffff16565b61280d606461280787876144dc565b906144e8565b1161281a5750600161281e565b5060005b9392505050565b61282f85886144f4565b61284b5760405162461bcd60e51b8152600401610986906153a7565b6000818152600c60205260409020546128765760405162461bcd60e51b81526004016109869061521b565b6001600160a01b0385166000908152600b60205260408120549085908290036128a5576128a28761467c565b91505b60018690556128b48689612aa1565b60035560098054839081106128cb576128cb6151dc565b9060005260206000209060020201600101604051806101200160405280896001600160a01b031681526020018c81526020018381526020018b8152602001600354815260200186815260200187815260200160001515815260200185815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff02191690831515021790555061010082015181600801555050866001600160a01b03167fc16be9a586414a157dd46b4d023aa9997a025dd1cbbaa67ac0c1b8273a5eaf558b84848d6003548b604051612a5196959493929190958652602086019490945260408501929092526060840152608083015260a082015260c00190565b60405180910390a250505050505050505050565b60008160800151421115612a9957612a936064612807846060015185602001516144dc90919063ffffffff16565b92915050565b506000919050565b600061281e8284615208565b601454604051631591424760e01b81526001600160a01b03848116600483015260248201849052600092839283928392839283929091169063159142479060440160c060405180830381865afa158015612b0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2f91906153d4565b949d939c50919a509850965090945092505050565b6000818152600c6020526040902054612b6f5760405162461bcd60e51b81526004016109869061521b565b612b7933876144f4565b612b955760405162461bcd60e51b8152600401610986906153a7565b336000908152600b602052604081205490819003612bb957612bb63361467c565b90505b60098181548110612bcc57612bcc6151dc565b9060005260206000209060020201600101604051806101200160405280336001600160a01b031681526020018a815260200187815260200189815260200188815260200185815260200186815260200160001515815260200184815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff02191690831515021790555061010082015181600801555050336001600160a01b03167f688a9a6d7e6c28841e769ec90973dd6816080c4e9f9d6894c4a86403b0264e548983888b8b8a604051612d4e96959493929190958652602086019490945260408501929092526060840152608083015260a082015260c00190565b60405180910390a25050505050505050565b60006001600454612d7191906152a1565b821115612d905760405162461bcd60e51b8152600401610986906152b4565b60408051602080820183526001600160a01b0386166000908152600b90915291822054600980548392908110612dc857612dc86151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b82821015612e8f57600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e0840152600801546101008301529083529092019101612df9565b50505091525080515190915015801590612eaa575080515183105b1561281a576001915050612a93565b600854600160b01b900460ff1615612ee35760405162461bcd60e51b8152600401610986906152f2565b336000908152600b602052604090205480612f105760405162461bcd60e51b81526004016109869061523c565b6001600454612f1f91906152a1565b821115612f3e5760405162461bcd60e51b8152600401610986906152b4565b600060098281548110612f5357612f536151dc565b90600052602060002090600202016001018381548110612f7557612f756151dc565b600091825260208083206040805161012081018252600990940290910180546001600160a01b031684526001810154848401526002810154848301526003810154606085015260048101546080850152600581015460a0850152600681015460c0850152600781015460ff16151560e08501526008015461010084018190528452600c909152822080549193509190613010576130106151dc565b600091825260209091206001600290920201015460ff166130435760405162461bcd60e51b815260040161098690615370565b60008160200151116130675760405162461bcd60e51b815260040161098690615273565b80608001514210156130ae5760405162461bcd60e51b815260206004820152601060248201526f2737ba1036b0ba3ab932b2103cb2ba1760811b6044820152606401610986565b60006130bc611aed83612a65565b9050600081116131015760405162461bcd60e51b815260206004820152601060248201526f21b630b4b6903737ba103932b0b23c9760811b6044820152606401610986565b60208201516000906131139083612aa1565b90506007548110156131675760405162461bcd60e51b815260206004820152601b60248201527f416d6f756e74206973206c657373207468616e206d696e696d756d00000000006044820152606401610986565b8047116131865760405162461bcd60e51b81526004016109869061541e565b60098481548110613199576131996151dc565b906000526020600020906002020160010185815481106131bb576131bb6151dc565b60009182526020822060099182020180546001600160a01b031916815560018101839055600281018390556003810183905560048101839055600581018390556006810183905560078101805460ff1916905560080191909155805485908110613227576132276151dc565b906000526020600020906002020160010160016009868154811061324d5761324d6151dc565b90600052602060002090600202016001018054905061326c91906152a1565b8154811061327c5761327c6151dc565b90600052602060002090600902016009858154811061329d5761329d6151dc565b906000526020600020906002020160010186815481106132bf576132bf6151dc565b600091825260209091208254600992830290910180546001600160a01b0319166001600160a01b03909216919091178155600180840154908201556002808401549082015560038084015490820155600480840154908201556005808401549082015560068084015490820155600780840154908201805460ff909216151560ff19909216919091179055600892830154920191909155805485908110613368576133686151dc565b90600052602060002090600202016001018054806133885761338861544b565b60008281526020812060096000199093019283020180546001600160a01b031916815560018101829055600281018290556003810182905560048101829055600581018290556006810182905560078101805460ff191690556008018190559155604051339183156108fc02918491818181858888f19350505050158015613414573d6000803e3d6000fd5b506040805182815242602082015233917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc6910160405180910390a25050505050565b6000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f5a06360d65acf95e98445dc834f205063424c636e65418d928cdfabc33a953999190a35050565b600854600160b01b900460ff16156134db5760405162461bcd60e51b8152600401610986906152f2565b336000908152600b6020526040902054806135085760405162461bcd60e51b81526004016109869061523c565b600854600160a81b900460ff166135615760405162461bcd60e51b815260206004820181905260248201527f5061727469616c207769746864726177206973206e6f7420656e61626c65642e6044820152606401610986565b600160045461357091906152a1565b82111561358f5760405162461bcd60e51b8152600401610986906152b4565b6000600982815481106135a4576135a46151dc565b906000526020600020906002020160010183815481106135c6576135c66151dc565b600091825260208083206040805161012081018252600990940290910180546001600160a01b031684526001810154848401526002810154848301526003810154606085015260048101546080850152600581015460a0850152600681015460c0850152600781015460ff16151560e08501526008015461010084018190528452600c909152822080549193509190613661576136616151dc565b600091825260209091206001600290920201015460ff166136945760405162461bcd60e51b815260040161098690615370565b60008160200151116136b85760405162461bcd60e51b815260040161098690615273565b80608001514210156136ff5760405162461bcd60e51b815260206004820152601060248201526f2737ba1036b0ba3ab932b2103cb2ba1760811b6044820152606401610986565b600061370d611aed83612a65565b9050600081116137525760405162461bcd60e51b815260206004820152601060248201526f21b630b4b6903737ba103932b0b23c9760811b6044820152606401610986565b60075481908110156137a65760405162461bcd60e51b815260206004820152601b60248201527f416d6f756e74206973206c657373207468616e206d696e696d756d00000000006044820152606401610986565b8047116137c55760405162461bcd60e51b81526004016109869061541e565b61388c600985815481106137db576137db6151dc565b906000526020600020906002020160010186815481106137fd576137fd6151dc565b90600052602060002090600902016001015460098681548110613822576138226151dc565b90600052602060002090600202016001018781548110613844576138446151dc565b906000526020600020906009020160030154846009888154811061386a5761386a6151dc565b90600052602060002090600202016001018981548110611c5f57611c5f6151dc565b15613c7c576000613912600986815481106138a9576138a96151dc565b906000526020600020906002020160010187815481106138cb576138cb6151dc565b906000526020600020906009020160020154600987815481106138f0576138f06151dc565b90600052602060002090600202016001018881548110611d4357611d436151dc565b90504260098681548110613928576139286151dc565b9060005260206000209060020201600101878154811061394a5761394a6151dc565b60009182526020909120600260099092020101556139684282612aa1565b6009868154811061397b5761397b6151dc565b9060005260206000209060020201600101878154811061399d5761399d6151dc565b9060005260206000209060090201600401819055506000600986815481106139c7576139c76151dc565b906000526020600020906002020160010187815481106139e9576139e96151dc565b60009182526020822060056009909202010191909155604051339184156108fc02918591818181858888f19350505050158015613a2a573d6000803e3d6000fd5b506040805183815242602082015233917f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc6910160405180910390a27fd0dbdf5a9c6f6230b05ec9279bf9c69ad874fceb6c427e3a79ad9d08951abe2760098681548110613a9957613a996151dc565b90600052602060002090600202016001018781548110613abb57613abb6151dc565b600091825260209091206009918202015481546001600160a01b03909116919088908110613aeb57613aeb6151dc565b90600052602060002090600202016001018881548110613b0d57613b0d6151dc565b90600052602060002090600902016001015460098881548110613b3257613b326151dc565b90600052602060002090600202016001018981548110613b5457613b546151dc565b90600052602060002090600902016002015460098981548110613b7957613b796151dc565b90600052602060002090600202016001018a81548110613b9b57613b9b6151dc565b90600052602060002090600902016005015460098a81548110613bc057613bc06151dc565b90600052602060002090600202016001018b81548110613be257613be26151dc565b90600052602060002090600902016004015460098b81548110613c0757613c076151dc565b90600052602060002090600202016001018c81548110613c2957613c296151dc565b600091825260209182902060066009909202010154604080516001600160a01b039098168852918701959095528501929092526060840152608083015260a082015260c00160405180910390a150612207565b6020830151613c8b9083612aa1565b905060098481548110613199576131996151dc565b600d546001600160a01b036101009091041633146117095760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610986565b600d80546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166000908152600b60205260408120546009805491929183908110613d8a57613d8a6151dc565b90600052602060002090600202016001018581548110613dac57613dac6151dc565b600091825260208083206040805161012081018252600990940290910180546001600160a01b031684526001810154928401929092526002820154908301526003810154606083015260048101546080830152600581015460a0830152600681015460c0830152600781015460ff16151560e0830152600801546101008201529150613e3a611aed83612a65565b90506000613e55828460200151612aa190919063ffffffff16565b905060098481548110613e6a57613e6a6151dc565b90600052602060002090600202016001018781548110613e8c57613e8c6151dc565b60009182526020822060099182020180546001600160a01b031916815560018101839055600281018390556003810183905560048101839055600581018390556006810183905560078101805460ff1916905560080191909155805485908110613ef857613ef86151dc565b9060005260206000209060020201600101600160098681548110613f1e57613f1e6151dc565b906000526020600020906002020160010180549050613f3d91906152a1565b81548110613f4d57613f4d6151dc565b906000526020600020906009020160098581548110613f6e57613f6e6151dc565b90600052602060002090600202016001018881548110613f9057613f906151dc565b600091825260209091208254600992830290910180546001600160a01b0319166001600160a01b03909216919091178155600180840154908201556002808401549082015560038084015490820155600480840154908201556005808401549082015560068084015490820155600780840154908201805460ff909216151560ff19909216919091179055600892830154920191909155805485908110614039576140396151dc565b90600052602060002090600202016001018054806140595761405961544b565b60008281526020812060096000199093019283020180546001600160a01b031916815560018101829055600281018290556003810182905560048101829055600581018290556006810182905560078101805460ff1916905560080155905584156109f957804710156140de5760405162461bcd60e51b81526004016109869061541e565b6040516001600160a01b0387169082156108fc029083906000818181858888f19350505050158015614114573d6000803e3d6000fd5b5050505050505050565b6141266126aa565b600d805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861415b3390565b6040516001600160a01b03909116815260200160405180910390a1565b600061418f600254836144dc90919063ffffffff16565b6141a8846141a260646128078a8a6144dc565b90612aa1565b116141b5575060016141b9565b5060005b949350505050565b600061281e82846152a1565b60006141d8866126f0565b6020810151815160408301516060840151608085015194955092939192909187146142455760405162461bcd60e51b815260206004820152601a60248201527f5061636b616765206973206e6f7420617574686f72697a65642e0000000000006044820152606401610986565b818b101580156142555750808b11155b6142a15760405162461bcd60e51b815260206004820152601860248201527f5374616b652076616c7565206e6f7420696e2072616e676500000000000000006044820152606401610986565b8a34146142e75760405162461bcd60e51b815260206004820152601460248201527324b73b30b634b21030b6b7bab73a1039b2b73a1760611b6044820152606401610986565b6142f189896146f2565b15156001146143425760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420616c6c204b657973206f776e656420627920616464726573732e00006044820152606401610986565b600161434c614817565b10156143915760405162461bcd60e51b815260206004820152601460248201527320b2323932b9b9903430bb329037379025b2bc9760611b6044820152606401610986565b61439d8b858b516127e1565b6143dc5760405162461bcd60e51b815260206004820152601060248201526f2737ba1032b737bab3b41025b2bcb99760811b6044820152606401610986565b6143e68989611548565b6143f58b85858b8d518b6148db565b5050505050505050505050565b6000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916905551909184917f76e6093c136cd7faa5a6d92b2b633f3b4595abd4a529b7a13917398355fea6949190a35050565b600d5460ff166117095760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610986565b6144ab61445a565b600d805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa3361415b565b600061281e8284615461565b600061281e8284615478565b60008060405180602001604052806009600b6000886001600160a01b03166001600160a01b03168152602001908152602001600020548154811061453a5761453a6151dc565b9060005260206000209060020201600101805480602002602001604051908101604052809291908181526020016000905b8282101561460157600084815260209081902060408051610120810182526009860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460ff16151560e084015260080154610100830152908352909201910161456b565b5050509152506004548151519192501161461f576000915050612a93565b60005b815151811015614671578382600001518281518110614643576146436151dc565b6020026020010151606001510361465f57600092505050612a93565b61466a600182615208565b9050614622565b506001949350505050565b60098054600190810180835560009283528291614698916152a1565b905082600982815481106146ae576146ae6151dc565b6000918252602080832060029290920290910180546001600160a01b0319166001600160a01b03948516179055949091168152600b90935260409092208290555090565b600f546000906001600160a01b03166147455760405162461bcd60e51b815260206004820152601560248201527425b2bc9021b7b73a3930b1ba103737ba1039b2ba1760591b6044820152606401610986565b60005b835181101561480d5760125484516001600160a01b03808616921690636352211e9087908590811061477c5761477c6151dc565b60200260200101516040518263ffffffff1660e01b81526004016147a291815260200190565b602060405180830381865afa1580156147bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147e3919061549a565b6001600160a01b0316146147fb576000915050612a93565b80614805816154b7565b915050614748565b5060019392505050565b600f546000906001600160a01b031661486a5760405162461bcd60e51b815260206004820152601560248201527425b2bc9021b7b73a3930b1ba103737ba1039b2ba1760591b6044820152606401610986565b6012546040516370a0823160e01b81523360048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156148b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906148d691906154d0565b905090565b6000818152600c60205260409020546149065760405162461bcd60e51b81526004016109869061521b565b6008546001600160a01b031661495e5760405162461bcd60e51b815260206004820152601860248201527f5374616b696e67206163636f756e74206e6f74207365742e00000000000000006044820152606401610986565b61496883866144f4565b6149845760405162461bcd60e51b8152600401610986906153a7565b600854600160a01b900460ff16156149d2576008546040516001600160a01b039091169087156108fc029088906000818181858888f193505050501580156149d0573d6000803e3d6000fd5b505b600854600160b81b900460ff1615614a36576008546006546001600160a01b03909116906108fc90614a0c90606490612807908b906144dc565b6040518115909202916000818181858888f19350505050158015614a34573d6000803e3d6000fd5b505b6001600160a01b0383166000908152600b6020526040812054904290829003614a6557614a628561467c565b91505b426001819055614a759087612aa1565b6003556009805483908110614a8c57614a8c6151dc565b9060005260206000209060020201600101604051806101200160405280876001600160a01b031681526020018a815260200183815260200189815260200160035481526020016000815260200186815260200160001515815260200185815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e08201518160070160006101000a81548160ff02191690831515021790555061010082015181600801555050846001600160a01b03167fc16be9a586414a157dd46b4d023aa9997a025dd1cbbaa67ac0c1b8273a5eaf558984848b6003548a604051612d4e96959493929190958652602086019490945260408501929092526060840152608083015260a082015260c00190565b508054600082556002029060005260206000209081019061124a9190614c55565b508054600082556005029060005260206000209081019061124a9190614c7a565b5b80821115614c76576000815560018101805460ff19169055600201614c56565b5090565b5b80821115614c765760008082556001820181905560028201819055600382018190556004820155600501614c7b565b6001600160a01b038116811461124a57600080fd5b600080600080600080600060e0888a031215614cda57600080fd5b8735965060208801359550604088013594506060880135614cfa81614caa565b9699959850939660808101359560a0820135955060c0909101359350915050565b600060208284031215614d2d57600080fd5b813561281e81614caa565b60006020808352604080840185518384870152818151808452606093508388019150858301925060005b81811015614dd957835180516001600160a01b031684528781015188850152868101518785015285810151868501526080808201519085015260a0808201519085015260c0808201519085015260e08082015115159085015261010090810151908401529286019261012090920191600101614d62565b509098975050505050505050565b600080600060608486031215614dfc57600080fd5b505081359360208301359350604090920135919050565b600060208284031215614e2557600080fd5b5035919050565b80358015158114614e3c57600080fd5b919050565b600080600060608486031215614e5657600080fd5b8335614e6181614caa565b9250614e6f60208501614e2c565b9150604084013590509250925092565b600080600080600060808688031215614e9757600080fd5b8535614ea281614caa565b94506020860135614eb281614caa565b935060408601359250606086013567ffffffffffffffff80821115614ed657600080fd5b818801915088601f830112614eea57600080fd5b813581811115614ef957600080fd5b896020828501011115614f0b57600080fd5b9699959850939650602001949392505050565b60008060408385031215614f3157600080fd5b8235614f3c81614caa565b946020939093013593505050565b600080600060608486031215614f5f57600080fd5b833592506020840135614f7181614caa565b929592945050506040919091013590565b60008060408385031215614f9557600080fd5b823591506020830135614fa781614caa565b809150509250929050565b600060208284031215614fc457600080fd5b61281e82614e2c565b634e487b7160e01b600052604160045260246000fd5b600082601f830112614ff457600080fd5b8135602067ffffffffffffffff8083111561501157615011614fcd565b8260051b604051601f19603f8301168101818110848211171561503657615036614fcd565b60405293845285810183019383810192508785111561505457600080fd5b83870191505b848210156150735781358352918301919083019061505a565b979650505050505050565b6000806040838503121561509157600080fd5b823567ffffffffffffffff8111156150a857600080fd5b6150b485828601614fe3565b9250506020830135614fa781614caa565b600080604083850312156150d857600080fd5b823591506150e860208401614e2c565b90509250929050565b60008060006060848603121561510657600080fd5b83359250602084013561511881614caa565b915061512660408501614e2c565b90509250925092565b600080600080600060a0868803121561514757600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b600080600080600060a0868803121561518257600080fd5b8535945060208601359350604086013567ffffffffffffffff8111156151a757600080fd5b6151b388828901614fe3565b9598949750949560608101359550608001359392505050565b634558454360e01b815260040190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115612a9357612a936151f2565b602080825260079082015266139bc8141bdbdb60ca1b604082015260600190565b60208082526017908201527f41646472657373206e6f7420726567697374657265642e000000000000000000604082015260600190565b60208082526014908201527327379030b1ba34bb32903837b9b4ba34b7b7399760611b604082015260600190565b81810381811115612a9357612a936151f2565b60208082526013908201527224b73232bc1037baba1037b3103930b733b29760691b604082015260600190565b6420a226a4a760d91b815260050190565b60208082526010908201526f21b7b73a3930b1ba102637b1b5b2b21760811b604082015260600190565b604080825283519082018190526000906020906060840190828701845b8281101561535557815184529284019290840190600101615339565b5050506001600160a01b039490941692019190915250919050565b60208082526018908201527f506f6f6c2054656d706f726172792053757370656e6465640000000000000000604082015260600190565b60208082526013908201527226b0bc1037b832b7103837b9b4ba34b7b7399760691b604082015260600190565b60008060008060008060c087890312156153ed57600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b6020808252601390820152722737ba1032b737bab3b4103130b630b731b29760691b604082015260600190565b634e487b7160e01b600052603160045260246000fd5b8082028115828204841417612a9357612a936151f2565b60008261549557634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156154ac57600080fd5b815161281e81614caa565b6000600182016154c9576154c96151f2565b5060010190565b6000602082840312156154e257600080fd5b505191905056fea2646970667358221220b7928ffcc33c8bd3073b21fc8d9edcc09fda6f1f3e43ef4c5f9391bec4ded02564736f6c63430008110033

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

0000000000000000000000005c76eb054b1b06a725be1715fbed9560ce5dba13

-----Decoded View---------------
Arg [0] : _newAdmin (address): 0x5C76Eb054B1b06A725be1715fbED9560cE5DbA13

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000005c76eb054b1b06a725be1715fbed9560ce5dba13


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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