Contract 0x303b6df406a47323fBf45Ac2412F85E87D36C5eA

Contract Overview

Balance:
0 BNB
Txn Hash
Block
From
To
Value [Txn Fee]
0x85f4804cd8348e695a9f4f85d5bc292350abd6b1266e510f22ae66f0a46423ac85463942021-05-04 12:02:0839 days 16 mins ago0xba535ade958703ffb99b9325ca8db04a00937029 IN  Contract Creation0 BNB0.05415436
[ 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[] public withdrawFeePercent;
    // The maximum number of days of penalties
    uint256[] 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
    );
    event WithdrawnSingleERC721(
        address indexed user,
        address token,
        uint128 tokenId
    );
    event WithdrawnBatchERC721(
        address indexed user,
        address token,
        uint128[] tokenIds
    );
    event EmergencyWithdrawnERC20(
        address indexed user,
        address token,
        uint256 amount
    );
    event EmergencyWithdrawnERC721(
        address indexed user,
        address token,
        uint128[] tokenIds
    );
    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 _uniLp, address _penaltyWallet) {
        owner = msg.sender;
        penaltyWallet = _penaltyWallet;

        PKF = _pkf;

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

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

        daysLockLevel.push(10 days);
        daysLockLevel.push(20 days);
        daysLockLevel.push(30 days);
        daysLockLevel.push(60 days);
        daysLockLevel.push(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(10**token.decimals).div(token.rate)
            );
        }

        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);
    }

    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);
    }

    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);
    }

    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(10**token.decimals).div(token.rate)
        );

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

    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);
    }

    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 _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":"_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"}],"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[]"}],"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[]"}],"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"}],"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"}],"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":"_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"}]

60806040526002805460ff191660041790553480156200001e57600080fd5b5060405162002ae038038062002ae0833981810160405260608110156200004457600080fd5b50805160208201516040909201516001808055600080546001600160a01b031990811633178255600280546001600160a01b0380871661010002610100600160a81b0319909216919091179091556003805491871691909216179055929392620000b39185919081816200017a565b620000c582600060968160016200017a565b5050681b1ae4d6e2ef5000006007555069010f0cf064dd5920000060085569043c33c1937564800000600955690cb49b44ba602d800000600a5560118054600181810183556000839052620d2f007f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c689283015582548082018455621a5e00908301558254808201845562278d009083015582548082018455624f1a009083015582549081019092556276a7009101556200029a565b6000546001600160a01b031633146200019257600080fd5b6001600160a01b038516600090815260126020526040902083620001fd576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a494e56414c49445f544f4b454e5f524154450000000000000000604482015290519081900360640190fd5b80546001600160a01b0387166001600160a01b0319909116811782556001820186905560028201859055600382018054841515610100810261ff001988151560ff1990941684171617909255604080518981526020810189905280820192909252606082019290925290517fa2e6575dd43e59d3cd5a578a774bc8fe643dca2202fc48ca6ad7549f7efddf249181900360800190a2505050505050565b61283680620002aa6000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c80638b36e64e11610104578063a1db9782116100a2578063d3494cc311610071578063d3494cc3146107ea578063de1705701461089d578063e4d2620e146108de578063f2fde38b1461091a576101cf565b8063a1db978214610726578063b4d2355414610752578063cb9a8c7e146107b1578063d288668a146107cd576101cf565b806390612a10116100de57806390612a101461067957806395512217146106ae57806397feb926146106d45780639d59c13414610700576101cf565b80638b36e64e1461064c5780638b752677146106695780638da5cb5b14610671576101cf565b806340c442de1161017157806356cb5e791161014b57806356cb5e791461051057806366322fc5146105c3578063747666bf146105e65780637f382a7c14610628576101cf565b806340c442de1461048d5780634a17fa6e146104b35780635435e4cd146104ed576101cf565b806317b9171b116101ad57806317b9171b1461034d5780631cc88afc1461039557806332ccb3a1146103bb5780633c9f3136146103da576101cf565b80630f208beb146101d45780630fed079a1461021b578063150b7a0214610252575b600080fd5b610202600480360360408110156101ea57600080fd5b506001600160a01b0381358116916020013516610940565b6040805192835260208301919091528051918290030190f35b6102506004803603604081101561023157600080fd5b5080356001600160a01b031690602001356001600160801b0316610964565b005b6103186004803603608081101561026857600080fd5b6001600160a01b038235811692602081013590911691604082013591908101906080810160608201356401000000008111156102a357600080fd5b8201836020820111156102b557600080fd5b803590602001918460018302840111640100000000831117156102d757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610b5c945050505050565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b6103836004803603606081101561036357600080fd5b506001600160a01b03813581169160208101359091169060400135610b85565b60408051918252519081900360200190f35b610250600480360360408110156103ab57600080fd5b5060ff8135169060200135610d4f565b610250600480360360208110156103d157600080fd5b50351515610e06565b610250600480360360408110156103f057600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561041b57600080fd5b82018360208201111561042d57600080fd5b8035906020019184602083028401116401000000008311171561044f57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610e30945050505050565b610250600480360360208110156104a357600080fd5b50356001600160a01b031661104a565b610250600480360360808110156104c957600080fd5b506001600160a01b0381351690602081013590604081013590606001351515611242565b6102506004803603604081101561050357600080fd5b508035906020013561139b565b6102506004803603604081101561052657600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561055157600080fd5b82018360208201111561056357600080fd5b8035906020019184602083028401116401000000008311171561058557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611425945050505050565b610250600480360360408110156105d957600080fd5b508035906020013561168c565b610250600480360360a08110156105fc57600080fd5b506001600160a01b038135169060208101359060408101359060608101351515906080013515156116b6565b6106306117e1565b604080516001600160a01b039092168252519081900360200190f35b6103836004803603602081101561066257600080fd5b50356117f0565b61063061180e565b610630611822565b6102506004803603604081101561068f57600080fd5b5080356001600160a01b031690602001356001600160801b0316611831565b610383600480360360208110156106c457600080fd5b50356001600160a01b0316611a64565b610250600480360360408110156106ea57600080fd5b506001600160a01b038135169060200135611a76565b6102506004803603602081101561071657600080fd5b50356001600160a01b0316611d5f565b6102506004803603604081101561073c57600080fd5b506001600160a01b038135169060200135611e47565b6107786004803603602081101561076857600080fd5b50356001600160a01b0316612105565b604080516001600160a01b0390961686526020860194909452848401929092521515606084015215156080830152519081900360a00190f35b6107b9612142565b604080519115158252519081900360200190f35b610383600480360360208110156107e357600080fd5b503561214b565b6102506004803603604081101561080057600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561082b57600080fd5b82018360208201111561083d57600080fd5b8035906020019184602083028401116401000000008311171561085f57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612158945050505050565b6108a5612326565b604051808261014080838360005b838110156108cb5781810151838201526020016108b3565b5050505090500191505060405180910390f35b610904600480360360208110156108f457600080fd5b50356001600160a01b031661238f565b6040805160ff9092168252519081900360200190f35b6102506004803603602081101561093057600080fd5b50356001600160a01b031661242c565b60046020908152600092835260408084209091529082529020805460019091015482565b600260015414156109bc576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260019081553360009081526004602090815260408083206001600160a01b03871684529091529020805490911115610a3d576040805162461bcd60e51b815260206004820152601d60248201527f6e6f7420656e6f75676820616d6f756e7420746f207769746864726177000000604482015290519081900360640190fd5b8054610a4a90600161244f565b81556001600160a01b038316600090815260126020908152604080832060028101543385526005909352922054610a809161244f565b33600081815260056020526040808220939093558251632142170760e11b815230600482015260248101929092526001600160801b038616604483015291516001600160a01b038716926342842e0e926064808201939182900301818387803b158015610aec57600080fd5b505af1158015610b00573d6000803e3d6000fd5b5050604080516001600160a01b03881681526001600160801b038716602082015281513394507f9b0d2d9cb32178c8c9d938abb7b3154f334053b2855151ae4af3e034443020e693509081900390910190a25050600180555050565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6001600160a01b03808416600090815260046020908152604080832093861683529290529081208054831115610c02576040805162461bcd60e51b815260206004820152601d60248201527f6e6f7420656e6f75676820616d6f756e7420746f207769746864726177000000604482015290519081900360640190fd5b610c316011600081548110610c1357fe5b9060005260206000200154826001015461249a90919063ffffffff16565b421015610c7657610c6e6064610c686010600081548110610c4e57fe5b9060005260206000200154866124f490919063ffffffff16565b9061254d565b915050610d48565b610c876011600181548110610c1357fe5b421015610ca457610c6e6064610c686010600181548110610c4e57fe5b610cb56011600281548110610c1357fe5b421015610cd257610c6e6064610c686010600281548110610c4e57fe5b610ce36011600381548110610c1357fe5b421015610d0057610c6e6064610c686010600381548110610c4e57fe5b610d116011600481548110610c1357fe5b421015610d2e57610c6e6064610c686010600481548110610c4e57fe5b610d446064610c686010600581548110610c4e57fe5b9150505b9392505050565b6000546001600160a01b03163314610d6657600080fd5b60008260ff16118015610d7d5750600a8260ff1611155b610dce576040805162461bcd60e51b815260206004820152600f60248201527f696e76616c6964205f7469657249640000000000000000000000000000000000604482015290519081900360640190fd5b8060068360ff16600a8110610ddf57fe5b015560025460ff9081169083161115610e02576002805460ff191660ff84161790555b5050565b6000546001600160a01b03163314610e1d57600080fd5b6013805460ff1916911515919091179055565b60026001541415610e88576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260019081556001600160a01b038316600090815260126020526040902060030154610100900460ff16151514610f07576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a544f4b454e5f4e4f545f41434345505445440000000000000000604482015290519081900360640190fd5b610f138233308461258f565b80516001600160a01b03831660009081526012602052604090206002810154610f5790610f419084906124f4565b336000908152600560205260409020549061249a565b33600090815260056020908152604080832093909355600481528282206001600160a01b038816835290522054610f8e908361249a565b3360008181526004602090815260408083206001600160a01b038a16808552908352818420958655426001909601959095558051948552848201818152885191860191909152875193947f29f710ede39ede0a00eba6e2e9c6444c6c110a11e1ba4c759fbeb7319e200420948a948a949293926060850192868201929102908190849084905b8381101561102c578181015183820152602001611014565b50505050905001935050505060405180910390a25050600180555050565b60135460ff166110a1576040805162461bcd60e51b815260206004820152601160248201527f66756e6374696f6e2064697361626c6564000000000000000000000000000000604482015290519081900360640190fd5b3360009081526004602090815260408083206001600160a01b038516845290915290208054611117576040805162461bcd60e51b815260206004820152601360248201527f6e6f7468696e6720746f20776974686472617700000000000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b0384168152601260205260409020600281015460018201546111699161115391610c68908690600a0a6124f4565b336000908152600560205260409020549061244f565b33600081815260056020908152604080832094909455835163a9059cbb60e01b815260048101939093526024830186905292516001600160a01b0388169363a9059cbb93604480820194929392918390030190829087803b1580156111cd57600080fd5b505af11580156111e1573d6000803e3d6000fd5b505050506040513d60208110156111f757600080fd5b5050604080516001600160a01b038616815260208101849052815133927ff563e0862357d06e5752eb37b7057a0b8b5aca7410305cfd9b45865523e48c6d928290030190a250505050565b6000546001600160a01b0316331461125957600080fd5b6001600160a01b0380851660008181526012602052604090208054909216146112c9576040805162461bcd60e51b815260206004820152601660248201527f544945523a3a544f4b454e5f4e4f545f45584953545300000000000000000000604482015290519081900360640190fd5b6000831161131e576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a494e56414c49445f544f4b454e5f524154450000000000000000604482015290519081900360640190fd5b6001810184905560028101839055600381018054831515610100810261ff001990921691909117909155604080518681526020810186905280820192909252516001600160a01b038716917fbd15641a49d1535bed381272d3ddc31eef8416b3b7bad7db30ddc5012a0d773b919081900360600190a25050505050565b6000546001600160a01b031633146113b257600080fd5b60648110611407576040805162461bcd60e51b815260206004820152601060248201527f746f6f20686967682070657263656e7400000000000000000000000000000000604482015290519081900360640190fd5b806010838154811061141557fe5b6000918252602090912001555050565b60135460ff1661147c576040805162461bcd60e51b815260206004820152601160248201527f66756e6374696f6e2064697361626c6564000000000000000000000000000000604482015290519081900360640190fd5b3360009081526004602090815260408083206001600160a01b0386168452909152902080546114f2576040805162461bcd60e51b815260206004820152601360248201527f6e6f7468696e6720746f20776974686472617700000000000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b03851681526012602052604090206002810154600182015461152e9161115391610c68908690600a0a6124f4565b3360009081526005602052604090205560018214156115e957846001600160a01b03166342842e0e30338760008151811061156557fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b03168152602001826001600160801b031681526020019350505050600060405180830381600087803b1580156115cc57600080fd5b505af11580156115e0573d6000803e3d6000fd5b505050506115f5565b6115f58530338761258f565b336001600160a01b03167fb715cb4e79ef166b1d9ed65d09702d7e3ec5122cb9fbeaa707fb913e9c1ce37c868660405180836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019060200280838360005b83811015611671578181015183820152602001611659565b50505050905001935050505060405180910390a25050505050565b6000546001600160a01b031633146116a357600080fd5b8062015180026011838154811061141557fe5b6000546001600160a01b031633146116cd57600080fd5b6001600160a01b038516600090815260126020526040902083611737576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a494e56414c49445f544f4b454e5f524154450000000000000000604482015290519081900360640190fd5b80546001600160a01b03871673ffffffffffffffffffffffffffffffffffffffff19909116811782556001820186905560028201859055600382018054841515610100810261ff001988151560ff1990941684171617909255604080518981526020810189905280820192909252606082019290925290517fa2e6575dd43e59d3cd5a578a774bc8fe643dca2202fc48ca6ad7549f7efddf249181900360800190a2505050505050565b6003546001600160a01b031681565b601081815481106117fd57fe5b600091825260209091200154905081565b60025461010090046001600160a01b031681565b6000546001600160a01b031681565b60026001541415611889576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260019081556001600160a01b038316600090815260126020526040902060030154610100900460ff16151514611908576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a544f4b454e5f4e4f545f41434345505445440000000000000000604482015290519081900360640190fd5b60408051632142170760e11b81523360048201523060248201526001600160801b038316604482015290516001600160a01b038416916342842e0e91606480830192600092919082900301818387803b15801561196457600080fd5b505af1158015611978573d6000803e3d6000fd5b505050506001600160a01b0382166000908152601260209081526040808320600281015433855260059093529220546119b09161249a565b33600090815260056020908152604080832093909355600481528282206001600160a01b0387168352905220546119e890600161249a565b3360008181526004602090815260408083206001600160a01b038916808552908352928190209485554260019095019490945583519182526001600160801b03861690820152825191927f5be542a8c2c9e5d3b957b4d097fd8f9a58be545f191664e9402e0aaa1e806a4492918290030190a250506001805550565b60056020526000908152604090205481565b60026001541415611ace576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556003546001600160a01b0383811691161415611b7557600354604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b158015611b4357600080fd5b505af1158015611b57573d6000803e3d6000fd5b505050506040513d6020811015611b6d57600080fd5b50611cbf9050565b6001600160a01b03821660009081526012602052604090206003015460ff610100909104161515600114611bf0576040805162461bcd60e51b815260206004820152601860248201527f544945523a3a544f4b454e5f4e4f545f41434345505445440000000000000000604482015290519081900360640190fd5b604080516323b872dd60e01b81523360048201523060248201526044810183905290516001600160a01b038416916323b872dd9160648083019260209291908290030181600087803b158015611c4557600080fd5b505af1158015611c59573d6000803e3d6000fd5b505050506040513d6020811015611c6f57600080fd5b50506001600160a01b038216600090815260126020526040902060018101546002820154611cad91610f4191600a9190910a90610c689086906124f4565b33600090815260056020526040902055505b3360009081526004602090815260408083206001600160a01b0386168452909152902054611ced908261249a565b3360008181526004602090815260408083206001600160a01b038816808552908352928190209485554260019095019490945583519182528101849052825191927f04d8f60fa44691072ee4e6e9128f56dfe9f2bf33a8f9df9d41fb15002a69e85192918290030190a2505060018055565b6000546001600160a01b03163314611d7657600080fd5b6002546001600160a01b03828116610100909204161415611dde576040805162461bcd60e51b815260206004820152601c60248201527f544945523a3a414c52454144595f50454e414c54595f57414c4c455400000000604482015290519081900360640190fd5b600280547fffffffffffffffffffffff0000000000000000000000000000000000000000ff166101006001600160a01b038416908102919091179091556040517f632dc63310d672067cf7ad0e0b3b52850161a8f5ce0c9d2055bce14ba39be17590600090a250565b60026001541415611e9f576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001553360009081526004602090815260408083206001600160a01b038616845290915290208054821115611f1d576040805162461bcd60e51b815260206004820152601d60248201527f6e6f7420656e6f75676820616d6f756e7420746f207769746864726177000000604482015290519081900360640190fd5b6003546001600160a01b03848116911614611f7c576001600160a01b038316600090815260126020526040902060028101546001820154611f6a9161115391610c68908790600a0a6124f4565b33600090815260056020526040902055505b6000611f89338585610b85565b90508015612019576002546040805163a9059cbb60e01b81526101009092046001600160a01b0390811660048401526024830184905290519086169163a9059cbb9160448083019260209291908290030181600087803b158015611fec57600080fd5b505af1158015612000573d6000803e3d6000fd5b505050506040513d602081101561201657600080fd5b50505b8154612025908461244f565b82556001600160a01b03841663a9059cbb33612041868561244f565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561208757600080fd5b505af115801561209b573d6000803e3d6000fd5b505050506040513d60208110156120b157600080fd5b5050604080516001600160a01b0386168152602081018390528151859233927fe12f449213a73ad1f62c33919b7322d5f9676030311d3627812988cbd92b1a0c929081900390910190a35050600180555050565b60126020526000908152604090208054600182015460028301546003909301546001600160a01b0390921692909160ff8082169161010090041685565b60135460ff1681565b601181815481106117fd57fe5b600260015414156121b0576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001553360009081526004602090815260408083206001600160a01b0386168452909152902081518154811115612230576040805162461bcd60e51b815260206004820152601d60248201527f6e6f7420656e6f75676820616d6f756e7420746f207769746864726177000000604482015290519081900360640190fd5b815461223c908261244f565b82556001600160a01b0384166000908152601260205260409020600281015461226a906111539084906124f4565b3360008181526005602052604090209190915561228b90869030908761258f565b336001600160a01b03167f10220b58b837e3d430439720bbcf47632a39c11a36ab399fa258c38c4826ddc4868660405180836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156123075781810151838201526020016122ef565b50505050905001935050505060405180910390a2505060018055505050565b61232e6127c0565b60015b600a8160ff16101561238a5760068160ff16600a811061234d57fe5b0154612359575061238c565b60068160ff16600a811061236957fe5b0154826001830360ff16600a811061237d57fe5b6020020152600101612331565b505b90565b6001600160a01b0380821660009081526005602090815260408083205460048352818420600354909516845293909152812054909182916123cf9161249a565b905060015b600a8160ff16116124245760068160ff16600a81106123ef57fe5b0154158061240d575060068160ff16600a811061240857fe5b015482105b15612419575050612427565b9150600182016123d4565b50505b919050565b6000546001600160a01b0316331461244357600080fd5b61244c81612649565b50565b600061249183836040518060400160405280601f81526020017f536166654d6174683a207375627472616374696f6e20756e646572666c6f77008152506126c4565b90505b92915050565b600082820183811015612491576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60008261250357506000612494565b8282028284828161251057fe5b04146124915760405162461bcd60e51b81526004018080602001828103825260218152602001806127e06021913960400191505060405180910390fd5b600061249183836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061275b565b60005b8151811461264257846001600160a01b03166342842e0e85858585815181106125b757fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b03168152602001826001600160801b031681526020019350505050600060405180830381600087803b15801561261e57600080fd5b505af1158015612632573d6000803e3d6000fd5b5050600190920191506125929050565b5050505050565b6001600160a01b03811661265c57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600081848411156127535760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612718578181015183820152602001612700565b50505050905090810190601f1680156127455780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836127aa5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612718578181015183820152602001612700565b5060008385816127b657fe5b0495945050505050565b604051806101400160405280600a90602082028036833750919291505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a26469706673582212203a07d23cb6b90f43fb5a71508debc1d9a9d368637008e61bff018fe7063d8fda64736f6c634300070100330000000000000000000000001dfdb0fb85402dc7f8d72d92ada8fbbb3ffc8633000000000000000000000000fe903a12359496b932e24c5e9b78f1b9060a63420000000000000000000000001bab8030249382a887f967fcaa7fe0be7b390728

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

0000000000000000000000001dfdb0fb85402dc7f8d72d92ada8fbbb3ffc8633000000000000000000000000fe903a12359496b932e24c5e9b78f1b9060a63420000000000000000000000001bab8030249382a887f967fcaa7fe0be7b390728

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000001dfdb0fb85402dc7f8d72d92ada8fbbb3ffc8633
Arg [1] : 000000000000000000000000fe903a12359496b932e24c5e9b78f1b9060a6342
Arg [2] : 0000000000000000000000001bab8030249382a887f967fcaa7fe0be7b390728


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