Contract 0xf0bcd99f51a7e749c8074c359aa1ae5b43a80806

Contract Overview

Balance:
0 BNB
Txn Hash
Block
From
To
Value [Txn Fee]
0x144cd06b7c2adb51dd3a447b9e69be1c6a01ccc3fd711c27b411feba529bf14e85768182021-05-05 13:23:2050 days 17 hrs ago0xba535ade958703ffb99b9325ca8db04a00937029 IN  Contract Creation0 BNB0.05520928
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RedKiteTiers

Compiler Version
v0.7.1+commit.f4a555be

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 10 : RedKiteTiers.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

import "../libraries/Ownable.sol";
import "../libraries/ReentrancyGuard.sol";
import "../token/ERC20/ERC20.sol";
import "../token/ERC721/IERC721.sol";
import "../token/ERC721/IERC721Receiver.sol";

contract RedKiteTiers is IERC721Receiver, Ownable, ReentrancyGuard {
    using SafeMath for uint256;

    // Info of each user
    struct UserInfo {
        uint256 staked; // How many tokens the user has provided
        uint256 stakedTime; // Block timestamp when the user provided token
    }

    // RedKiteTiers allow to stake multi tokens to up your tier. Please
    // visit the website to get token list or use the token contract to
    // check it is supported or not.

    // Info of each Token
    // Currency Rate with PKF: amount * rate / 10 ** decimals
    // Default PKF: rate=1, decimals=0
    struct ExternalToken {
        address contractAddress;
        uint256 decimals;
        uint256 rate;
        bool isERC721;
        bool canStake;
    }

    uint256 constant MAX_NUM_TIERS = 10;
    uint8 currentMaxTier = 4;

    // Address take user's withdraw fee
    address public penaltyWallet;
    // The POLKAFOUNDRY TOKEN!
    address public PKF;

    // Info of each user that stakes tokens
    mapping(address => mapping(address => UserInfo)) public userInfo;
    // Info of total Non-PKF token staked, converted with rate
    mapping(address => uint256) public userExternalStaked;
    // Minimum PKF need to stake each tier
    uint256[MAX_NUM_TIERS] tierPrice;
    // Percentage of penalties
    uint256[6] public withdrawFeePercent;
    // The maximum number of days of penalties
    uint256[5] public daysLockLevel;
    // Info of each token can stake
    mapping(address => ExternalToken) public externalToken;

    bool public canEmergencyWithdraw;

    event StakedERC20(address indexed user, address token, uint256 amount);
    event StakedSingleERC721(
        address indexed user,
        address token,
        uint128 tokenId
    );
    event StakedBatchERC721(
        address indexed user,
        address token,
        uint128[] tokenIds
    );
    event WithdrawnERC20(
        address indexed user,
        address token,
        uint256 indexed amount,
        uint256 fee,
        uint256 lastStakedTime
    );
    event WithdrawnSingleERC721(
        address indexed user,
        address token,
        uint128 tokenId,
        uint256 lastStakedTime
    );
    event WithdrawnBatchERC721(
        address indexed user,
        address token,
        uint128[] tokenIds,
        uint256 lastStakedTime
    );
    event EmergencyWithdrawnERC20(
        address indexed user,
        address token,
        uint256 amount,
        uint256 lastStakedTime
    );
    event EmergencyWithdrawnERC721(
        address indexed user,
        address token,
        uint128[] tokenIds,
        uint256 lastStakedTime
    );
    event AddExternalToken(
        address indexed token,
        uint256 decimals,
        uint256 rate,
        bool isERC721,
        bool canStake
    );
    event ExternalTokenStatsChange(
        address indexed token,
        uint256 decimals,
        uint256 rate,
        bool canStake
    );
    event ChangePenaltyWallet(address indexed penaltyWallet);

    constructor(address _pkf, address _sPkf, address _uniLp, address _penaltyWallet) {
        owner = msg.sender;
        penaltyWallet = _penaltyWallet;

        PKF = _pkf;

        addExternalToken(_pkf, 0, 1 , false, true);
        addExternalToken(_sPkf, 0, 1, false, true);
        addExternalToken(_uniLp, 0, 150, false, true);

        tierPrice[1] = 500e18;
        tierPrice[2] = 5000e18;
        tierPrice[3] = 20000e18;
        tierPrice[4] = 60000e18;

        daysLockLevel[0] = 10 days;
        daysLockLevel[1] = 20 days;
        daysLockLevel[2] = 30 days;
        daysLockLevel[3] = 60 days;
        daysLockLevel[4] = 90 days;
    }

    function depositERC20(address _token, uint256 _amount)
        external
        nonReentrant()
    {
        if (_token == PKF) {
            IERC20(PKF).transferFrom(msg.sender, address(this), _amount);
        } else {
            require(
                externalToken[_token].canStake == true,
                "TIER::TOKEN_NOT_ACCEPTED"
            );
            IERC20(_token).transferFrom(msg.sender, address(this), _amount);

            ExternalToken storage token = externalToken[_token];
            userExternalStaked[msg.sender] = userExternalStaked[msg.sender].add(
                _amount.mul(token.rate).div(10**token.decimals)
            );
        }

        userInfo[msg.sender][_token].staked = userInfo[msg.sender][_token]
            .staked
            .add(_amount);
        userInfo[msg.sender][_token].stakedTime = block.timestamp;

        emit StakedERC20(msg.sender, _token, _amount);
    }

    function depositSingleERC721(address _token, uint128 _tokenId)
        external
        nonReentrant()
    {
        require(
            externalToken[_token].canStake == true,
            "TIER::TOKEN_NOT_ACCEPTED"
        );
        IERC721(_token).safeTransferFrom(msg.sender, address(this), _tokenId);

        ExternalToken storage token = externalToken[_token];
        userExternalStaked[msg.sender] = userExternalStaked[msg.sender].add(
            token.rate
        );

        userInfo[msg.sender][_token].staked = userInfo[msg.sender][_token]
            .staked
            .add(1);
        userInfo[msg.sender][_token].stakedTime = block.timestamp;

        emit StakedSingleERC721(msg.sender, _token, _tokenId);
    }

    function depositBatchERC721(address _token, uint128[] memory _tokenIds)
        external
        nonReentrant()
    {
        require(
            externalToken[_token].canStake == true,
            "TIER::TOKEN_NOT_ACCEPTED"
        );
        _batchSafeTransferFrom(_token, msg.sender, address(this), _tokenIds);

        uint256 amount = _tokenIds.length;
        ExternalToken storage token = externalToken[_token];
        userExternalStaked[msg.sender] = userExternalStaked[msg.sender].add(
            amount.mul(token.rate)
        );

        userInfo[msg.sender][_token].staked = userInfo[msg.sender][_token]
            .staked
            .add(amount);
        userInfo[msg.sender][_token].stakedTime = block.timestamp;

        emit StakedBatchERC721(msg.sender, _token, _tokenIds);
    }

    function withdrawERC20(address _token, uint256 _amount)
        external
        nonReentrant()
    {
        UserInfo storage user = userInfo[msg.sender][_token];
        require(user.staked >= _amount, "not enough amount to withdraw");

        if (_token != PKF) {
            ExternalToken storage token = externalToken[_token];
            userExternalStaked[msg.sender] = userExternalStaked[msg.sender].sub(
                _amount.mul(token.rate).div(10**token.decimals)
            );
        }

        uint256 toPunish = calculateWithdrawFee(msg.sender, _token, _amount);
        if (toPunish > 0) {
            IERC20(_token).transfer(penaltyWallet, toPunish);
        }

        user.staked = user.staked.sub(_amount);

        IERC20(_token).transfer(msg.sender, _amount.sub(toPunish));
        emit WithdrawnERC20(
            msg.sender,
            _token,
            _amount,
            toPunish,
            user.stakedTime
        );
    }

    function withdrawSingleERC721(address _token, uint128 _tokenId)
        external
        nonReentrant()
    {
        UserInfo storage user = userInfo[msg.sender][_token];
        require(user.staked >= 1, "not enough amount to withdraw");

        user.staked = user.staked.sub(1);

        ExternalToken storage token = externalToken[_token];
        userExternalStaked[msg.sender] = userExternalStaked[msg.sender].sub(
            token.rate
        );

        IERC721(_token).safeTransferFrom(address(this), msg.sender, _tokenId);
        emit WithdrawnSingleERC721(
            msg.sender,
            _token,
            _tokenId,
            user.stakedTime
        );
    }

    function withdrawBatchERC721(address _token, uint128[] memory _tokenIds)
        external
        nonReentrant()
    {
        UserInfo storage user = userInfo[msg.sender][_token];
        uint256 amount = _tokenIds.length;
        require(user.staked >= amount, "not enough amount to withdraw");

        user.staked = user.staked.sub(amount);

        ExternalToken storage token = externalToken[_token];
        userExternalStaked[msg.sender] = userExternalStaked[msg.sender].sub(
            amount.mul(token.rate)
        );

        _batchSafeTransferFrom(_token, address(this), msg.sender, _tokenIds);
        emit WithdrawnBatchERC721(
            msg.sender,
            _token,
            _tokenIds,
            user.stakedTime
        );
    }

    function setPenaltyWallet(address _penaltyWallet) external onlyOwner {
        require(
            penaltyWallet != _penaltyWallet,
            "TIER::ALREADY_PENALTY_WALLET"
        );
        penaltyWallet = _penaltyWallet;

        emit ChangePenaltyWallet(_penaltyWallet);
    }

    function updateEmergencyWithdrawStatus(bool _status) external onlyOwner {
        canEmergencyWithdraw = _status;
    }

    function emergencyWithdrawERC20(address _token) external {
        require(canEmergencyWithdraw, "function disabled");
        UserInfo storage user = userInfo[msg.sender][_token];
        require(user.staked > 0, "nothing to withdraw");

        uint256 _amount = user.staked;
        user.staked = 0;

        ExternalToken storage token = externalToken[_token];
        userExternalStaked[msg.sender] = userExternalStaked[msg.sender].sub(
            _amount.mul(token.rate).div(10**token.decimals)
        );

        IERC20(_token).transfer(msg.sender, _amount);
        emit EmergencyWithdrawnERC20(
            msg.sender,
            _token,
            _amount,
            user.stakedTime
        );
    }

    function emergencyWithdrawERC721(address _token, uint128[] memory _tokenIds)
        external
    {
        require(canEmergencyWithdraw, "function disabled");
        UserInfo storage user = userInfo[msg.sender][_token];
        require(user.staked > 0, "nothing to withdraw");

        uint256 _amount = user.staked;
        user.staked = 0;

        ExternalToken storage token = externalToken[_token];
        userExternalStaked[msg.sender] = userExternalStaked[msg.sender].sub(
            _amount.mul(10**token.decimals).div(token.rate)
        );

        if (_amount == 1) {
            IERC721(_token).safeTransferFrom(
                address(this),
                msg.sender,
                _tokenIds[0]
            );
        } else {
            _batchSafeTransferFrom(
                _token,
                address(this),
                msg.sender,
                _tokenIds
            );
        }
        emit EmergencyWithdrawnERC721(
            msg.sender,
            _token,
            _tokenIds,
            user.stakedTime
        );
    }

    function addExternalToken(
        address _token,
        uint256 _decimals,
        uint256 _rate,
        bool _isERC721,
        bool _canStake
    ) public onlyOwner {
        ExternalToken storage token = externalToken[_token];

        require(_rate > 0, "TIER::INVALID_TOKEN_RATE");

        token.contractAddress = _token;
        token.decimals = _decimals;
        token.rate = _rate;
        token.isERC721 = _isERC721;
        token.canStake = _canStake;

        emit AddExternalToken(_token, _decimals, _rate, _isERC721, _canStake);
    }

    function setExternalToken(
        address _token,
        uint256 _decimals,
        uint256 _rate,
        bool _canStake
    ) external onlyOwner {
        ExternalToken storage token = externalToken[_token];

        require(token.contractAddress == _token, "TIER::TOKEN_NOT_EXISTS");
        require(_rate > 0, "TIER::INVALID_TOKEN_RATE");

        token.decimals = _decimals;
        token.rate = _rate;
        token.canStake = _canStake;

        emit ExternalTokenStatsChange(_token, _decimals, _rate, _canStake);
    }

    function updateTier(uint8 _tierId, uint256 _amount) external onlyOwner {
        require(_tierId > 0 && _tierId <= MAX_NUM_TIERS, "invalid _tierId");
        tierPrice[_tierId] = _amount;
        if (_tierId > currentMaxTier) {
            currentMaxTier = _tierId;
        }
    }

    function updateWithdrawFee(uint256 _key, uint256 _percent)
        external
        onlyOwner
    {
        require(_percent < 100, "too high percent");
        withdrawFeePercent[_key] = _percent;
    }

    function updatePunishTime(uint256 _key, uint256 _days) external onlyOwner {
        require(_days >= 0, "too short time");
        daysLockLevel[_key] = _days * 1 days;
    }

    function getUserTier(address _userAddress)
        external
        view
        returns (uint8 res)
    {
        uint256 totalStaked =
            userInfo[_userAddress][PKF].staked.add(
                userExternalStaked[_userAddress]
            );

        for (uint8 i = 1; i <= MAX_NUM_TIERS; i++) {
            if (tierPrice[i] == 0 || totalStaked < tierPrice[i]) {
                return res;
            }

            res = i;
        }
    }

    function calculateWithdrawFee(
        address _userAddress,
        address _token,
        uint256 _amount
    ) public view returns (uint256) {
        UserInfo storage user = userInfo[_userAddress][_token];
        require(user.staked >= _amount, "not enough amount to withdraw");

        if (block.timestamp < user.stakedTime.add(daysLockLevel[0])) {
            return _amount.mul(withdrawFeePercent[0]).div(100); //30%
        }

        if (block.timestamp < user.stakedTime.add(daysLockLevel[1])) {
            return _amount.mul(withdrawFeePercent[1]).div(100); //25%
        }

        if (block.timestamp < user.stakedTime.add(daysLockLevel[2])) {
            return _amount.mul(withdrawFeePercent[2]).div(100); //20%
        }

        if (block.timestamp < user.stakedTime.add(daysLockLevel[3])) {
            return _amount.mul(withdrawFeePercent[3]).div(100); //10%
        }

        if (block.timestamp < user.stakedTime.add(daysLockLevel[4])) {
            return _amount.mul(withdrawFeePercent[4]).div(100); //5%
        }

        return _amount.mul(withdrawFeePercent[5]).div(100);
    }

    //frontend func
    function getTiers()
        external
        view
        returns (uint256[MAX_NUM_TIERS] memory buf)
    {
        for (uint8 i = 1; i < MAX_NUM_TIERS; i++) {
            if (tierPrice[i] == 0) {
                return buf;
            }
            buf[i - 1] = tierPrice[i];
        }

        return buf;
    }

    function userTotalStaked(address _userAddress) external view returns (uint256) {
        return
            userInfo[_userAddress][PKF].staked.add(
                userExternalStaked[_userAddress]
            );
    }

    function _batchSafeTransferFrom(
        address _token,
        address _from,
        address _recepient,
        uint128[] memory _tokenIds
    ) internal {
        for (uint256 i = 0; i != _tokenIds.length; i++) {
            IERC721(_token).safeTransferFrom(_from, _recepient, _tokenIds[i]);
        }
    }

    function onERC721Received(
        address,
        address,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }
}

File 2 of 10 : Ownable.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;


/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;

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

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

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function transferOwnership(address _newOwner) public onlyOwner {
    _transferOwnership(_newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address _newOwner) internal {
    require(_newOwner != address(0));
    emit OwnershipTransferred(owner, _newOwner);
    owner = _newOwner;
  }
}

File 3 of 10 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

File 4 of 10 : ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "../utils/Context.sol";
import "./IERC20.sol";
import "../../libraries/SafeMath.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
        _totalSupply = 1000000e18;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal {
        _decimals = decimals_;
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

File 5 of 10 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

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

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

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

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

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

File 6 of 10 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}

File 7 of 10 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 GSN 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 payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 8 of 10 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

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

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

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

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

File 9 of 10 : SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;

// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol
// Subject to the MIT license.

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @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) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting with custom message on overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, errorMessage);

        return c;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot underflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

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

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @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, string memory errorMessage) internal pure returns (uint256) {
        // 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 0;
        }

        uint256 c = a * b;
        require(c / a == b, errorMessage);

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers.
     * Reverts 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) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers.
     * Reverts 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) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts 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 mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 10 of 10 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_pkf","type":"address"},{"internalType":"address","name":"_sPkf","type":"address"},{"internalType":"address","name":"_uniLp","type":"address"},{"internalType":"address","name":"_penaltyWallet","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isERC721","type":"bool"},{"indexed":false,"internalType":"bool","name":"canStake","type":"bool"}],"name":"AddExternalToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"penaltyWallet","type":"address"}],"name":"ChangePenaltyWallet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastStakedTime","type":"uint256"}],"name":"EmergencyWithdrawnERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint128[]","name":"tokenIds","type":"uint128[]"},{"indexed":false,"internalType":"uint256","name":"lastStakedTime","type":"uint256"}],"name":"EmergencyWithdrawnERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rate","type":"uint256"},{"indexed":false,"internalType":"bool","name":"canStake","type":"bool"}],"name":"ExternalTokenStatsChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint128[]","name":"tokenIds","type":"uint128[]"}],"name":"StakedBatchERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakedERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint128","name":"tokenId","type":"uint128"}],"name":"StakedSingleERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint128[]","name":"tokenIds","type":"uint128[]"},{"indexed":false,"internalType":"uint256","name":"lastStakedTime","type":"uint256"}],"name":"WithdrawnBatchERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastStakedTime","type":"uint256"}],"name":"WithdrawnERC20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint128","name":"tokenId","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"lastStakedTime","type":"uint256"}],"name":"WithdrawnSingleERC721","type":"event"},{"inputs":[],"name":"PKF","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"},{"internalType":"uint256","name":"_rate","type":"uint256"},{"internalType":"bool","name":"_isERC721","type":"bool"},{"internalType":"bool","name":"_canStake","type":"bool"}],"name":"addExternalToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"calculateWithdrawFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canEmergencyWithdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"daysLockLevel","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint128[]","name":"_tokenIds","type":"uint128[]"}],"name":"depositBatchERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint128","name":"_tokenId","type":"uint128"}],"name":"depositSingleERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"emergencyWithdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint128[]","name":"_tokenIds","type":"uint128[]"}],"name":"emergencyWithdrawERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"externalToken","outputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"bool","name":"isERC721","type":"bool"},{"internalType":"bool","name":"canStake","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTiers","outputs":[{"internalType":"uint256[10]","name":"buf","type":"uint256[10]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"}],"name":"getUserTier","outputs":[{"internalType":"uint8","name":"res","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"penaltyWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"},{"internalType":"uint256","name":"_rate","type":"uint256"},{"internalType":"bool","name":"_canStake","type":"bool"}],"name":"setExternalToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_penaltyWallet","type":"address"}],"name":"setPenaltyWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_status","type":"bool"}],"name":"updateEmergencyWithdrawStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_key","type":"uint256"},{"internalType":"uint256","name":"_days","type":"uint256"}],"name":"updatePunishTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_tierId","type":"uint8"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"updateTier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_key","type":"uint256"},{"internalType":"uint256","name":"_percent","type":"uint256"}],"name":"updateWithdrawFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userExternalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"staked","type":"uint256"},{"internalType":"uint256","name":"stakedTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_userAddress","type":"address"}],"name":"userTotalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint128[]","name":"_tokenIds","type":"uint128[]"}],"name":"withdrawBatchERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint128","name":"_tokenId","type":"uint128"}],"name":"withdrawSingleERC721","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526002805460ff191660041790553480156200001e57600080fd5b5060405162002aea38038062002aea833981810160405260808110156200004457600080fd5b508051602082015160408301516060909301516001808055600080546001600160a01b031990811633178255600280546001600160a01b0380871661010002610100600160a81b031990921691909117909155600380549188169190921617905593949293620000b991869190818162000140565b620000ca8360006001818162000140565b620000dc826000609681600162000140565b5050681b1ae4d6e2ef500000600755505069010f0cf064dd5920000060085569043c33c1937564800000600955690cb49b44ba602d800000600a55620d2f00601655621a5e0060175562278d00601855624f1a006019556276a700601a5562000260565b6000546001600160a01b031633146200015857600080fd5b6001600160a01b0385166000908152601b6020526040902083620001c3576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a494e56414c49445f544f4b454e5f524154450000000000000000604482015290519081900360640190fd5b80546001600160a01b0387166001600160a01b0319909116811782556001820186905560028201859055600382018054841515610100810261ff001988151560ff1990941684171617909255604080518981526020810189905280820192909252606082019290925290517fa2e6575dd43e59d3cd5a578a774bc8fe643dca2202fc48ca6ad7549f7efddf249181900360800190a2505050505050565b61287a80620002706000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80638b36e64e11610104578063a1db9782116100a2578063d3494cc311610071578063d3494cc31461081b578063de170570146108ce578063e4d2620e1461090f578063f2fde38b1461094b576101da565b8063a1db978214610757578063b4d2355414610783578063cb9a8c7e146107e2578063d288668a146107fe576101da565b806390612a10116100de57806390612a10146106aa57806395512217146106df57806397feb926146107055780639d59c13414610731576101da565b80638b36e64e1461067d5780638b7526771461069a5780638da5cb5b146106a2576101da565b806340c442de1161017c57806366322fc51161014b57806366322fc5146105ce578063719de1ef146105f1578063747666bf146106175780637f382a7c14610659576101da565b806340c442de146104985780634a17fa6e146104be5780635435e4cd146104f857806356cb5e791461051b576101da565b806317b9171b116101b857806317b9171b146103585780631cc88afc146103a057806332ccb3a1146103c65780633c9f3136146103e5576101da565b80630f208beb146101df5780630fed079a14610226578063150b7a021461025d575b600080fd5b61020d600480360360408110156101f557600080fd5b506001600160a01b0381358116916020013516610971565b6040805192835260208301919091528051918290030190f35b61025b6004803603604081101561023c57600080fd5b5080356001600160a01b031690602001356001600160801b0316610995565b005b6103236004803603608081101561027357600080fd5b6001600160a01b038235811692602081013590911691604082013591908101906080810160608201356401000000008111156102ae57600080fd5b8201836020820111156102c057600080fd5b803590602001918460018302840111640100000000831117156102e257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610b97945050505050565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b61038e6004803603606081101561036e57600080fd5b506001600160a01b03813581169160208101359091169060400135610bc0565b60408051918252519081900360200190f35b61025b600480360360408110156103b657600080fd5b5060ff8135169060200135610d29565b61025b600480360360208110156103dc57600080fd5b50351515610de0565b61025b600480360360408110156103fb57600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561042657600080fd5b82018360208201111561043857600080fd5b8035906020019184602083028401116401000000008311171561045a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610e0a945050505050565b61025b600480360360208110156104ae57600080fd5b50356001600160a01b0316611024565b61025b600480360360808110156104d457600080fd5b506001600160a01b038135169060208101359060408101359060600135151561122e565b61025b6004803603604081101561050e57600080fd5b5080359060200135611387565b61025b6004803603604081101561053157600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561055c57600080fd5b82018360208201111561056e57600080fd5b8035906020019184602083028401116401000000008311171561059057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611407945050505050565b61025b600480360360408110156105e457600080fd5b508035906020013561167a565b61038e6004803603602081101561060757600080fd5b50356001600160a01b03166116a4565b61025b600480360360a081101561062d57600080fd5b506001600160a01b038135169060208101359060408101359060608101351515906080013515156116eb565b610661611816565b604080516001600160a01b039092168252519081900360200190f35b61038e6004803603602081101561069357600080fd5b5035611825565b610661611839565b61066161184d565b61025b600480360360408110156106c057600080fd5b5080356001600160a01b031690602001356001600160801b031661185c565b61038e600480360360208110156106f557600080fd5b50356001600160a01b0316611a8f565b61025b6004803603604081101561071b57600080fd5b506001600160a01b038135169060200135611aa1565b61025b6004803603602081101561074757600080fd5b50356001600160a01b0316611d8a565b61025b6004803603604081101561076d57600080fd5b506001600160a01b038135169060200135611e72565b6107a96004803603602081101561079957600080fd5b50356001600160a01b031661213e565b604080516001600160a01b0390961686526020860194909452848401929092521515606084015215156080830152519081900360a00190f35b6107ea61217b565b604080519115158252519081900360200190f35b61038e6004803603602081101561081457600080fd5b5035612184565b61025b6004803603604081101561083157600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561085c57600080fd5b82018360208201111561086e57600080fd5b8035906020019184602083028401116401000000008311171561089057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612191945050505050565b6108d661236b565b604051808261014080838360005b838110156108fc5781810151838201526020016108e4565b5050505090500191505060405180910390f35b6109356004803603602081101561092557600080fd5b50356001600160a01b03166123d4565b6040805160ff9092168252519081900360200190f35b61025b6004803603602081101561096157600080fd5b50356001600160a01b0316612470565b60046020908152600092835260408084209091529082529020805460019091015482565b600260015414156109ed576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260019081553360009081526004602090815260408083206001600160a01b03871684529091529020805490911115610a6e576040805162461bcd60e51b815260206004820152601d60248201527f6e6f7420656e6f75676820616d6f756e7420746f207769746864726177000000604482015290519081900360640190fd5b8054610a7b906001612493565b81556001600160a01b0383166000908152601b6020908152604080832060028101543385526005909352922054610ab191612493565b33600081815260056020526040808220939093558251632142170760e11b815230600482015260248101929092526001600160801b038616604483015291516001600160a01b038716926342842e0e926064808201939182900301818387803b158015610b1d57600080fd5b505af1158015610b31573d6000803e3d6000fd5b5050506001830154604080516001600160a01b03881681526001600160801b038716602082015280820192909252513392507fde1c47f06163d16168ff4f2c984a4b075ae9911770dc5a03bb5cf091ba29e6489181900360600190a25050600180555050565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6001600160a01b03808416600090815260046020908152604080832093861683529290529081208054831115610c3d576040805162461bcd60e51b815260206004820152601d60248201527f6e6f7420656e6f75676820616d6f756e7420746f207769746864726177000000604482015290519081900360640190fd5b610c52601660005b01546001830154906124de565b421015610c7d57610c756064610c6f601060005b01548690612538565b90612591565b915050610d22565b610c8960166001610c45565b421015610ca157610c756064610c6f60106001610c66565b610cad60166002610c45565b421015610cc557610c756064610c6f60106002610c66565b610cd160166003610c45565b421015610ce957610c756064610c6f60106003610c66565b610cf560166004610c45565b421015610d0d57610c756064610c6f60106004610c66565b610d1e6064610c6f60106005610c66565b9150505b9392505050565b6000546001600160a01b03163314610d4057600080fd5b60008260ff16118015610d575750600a8260ff1611155b610da8576040805162461bcd60e51b815260206004820152600f60248201527f696e76616c6964205f7469657249640000000000000000000000000000000000604482015290519081900360640190fd5b8060068360ff16600a8110610db957fe5b015560025460ff9081169083161115610ddc576002805460ff191660ff84161790555b5050565b6000546001600160a01b03163314610df757600080fd5b601c805460ff1916911515919091179055565b60026001541415610e62576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260019081556001600160a01b0383166000908152601b6020526040902060030154610100900460ff16151514610ee1576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a544f4b454e5f4e4f545f41434345505445440000000000000000604482015290519081900360640190fd5b610eed823330846125d3565b80516001600160a01b0383166000908152601b602052604090206002810154610f3190610f1b908490612538565b33600090815260056020526040902054906124de565b33600090815260056020908152604080832093909355600481528282206001600160a01b038816835290522054610f6890836124de565b3360008181526004602090815260408083206001600160a01b038a16808552908352818420958655426001909601959095558051948552848201818152885191860191909152875193947f29f710ede39ede0a00eba6e2e9c6444c6c110a11e1ba4c759fbeb7319e200420948a948a949293926060850192868201929102908190849084905b83811015611006578181015183820152602001610fee565b50505050905001935050505060405180910390a25050600180555050565b601c5460ff1661107b576040805162461bcd60e51b815260206004820152601160248201527f66756e6374696f6e2064697361626c6564000000000000000000000000000000604482015290519081900360640190fd5b3360009081526004602090815260408083206001600160a01b0385168452909152902080546110f1576040805162461bcd60e51b815260206004820152601360248201527f6e6f7468696e6720746f20776974686472617700000000000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b0384168152601b60205260409020600181015460028201546111479161113191600a9190910a90610c6f908690612538565b3360009081526005602052604090205490612493565b33600081815260056020908152604080832094909455835163a9059cbb60e01b815260048101939093526024830186905292516001600160a01b0388169363a9059cbb93604480820194929392918390030190829087803b1580156111ab57600080fd5b505af11580156111bf573d6000803e3d6000fd5b505050506040513d60208110156111d557600080fd5b50506001830154604080516001600160a01b038716815260208101859052808201929092525133917f4439d36dd45fdaddcf6518d7a4fee7971ff74a765f0394b0baef30f323964a54919081900360600190a250505050565b6000546001600160a01b0316331461124557600080fd5b6001600160a01b038085166000818152601b602052604090208054909216146112b5576040805162461bcd60e51b815260206004820152601660248201527f544945523a3a544f4b454e5f4e4f545f45584953545300000000000000000000604482015290519081900360640190fd5b6000831161130a576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a494e56414c49445f544f4b454e5f524154450000000000000000604482015290519081900360640190fd5b6001810184905560028101839055600381018054831515610100810261ff001990921691909117909155604080518681526020810186905280820192909252516001600160a01b038716917fbd15641a49d1535bed381272d3ddc31eef8416b3b7bad7db30ddc5012a0d773b919081900360600190a25050505050565b6000546001600160a01b0316331461139e57600080fd5b606481106113f3576040805162461bcd60e51b815260206004820152601060248201527f746f6f20686967682070657263656e7400000000000000000000000000000000604482015290519081900360640190fd5b806010836006811061140157fe5b01555050565b601c5460ff1661145e576040805162461bcd60e51b815260206004820152601160248201527f66756e6374696f6e2064697361626c6564000000000000000000000000000000604482015290519081900360640190fd5b3360009081526004602090815260408083206001600160a01b0386168452909152902080546114d4576040805162461bcd60e51b815260206004820152601360248201527f6e6f7468696e6720746f20776974686472617700000000000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b0385168152601b60205260409020600281015460018201546115109161113191610c6f908690600a0a612538565b3360009081526005602052604090205560018214156115cb57846001600160a01b03166342842e0e30338760008151811061154757fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b03168152602001826001600160801b031681526020019350505050600060405180830381600087803b1580156115ae57600080fd5b505af11580156115c2573d6000803e3d6000fd5b505050506115d7565b6115d7853033876125d3565b336001600160a01b03167fc8c58486a6acdbf0a6a4e4d8cc486cfc6f767fd3c4ff2e27d4245dc4e08dcda08686866001015460405180846001600160a01b0316815260200180602001838152602001828103825284818151815260200191508051906020019060200280838360005b8381101561165e578181015183820152602001611646565b5050505090500194505050505060405180910390a25050505050565b6000546001600160a01b0316331461169157600080fd5b8062015180026016836005811061140157fe5b6001600160a01b038082166000908152600560209081526040808320546004835281842060035490951684529390915281205490916116e391906124de565b90505b919050565b6000546001600160a01b0316331461170257600080fd5b6001600160a01b0385166000908152601b602052604090208361176c576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a494e56414c49445f544f4b454e5f524154450000000000000000604482015290519081900360640190fd5b80546001600160a01b03871673ffffffffffffffffffffffffffffffffffffffff19909116811782556001820186905560028201859055600382018054841515610100810261ff001988151560ff1990941684171617909255604080518981526020810189905280820192909252606082019290925290517fa2e6575dd43e59d3cd5a578a774bc8fe643dca2202fc48ca6ad7549f7efddf249181900360800190a2505050505050565b6003546001600160a01b031681565b6010816006811061183257fe5b0154905081565b60025461010090046001600160a01b031681565b6000546001600160a01b031681565b600260015414156118b4576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260019081556001600160a01b0383166000908152601b6020526040902060030154610100900460ff16151514611933576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a544f4b454e5f4e4f545f41434345505445440000000000000000604482015290519081900360640190fd5b60408051632142170760e11b81523360048201523060248201526001600160801b038316604482015290516001600160a01b038416916342842e0e91606480830192600092919082900301818387803b15801561198f57600080fd5b505af11580156119a3573d6000803e3d6000fd5b505050506001600160a01b0382166000908152601b60209081526040808320600281015433855260059093529220546119db916124de565b33600090815260056020908152604080832093909355600481528282206001600160a01b038716835290522054611a139060016124de565b3360008181526004602090815260408083206001600160a01b038916808552908352928190209485554260019095019490945583519182526001600160801b03861690820152825191927f5be542a8c2c9e5d3b957b4d097fd8f9a58be545f191664e9402e0aaa1e806a4492918290030190a250506001805550565b60056020526000908152604090205481565b60026001541415611af9576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556003546001600160a01b0383811691161415611ba057600354604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b158015611b6e57600080fd5b505af1158015611b82573d6000803e3d6000fd5b505050506040513d6020811015611b9857600080fd5b50611cea9050565b6001600160a01b0382166000908152601b602052604090206003015460ff610100909104161515600114611c1b576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a544f4b454e5f4e4f545f41434345505445440000000000000000604482015290519081900360640190fd5b604080516323b872dd60e01b81523360048201523060248201526044810183905290516001600160a01b038416916323b872dd9160648083019260209291908290030181600087803b158015611c7057600080fd5b505af1158015611c84573d6000803e3d6000fd5b505050506040513d6020811015611c9a57600080fd5b50506001600160a01b0382166000908152601b6020526040902060018101546002820154611cd891610f1b91600a9190910a90610c6f908690612538565b33600090815260056020526040902055505b3360009081526004602090815260408083206001600160a01b0386168452909152902054611d1890826124de565b3360008181526004602090815260408083206001600160a01b038816808552908352928190209485554260019095019490945583519182528101849052825191927f04d8f60fa44691072ee4e6e9128f56dfe9f2bf33a8f9df9d41fb15002a69e85192918290030190a2505060018055565b6000546001600160a01b03163314611da157600080fd5b6002546001600160a01b03828116610100909204161415611e09576040805162461bcd60e51b815260206004820152601c60248201527f544945523a3a414c52454144595f50454e414c54595f57414c4c455400000000604482015290519081900360640190fd5b600280547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b038416908102919091179091556040517f632dc63310d672067cf7ad0e0b3b52850161a8f5ce0c9d2055bce14ba39be17590600090a250565b60026001541415611eca576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001553360009081526004602090815260408083206001600160a01b038616845290915290208054821115611f48576040805162461bcd60e51b815260206004820152601d60248201527f6e6f7420656e6f75676820616d6f756e7420746f207769746864726177000000604482015290519081900360640190fd5b6003546001600160a01b03848116911614611fab576001600160a01b0383166000908152601b6020526040902060018101546002820154611f999161113191600a9190910a90610c6f908790612538565b33600090815260056020526040902055505b6000611fb8338585610bc0565b90508015612048576002546040805163a9059cbb60e01b81526101009092046001600160a01b0390811660048401526024830184905290519086169163a9059cbb9160448083019260209291908290030181600087803b15801561201b57600080fd5b505af115801561202f573d6000803e3d6000fd5b505050506040513d602081101561204557600080fd5b50505b81546120549084612493565b82556001600160a01b03841663a9059cbb336120708685612493565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156120b657600080fd5b505af11580156120ca573d6000803e3d6000fd5b505050506040513d60208110156120e057600080fd5b50506001820154604080516001600160a01b0387168152602081018490528082019290925251849133917fc39c3b35eb9537ba0cdf6a2ae51c3bc5e1b6dafd6724374540b1620effd15b6b9181900360600190a35050600180555050565b601b6020526000908152604090208054600182015460028301546003909301546001600160a01b0390921692909160ff8082169161010090041685565b601c5460ff1681565b6016816005811061183257fe5b600260015414156121e9576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001553360009081526004602090815260408083206001600160a01b0386168452909152902081518154811115612269576040805162461bcd60e51b815260206004820152601d60248201527f6e6f7420656e6f75676820616d6f756e7420746f207769746864726177000000604482015290519081900360640190fd5b81546122759082612493565b82556001600160a01b0384166000908152601b6020526040902060028101546122a390611131908490612538565b336000818152600560205260409020919091556122c49086903090876125d3565b336001600160a01b03167f0c8a28bbc892d654c472b89d244e7ec16e9cf0c2ff243a02e738f7abd5b56f428686866001015460405180846001600160a01b0316815260200180602001838152602001828103825284818151815260200191508051906020019060200280838360005b8381101561234b578181015183820152602001612333565b5050505090500194505050505060405180910390a2505060018055505050565b612373612804565b60015b600a8160ff1610156123cf5760068160ff16600a811061239257fe5b015461239e57506123d1565b60068160ff16600a81106123ae57fe5b0154826001830360ff16600a81106123c257fe5b6020020152600101612376565b505b90565b6001600160a01b038082166000908152600560209081526040808320546004835281842060035490951684529390915281205490918291612414916124de565b905060015b600a8160ff16116124695760068160ff16600a811061243457fe5b01541580612452575060068160ff16600a811061244d57fe5b015482105b1561245e5750506116e6565b915060018201612419565b5050919050565b6000546001600160a01b0316331461248757600080fd5b6124908161268d565b50565b60006124d583836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f7700815250612708565b90505b92915050565b6000828201838110156124d5576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082612547575060006124d8565b8282028284828161255457fe5b04146124d55760405162461bcd60e51b81526004018080602001828103825260218152602001806128246021913960400191505060405180910390fd5b60006124d583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061279f565b60005b8151811461268657846001600160a01b03166342842e0e85858585815181106125fb57fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b03168152602001826001600160801b031681526020019350505050600060405180830381600087803b15801561266257600080fd5b505af1158015612676573d6000803e3d6000fd5b5050600190920191506125d69050565b5050505050565b6001600160a01b0381166126a057600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600081848411156127975760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561275c578181015183820152602001612744565b50505050905090810190601f1680156127895780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836127ee5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561275c578181015183820152602001612744565b5060008385816127fa57fe5b0495945050505050565b604051806101400160405280600a90602082028036833750919291505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212207fba1f8cb19c1defef28ef77c96a9ea850f6b007529cced1770338c5e583051964736f6c634300070100330000000000000000000000005d24b566f91a1b3d8b3c8e83544e8160924ce2760000000000000000000000002499ec6fad7394dbf3b7d06bccfd90092a6e5a03000000000000000000000000f8f37cb8a7d54be879b69ea63b1a645e8c262601000000000000000000000000ba535ade958703ffb99b9325ca8db04a00937029

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

0000000000000000000000005d24b566f91a1b3d8b3c8e83544e8160924ce2760000000000000000000000002499ec6fad7394dbf3b7d06bccfd90092a6e5a03000000000000000000000000f8f37cb8a7d54be879b69ea63b1a645e8c262601000000000000000000000000ba535ade958703ffb99b9325ca8db04a00937029

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000005d24b566f91a1b3d8b3c8e83544e8160924ce276
Arg [1] : 0000000000000000000000002499ec6fad7394dbf3b7d06bccfd90092a6e5a03
Arg [2] : 000000000000000000000000f8f37cb8a7d54be879b69ea63b1a645e8c262601
Arg [3] : 000000000000000000000000ba535ade958703ffb99b9325ca8db04a00937029


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading