ETH Price: $3,153.64 (-4.18%)

Token

Idexo General Staking Pool (IGSP)
 

Overview

Max Total Supply

0 IGSP

Holders

13

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
0 IGSP
0x1e62524bad7d01f319e3a5593f777ddc089002fc
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
StakePoolSimpleCombined

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-10-08
*/

pragma solidity 0.8.4;


// SPDX-License-Identifier: MIT
/**
 * @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);
}

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

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

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

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant alphabet = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = alphabet[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

}

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

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    function hasRole(bytes32 role, address account) external view returns (bool);
    function getRoleAdmin(bytes32 role) external view returns (bytes32);
    function grantRole(bytes32 role, address account) external;
    function revokeRole(bytes32 role, address account) external;
    function renounceRole(bytes32 role, address account) external;
}

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping (address => bool) members;
        bytes32 adminRole;
    }

    mapping (bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId
            || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{20}) is missing role (0x[0-9a-f]{32})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if(!hasRole(role, account)) {
            revert(string(abi.encodePacked(
                "AccessControl: account ",
                Strings.toHexString(uint160(account), 20),
                " is missing role ",
                Strings.toHexString(uint256(role), 32)
            )));
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        emit RoleAdminChanged(role, getRoleAdmin(role), adminRole);
        _roles[role].adminRole = adminRole;
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

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

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

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

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {

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

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

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

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping (uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping (address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor (string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IERC721).interfaceId
            || interfaceId == type(IERC721Metadata).interfaceId
            || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0
            ? string(abi.encodePacked(baseURI, tokenId.toString()))
            : '';
    }

    /**
     * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
     * in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @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.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        private returns (bool)
    {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

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

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

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

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }
}

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

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

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

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

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

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

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

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

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

interface IStakeToken is IERC721 {
    function getStakeTokenIds(
        address account
    )
        external
        returns (uint256[] memory);

    function isHolder(
        address account
    )
        external
        returns (bool);

    function getStakeInfo(
        uint256 stakeId
    )
        external
        returns (uint256, uint256, uint256);

    function getEligibleStakeAmount(
        uint256 fromDate
    )
        external
        returns (uint256);
}

contract StakeToken is IStakeToken, ERC721, Ownable {
    using SafeMath for uint256;
    // Last stake token id, start from 1
    uint256 public tokenIds;
    uint256 public constant multiplierDenominator = 100;

    struct Stake {
        uint256 amount;
        uint256 multiplier;
        uint256 depositedAt;
    }
    // stake id => stake info
    mapping(uint256 => Stake) public stakes;
    // staker wallet => stake id array
    mapping(address => uint256[]) public stakerIds;

    event StakeAmountDecreased(uint256 stakeId, uint256 decreaseAmount);

    constructor(
        string memory name_,
        string memory symbol_
    )
        ERC721(name_, symbol_)
    { }

    /**
     * @dev Get stake token id array owned by wallet address.
     * @param account address
     */
    function getStakeTokenIds(
        address account
    )
        public
        override
        view
        returns (uint256[] memory)
    {
        return stakerIds[account];
    }

    /**
     * @dev Return total stake amount of `account`
     */
    function getStakeAmount(
        address account
    )
        external
        view
        returns (uint256)
    {
        uint256[] memory stakeIds = stakerIds[account];
        uint256 totalStakeAmount;
        for (uint256 i = 0; i < stakeIds.length; i++) {
            totalStakeAmount += stakes[stakeIds[i]].amount;
        }
        return totalStakeAmount;
    }

    /**
     * @dev Check if wallet address owns any stake tokens.
     * @param account address
     */
    function isHolder(
        address account
    )
        public
        override
        view
        returns (bool)
    {
        return balanceOf(account) > 0;
    }

    /**
     * @dev Return stake info from `stakeId`.
     * Requirements:
     *
     * - `stakeId` must exist in stake pool
     * @param stakeId uint256
     */
    function getStakeInfo(
        uint256 stakeId
    )
        public
        override
        view
        returns (uint256, uint256, uint256)
    {
        require(_exists(stakeId), "StakeToken#getStakeInfo: STAKE_NOT_FOUND");
        return (stakes[stakeId].amount, stakes[stakeId].multiplier, stakes[stakeId].depositedAt);
    }

    /**
     * @dev Return total stake amount that have been in the pool from `fromDate`
     * Requirements:
     *
     * - `fromDate` must be past date
     */
    function getEligibleStakeAmount(
        uint256 fromDate
    )
        public
        override
        view
        returns (uint256)
    {
        require(fromDate <= block.timestamp, "StakeToken#getEligibleStakeAmount: NO_PAST_DATE");
        uint256 totalSAmount;

        for (uint256 i = 1; i <= tokenIds; i++) {
            if (_exists(i)) {
                Stake memory stake = stakes[i];
                if (stake.depositedAt > fromDate) {
                    break;
                }
                totalSAmount += stake.amount * stake.multiplier / multiplierDenominator;
            }
        }

        return totalSAmount;
    }

    /**
     * @dev Returns StakeToken multiplier.
     *
     * 0 < `tokenId` <300: 120.
     * 300 <= `tokenId` <4000: 110.
     * 4000 <= `tokenId`: 100.
     */
    function _getMultiplier()
        private
        view
        returns (uint256)
    {
        if (tokenIds < 300) {
            return 120;
        } else if (300 <= tokenIds && tokenIds < 4000) {
            return 110;
        } else {
            return 100;
        }
    }

    /**
     * @dev Mint a new StakeToken.
     * Requirements:
     *
     * - `account` must not be zero address, check ERC721 {_mint}
     * - `amount` must not be zero
     * @param account address of recipient.
     * @param amount mint amount.
     * @param depositedAt timestamp when stake was deposited.
     */
    function _mint(
        address account,
        uint256 amount,
        uint256 depositedAt
    )
        internal
        virtual
        returns (uint256)
    {
        require(amount > 0, "StakeToken#_mint: INVALID_AMOUNT");
        tokenIds++;
        uint256 multiplier = _getMultiplier();
        super._mint(account, tokenIds);
        Stake storage newStake = stakes[tokenIds];
        newStake.amount = amount;
        newStake.multiplier = multiplier;
        newStake.depositedAt = depositedAt;
        stakerIds[account].push(tokenIds);

        return tokenIds;
    }

    /**
     * @dev Burn stakeToken.
     * Requirements:
     *
     * - `stakeId` must exist in stake pool
     * @param stakeId id of buring token.
     */
    function _burn(
        uint256 stakeId
    )
        internal
        override
    {
        require(_exists(stakeId), "StakeToken#_burn: STAKE_NOT_FOUND");
        address stakeOwner = ownerOf(stakeId);
        super._burn(stakeId);
        delete stakes[stakeId];
        uint256[] storage stakeIds = stakerIds[stakeOwner];
        for (uint256 i = 0; i < stakeIds.length; i++) {
            if (stakeIds[i] == stakeId) {
                if (i != stakeIds.length - 1) {
                    stakeIds[i] = stakeIds[stakeIds.length - 1];
                }
                stakeIds.pop();
                break;
            }
        }
    }

    /**
     * @dev Decrease stake amount.
     * If stake amount leads to be zero, the stake is burned.
     * Requirements:
     *
     * - `stakeId` must exist in stake pool
     * @param stakeId id of buring token.
     * @param amount to withdraw.
     */
    function _decreaseStakeAmount(
        uint256 stakeId,
        uint256 amount
    )
        internal
        virtual
    {
        require(_exists(stakeId), "StakeToken#_decreaseStakeAmount: STAKE_NOT_FOUND");
        require(amount <= stakes[stakeId].amount, "StakeToken#_decreaseStakeAmount: INSUFFICIENT_STAKE_AMOUNT");
        if (amount == stakes[stakeId].amount) {
            _burn(stakeId);
        } else {
            stakes[stakeId].amount = stakes[stakeId].amount.sub(amount);
            emit StakeAmountDecreased(stakeId, amount);
        }
    }
}

interface IStakePool is IStakeToken {
    function addOperator(
        address account
    )
        external;

    function removeOperator(
        address account
    )
        external;

    function checkOperator(
        address account
    )
        external
        returns (bool);

    function deposit(
        uint256 amount
    )
        external;

    function withdraw(
        uint256 stakeId,
        uint256 amount
    )
        external;


    function depositReward(
        uint256 amount
    )
        external;


}

contract StakePoolSimpleCombined is IStakePool, StakeToken, AccessControl, ReentrancyGuard {
    using SafeERC20 for IERC20;

    bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
    uint256 public constant MONTH = 31 days;
    uint256 public constant QUARTER = 93 days;
    uint256 public constant YEAR = 365 days;
    // Reward distribution ratio - monthly, quarterly, yearly
    uint256 public constant mDistributionRatio = 25;
    uint256 public constant qDistributionRatio = 50;
    uint256 public constant yDistributionRatio = 25;
    // Minimum stake amount
    uint256 public constant minStakeAmount = 2500 * 1e18;

    uint256 public constant sClaimShareDenominator = 1e18;

    // Address of deposit token.
    IERC20 public depositToken;
    // Address of reward token.
    IERC20 public rewardToken;
    // Timestamp when stake pool was deployed to mainnet.
    uint256 public deployedAt;

    struct ClaimableRewardDeposit {
        address operator;
        uint256 amount;
        uint256 tokenId;
        uint256 depositedAt;
    }

    struct RewardDeposit {
        address operator;
        uint256 amount;
        uint256 depositedAt;
    }


    // Reward deposit history
    ClaimableRewardDeposit[] public claimableRewardDeposits;

    // Reward deposit history
    RewardDeposit[] public rewardDeposits;


    // tokenId => available reward amount that tokenId can claim.
    mapping(uint256 => uint256) public claimableRewards;

    event Deposited(address indexed account, uint256 indexed stakeId, uint256 amount);
    event Withdrawn(address indexed account, uint256 indexed stakeId, uint256 amount);
    event ClaimableRewardDeposited(address indexed account, uint256 amount);
    event RewardDeposited(address indexed account, uint256 amount);
    event RewardClaimed(address indexed account, uint256 amount);
    event Swept(address indexed operator, address token, address indexed to, uint256 amount);


    constructor(
        string memory stakeTokenName_,
        string memory stakeTokenSymbol_,
        IERC20 depositToken_,
        IERC20 rewardToken_
    )
        StakeToken(stakeTokenName_, stakeTokenSymbol_)
    {
        depositToken = depositToken_;
        rewardToken = rewardToken_;
        deployedAt = block.timestamp;

        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _setupRole(OPERATOR_ROLE, msg.sender);
    }

    /**
     * @dev Override supportInterface.
     */
    function supportsInterface(
        bytes4 interfaceId
    )
        public
        view
        virtual
        override(IERC165, AccessControl)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    /***********************|
    |          Role         |
    |______________________*/

    /**
     * @dev Restricted to members of the admin role.
     */
    modifier onlyAdmin() {
        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "StakePool#onlyAdmin: CALLER_NO_ADMIN_ROLE");
        _;
    }

    /**
     * @dev Restricted to members of the operator role.
     */
    modifier onlyOperator() {
        require(hasRole(OPERATOR_ROLE, msg.sender), "StakePool#onlyOperator: CALLER_NO_OPERATOR_ROLE");
        _;
    }

    /**
     * @dev Add an account to the operator role.
     * @param account address of recipient.
     */
    function addOperator(
        address account
    )
        public
        override
        onlyAdmin
    {
        // Check if `account` already has operator role
        require(!hasRole(OPERATOR_ROLE, account), "StakePool#addOperator: ALREADY_OERATOR_ROLE");
        grantRole(OPERATOR_ROLE, account);
    }

    /**
     * @dev Remove an account from the operator role.
     * @param account address.
     */
    function removeOperator(
        address account
    )
        public
        override
        onlyAdmin
    {
        // Check if `account` has operator role
        require(hasRole(OPERATOR_ROLE, account), "StakePool#removeOperator: NO_OPERATOR_ROLE");
        revokeRole(OPERATOR_ROLE, account);
    }

    /**
     * @dev Check if an account is operator.
     * @param account address of operator being checked.
     */
    function checkOperator(
        address account
    )
        public
        override
        view
        returns (bool)
    {
        return hasRole(OPERATOR_ROLE, account);
    }

    /************************|
    |          Stake         |
    |_______________________*/

    /**
     * @dev Deposit stake to the pool.
     * Requirements:
     *
     * - `amount` must not be zero
     * @param amount deposit amount.
     */
    function deposit(
        uint256 amount
    )
        external
        override
    {
        require(amount >= minStakeAmount, "StakePool#deposit: UNDER_MINIMUM_STAKE_AMOUNT");
        _deposit(msg.sender, amount);
    }

    /**
     * @dev Withdraw from the pool.
     *
     * If amount is less than amount of the stake, cut down amount.
     * If amount is equal to amount of the stake, burn the stake.
     *
     * Requirements:
     *
     * - `amount` >= `minStakeAmount`
     * @param stakeId id of Stake that is being withdrawn.
     * @param amount withdraw amount.
     */
    function withdraw(
        uint256 stakeId,
        uint256 amount
    )
        external
        override
    {
        require(amount > 0, "StakePool#withdraw: UNDER_MINIMUM_WITHDRAW_AMOUNT");
        _withdraw(msg.sender, stakeId, amount);
    }

    /**
     * @dev Deposit stake to the pool.
     * @param account address of recipient.
     * @param amount deposit amount.
     */
    function _deposit(
        address account,
        uint256 amount
    )
        private
        nonReentrant
    {
        uint256 stakeId = _mint(account, amount, block.timestamp);
        require(depositToken.transferFrom(account, address(this), amount), "StakePool#_deposit: TRANSFER_FAILED");

        emit Deposited(account, stakeId, amount);
    }

    /**
     * @dev If amount is less than amount of the stake, cut off amount.
     * If amount is equal to amount of the stake, burn the stake.
     *
     * Requirements:
     *
     * - `account` must be owner of `stakeId`
     * @param account address whose stake is being withdrawn.
     * @param stakeId id of stake that is being withdrawn.
     * @param withdrawAmount withdraw amount.
     */
    function _withdraw(
        address account,
        uint256 stakeId,
        uint256 withdrawAmount
    )
        private
        nonReentrant
    {
        require(ownerOf(stakeId) == account, "StakePool#_withdraw: NO_STAKE_OWNER");
        _decreaseStakeAmount(stakeId, withdrawAmount);
        require(depositToken.transfer(account, withdrawAmount), "StakePool#_withdraw: TRANSFER_FAILED");

        emit Withdrawn(account, stakeId, withdrawAmount);
    }

    /*************************|
    |          Reward         |
    |________________________*/

    /**
     * @dev Deposit reward to the pool.
     * Requirements:
     *
     * - `amount` must not be zero
     * @param amount deposit amount.
     */
    function depositReward(
        uint256 amount
    )
        external
        override
        onlyOperator
    {
        require(amount > 0, "StakePool#depositReward: ZERO_AMOUNT");
        _depositReward(msg.sender, amount);
    }

    /**
     * @dev Return reward deposit info by id.
     */
    function getRewardDeposit(
        uint256 id
    )
        external
        view
        returns (address, uint256, uint256)
    {
        return (rewardDeposits[id].operator, rewardDeposits[id].amount, rewardDeposits[id].depositedAt);
    }

    /**
     * @dev Return reward deposit info by id.
     */
    function getClaimableReward(
        uint256 tokenId
    )
        external
        view
        returns (uint256)
    {
        return (claimableRewards[tokenId]);
    }

    /**
     * @dev add to claimable reward for a given token id
     */
    function addClaimableReward(
        uint256 tokenId,
        uint256 amount
    )
        external
        onlyOperator
    {
        claimableRewards[tokenId] += amount;
    }

    /**
     * @dev batch add to claimable reward for given token ids
     */
    function addClaimableRewards(
        uint256[] calldata tokenIds,
        uint256[] calldata amounts
    )
        external
        onlyOperator
    {
        for (uint256 i = 0; i < tokenIds.length; i++) {
            claimableRewards[tokenIds[i]] += amounts[i];
        }
    }


    /**
     * @dev Claim reward.
     *
     * Requirements:
     *
     * - stake token owner must call
     * - `amount` must be less than claimable reward
     * @param amount claim amount
     */
    function claimReward(
        uint256 tokenId,
        uint256 amount
    )
        external
        nonReentrant
    {
        require((ownerOf(tokenId) == msg.sender), "StakePool#claimReward: CALLER_NO_TOKEN_OWNER");
        require(claimableRewards[tokenId] >= amount, "StakePool#claimReward: INSUFFICIENT_FUNDS");
        claimableRewards[tokenId] -= amount;
        rewardToken.safeTransfer(msg.sender, amount);
        emit RewardClaimed(msg.sender, amount);
    }


    /**
     * @dev Sweep funds
     * Accessible by operators
     */
    function sweep(
        address token_,
        address to,
        uint256 amount
    )
        public
        onlyOperator
    {
        IERC20 token = IERC20(token_);
        // balance check is being done in ERC20
        token.transfer(to, amount);
        emit Swept(msg.sender, token_, to, amount);
    }

    /**
     * @dev Deposit reward to the pool.
     * @param account address who deposits to the pool.
     * @param amount deposit amount.
     */
    function _depositReward(
        address account,
        uint256 amount
    )
        private
    {
        rewardToken.safeTransferFrom(account, address(this), amount);
        rewardDeposits.push(RewardDeposit({
            operator: account,
            amount: amount,
            depositedAt: block.timestamp
        }));
        emit RewardDeposited(account, amount);
    }



}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"stakeTokenName_","type":"string"},{"internalType":"string","name":"stakeTokenSymbol_","type":"string"},{"internalType":"contract IERC20","name":"depositToken_","type":"address"},{"internalType":"contract IERC20","name":"rewardToken_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimableRewardDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposited","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":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreaseAmount","type":"uint256"}],"name":"StakeAmountDecreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Swept","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"stakeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MONTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUARTER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addClaimableReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"addClaimableRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"checkOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimableRewardDeposits","outputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"depositedAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"claimableRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getClaimableReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fromDate","type":"uint256"}],"name":"getEligibleStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getRewardDeposit","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeId","type":"uint256"}],"name":"getStakeInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getStakeTokenIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isHolder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mDistributionRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multiplierDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"qDistributionRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardDeposits","outputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"depositedAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sClaimShareDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakerIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakes","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"},{"internalType":"uint256","name":"depositedAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stakeId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"yDistributionRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162003e6238038062003e62833981016040819052620000349162000375565b83838181816000908051906020019062000050929190620001ff565b50805162000066906001906020840190620001ff565b50505060006200007b6200014760201b60201c565b600680546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350506001600b5550600c80546001600160a01b038085166001600160a01b031992831617909255600d80549284169290911691909117905542600e55620001116000336200014b565b6200013d7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929336200014b565b5050505062000454565b3390565b6200015782826200015b565b5050565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff1662000157576000828152600a602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620001bb3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b8280546200020d9062000401565b90600052602060002090601f0160209004810192826200023157600085556200027c565b82601f106200024c57805160ff19168380011785556200027c565b828001600101855582156200027c579182015b828111156200027c5782518255916020019190600101906200025f565b506200028a9291506200028e565b5090565b5b808211156200028a57600081556001016200028f565b80516001600160a01b0381168114620002bd57600080fd5b919050565b600082601f830112620002d3578081fd5b81516001600160401b0380821115620002f057620002f06200043e565b604051601f8301601f19908116603f011681019082821181831017156200031b576200031b6200043e565b8160405283815260209250868385880101111562000337578485fd5b8491505b838210156200035a57858201830151818301840152908201906200033b565b838211156200036b57848385830101525b9695505050505050565b600080600080608085870312156200038b578384fd5b84516001600160401b0380821115620003a2578586fd5b620003b088838901620002c2565b95506020870151915080821115620003c6578485fd5b50620003d587828801620002c2565b935050620003e660408601620002a5565b9150620003f660608601620002a5565b905092959194509250565b600181811c908216806200041657607f821691505b602082108114156200043857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6139fe80620004646000396000f3fe608060405234801561001057600080fd5b506004361061038d5760003560e01c80638c25be3d116101de578063c51330a21161010f578063d5a44f86116100ad578063f18876841161007c578063f188768414610830578063f2fde38b14610840578063f5b541a614610853578063f7c618c11461086857600080fd5b8063d5a44f86146107a9578063de1ac2fd146107d8578063e985e9c5146107eb578063eae4c19f1461082757600080fd5b8063ca38f5ef116100e9578063ca38f5ef1461076a578063d4d7b19a14610779578063d547741f1461078c578063d5999a5c1461079f57600080fd5b8063c51330a214610731578063c87b56dd14610744578063c89039c51461075757600080fd5b8063a217fddf1161017c578063b4fc478911610156578063b4fc4789146106e5578063b532c9ed146106f8578063b6b55f251461070b578063b88d4fde1461071e57600080fd5b8063a217fddf146106b7578063a22cb465146106bf578063ac8a584a146106d257600080fd5b806395a07bbb116101b857806395a07bbb1461066957806395d89b411461067c5780639835fc7e146106845780639870d7fe146106a457600080fd5b80638c25be3d146106255780638da5cb5b1461064557806391d148541461065657600080fd5b806336568abe116102c357806370a08231116102615780637bc30dc5116102305780637bc30dc5146105ff578063839145401461060757806386402362146105ff57806386bb8f371461061257600080fd5b806370a08231146105d3578063714cff56146105e6578063715018a6146105ef57806372fbeb50146105f757600080fd5b80634cea7a901161029d5780634cea7a901461057a578063592920ec1461059a57806362c06767146105ad5780636352211e146105c057600080fd5b806336568abe1461054157806342842e0e14610554578063441a3e701461056757600080fd5b80630c2eb403116103305780631e2720ff1161030a5780631e2720ff146104e557806323b872dd146104f8578063248a9ca31461050b5780632f2ff15d1461052e57600080fd5b80630c2eb4031461048d5780630ce72d6e146104a05780631add5ab2146104a857600080fd5b806306fdde031161036c57806306fdde031461040a578063081812fc1461041f578063095ea7b31461044a578063098134821461045f57600080fd5b80627209601461039257806301ffc9a7146103cf578063038c0f77146103f2575b600080fd5b6103a56103a03660046134ae565b61087b565b604080516001600160a01b0390941684526020840192909252908201526060015b60405180910390f35b6103e26103dd3660046134e8565b6108b8565b60405190151581526020016103c6565b6103fc627a9b8081565b6040519081526020016103c6565b6104126108c9565b6040516103c691906136ae565b61043261042d3660046134ae565b61095b565b6040516001600160a01b0390911681526020016103c6565b61045d610458366004613400565b6109e8565b005b61047261046d3660046134ae565b610afe565b604080519384526020840192909252908201526060016103c6565b6103fc61049b36600461326e565b610b8b565b6103fc603281565b6104bb6104b63660046134ae565b610c65565b604080516001600160a01b03909516855260208501939093529183015260608201526080016103c6565b61045d6104f33660046134ae565b610ca9565b61045d6105063660046132ba565b610d46565b6103fc6105193660046134ae565b6000908152600a602052604090206001015490565b61045d61053c3660046134c6565b610d77565b61045d61054f3660046134c6565b610d9d565b61045d6105623660046132ba565b610e1b565b61045d610575366004613520565b610e36565b61058d61058836600461326e565b610eab565b6040516103c6919061366a565b6103fc6105a8366004613400565b610f17565b61045d6105bb3660046132ba565b610f48565b6104326105ce3660046134ae565b611050565b6103fc6105e136600461326e565b6110c7565b6103fc60075481565b61045d61114e565b6103fc606481565b6103fc601981565b6103fc6301e1338081565b61045d610620366004613520565b6111f2565b6103fc6106333660046134ae565b60009081526011602052604090205490565b6006546001600160a01b0316610432565b6103e26106643660046134c6565b611377565b61045d610677366004613429565b6113a2565b61041261146f565b6103fc6106923660046134ae565b60116020526000908152604090205481565b61045d6106b236600461326e565b61147e565b6103fc600081565b61045d6106cd3660046133ca565b611536565b61045d6106e036600461326e565b6115fb565b61045d6106f3366004613520565b6116b1565b6103a56107063660046134ae565b61170c565b61045d6107193660046134ae565b6117c3565b61045d61072c3660046132f5565b61183c565b6103fc61073f3660046134ae565b611874565b6104126107523660046134ae565b611980565b600c54610432906001600160a01b031681565b6103fc670de0b6b3a764000081565b6103e261078736600461326e565b611a58565b61045d61079a3660046134c6565b611a6b565b6103fc6228de8081565b6104726107b73660046134ae565b60086020526000908152604090208054600182015460029092015490919083565b6103e26107e636600461326e565b611a91565b6103e26107f9366004613288565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6103fc600e5481565b6103fc68878678326eac90000081565b61045d61084e36600461326e565b611aab565b6103fc6000805160206139a983398151915281565b600d54610432906001600160a01b031681565b6010818154811061088b57600080fd5b60009182526020909120600390910201805460018201546002909201546001600160a01b03909116925083565b60006108c382611bc6565b92915050565b6060600080546108d8906138d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610904906138d8565b80156109515780601f1061092657610100808354040283529160200191610951565b820191906000526020600020905b81548152906001019060200180831161093457829003601f168201915b5050505050905090565b600061096682611beb565b6109cc5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006109f382611050565b9050806001600160a01b0316836001600160a01b03161415610a615760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016109c3565b336001600160a01b0382161480610a7d5750610a7d81336107f9565b610aef5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016109c3565b610af98383611c08565b505050565b6000806000610b0c84611beb565b610b695760405162461bcd60e51b815260206004820152602860248201527f5374616b65546f6b656e236765745374616b65496e666f3a205354414b455f4e60448201526713d517d193d5539160c21b60648201526084016109c3565b5050506000908152600860205260409020805460018201546002909201549092565b6001600160a01b038116600090815260096020908152604080832080548251818502810185019093528083528493830182828015610be857602002820191906000526020600020905b815481526020019060010190808311610bd4575b50505050509050600080600090505b8251811015610c5d5760086000848381518110610c2457634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000015482610c499190613833565b915080610c5581613913565b915050610bf7565b509392505050565b600f8181548110610c7557600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919084565b610cc16000805160206139a983398151915233611377565b610cdd5760405162461bcd60e51b81526004016109c3906137ad565b60008111610d395760405162461bcd60e51b8152602060048201526024808201527f5374616b65506f6f6c236465706f7369745265776172643a205a45524f5f414d60448201526313d5539560e21b60648201526084016109c3565b610d433382611c76565b50565b610d503382611d89565b610d6c5760405162461bcd60e51b81526004016109c39061375c565b610af9838383611e73565b6000828152600a6020526040902060010154610d938133612013565b610af98383612077565b6001600160a01b0381163314610e0d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016109c3565b610e1782826120fd565b5050565b610af98383836040518060200160405280600081525061183c565b60008111610ea05760405162461bcd60e51b815260206004820152603160248201527f5374616b65506f6f6c2377697468647261773a20554e4445525f4d494e494d556044820152701357d5d2551211149055d7d05353d55395607a1b60648201526084016109c3565b610e17338383612164565b6001600160a01b038116600090815260096020908152604091829020805483518184028101840190945280845260609392830182828015610f0b57602002820191906000526020600020905b815481526020019060010190808311610ef7575b50505050509050919050565b60096020528160005260406000208181548110610f3357600080fd5b90600052602060002001600091509150505481565b610f606000805160206139a983398151915233611377565b610f7c5760405162461bcd60e51b81526004016109c3906137ad565b60405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284919082169063a9059cbb90604401602060405180830381600087803b158015610fc957600080fd5b505af1158015610fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110019190613492565b50604080516001600160a01b0386811682526020820185905285169133917fddb9e887767e767a0e6a62c15b95f9f09e40e04427f78be916fdf478da1dbc23910160405180910390a350505050565b6000818152600260205260408120546001600160a01b0316806108c35760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016109c3565b60006001600160a01b0382166111325760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016109c3565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b031633146111a85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109c3565b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600680546001600160a01b0319169055565b6002600b5414156112155760405162461bcd60e51b81526004016109c3906137fc565b6002600b553361122483611050565b6001600160a01b03161461128f5760405162461bcd60e51b815260206004820152602c60248201527f5374616b65506f6f6c23636c61696d5265776172643a2043414c4c45525f4e4f60448201526b2faa27a5a2a72fa7aba722a960a11b60648201526084016109c3565b6000828152601160205260409020548111156112ff5760405162461bcd60e51b815260206004820152602960248201527f5374616b65506f6f6c23636c61696d5265776172643a20494e53554646494349604482015268454e545f46554e445360b81b60648201526084016109c3565b6000828152601160205260408120805483929061131d90849061387e565b9091555050600d54611339906001600160a01b03163383612337565b60405181815233907f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f72419060200160405180910390a250506001600b55565b6000918252600a602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6113ba6000805160206139a983398151915233611377565b6113d65760405162461bcd60e51b81526004016109c3906137ad565b60005b838110156114685782828281811061140157634e487b7160e01b600052603260045260246000fd5b905060200201356011600087878581811061142c57634e487b7160e01b600052603260045260246000fd5b90506020020135815260200190815260200160002060008282546114509190613833565b9091555081905061146081613913565b9150506113d9565b5050505050565b6060600180546108d8906138d8565b611489600033611377565b6114a55760405162461bcd60e51b81526004016109c390613713565b6114bd6000805160206139a983398151915282611377565b1561151e5760405162461bcd60e51b815260206004820152602b60248201527f5374616b65506f6f6c236164644f70657261746f723a20414c52454144595f4f60448201526a455241544f525f524f4c4560a81b60648201526084016109c3565b610d436000805160206139a983398151915282610d77565b6001600160a01b03821633141561158f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109c3565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611606600033611377565b6116225760405162461bcd60e51b81526004016109c390613713565b61163a6000805160206139a983398151915282611377565b6116995760405162461bcd60e51b815260206004820152602a60248201527f5374616b65506f6f6c2372656d6f76654f70657261746f723a204e4f5f4f50456044820152695241544f525f524f4c4560b01b60648201526084016109c3565b610d436000805160206139a983398151915282611a6b565b6116c96000805160206139a983398151915233611377565b6116e55760405162461bcd60e51b81526004016109c3906137ad565b60008281526011602052604081208054839290611703908490613833565b90915550505050565b60008060006010848154811061173257634e487b7160e01b600052603260045260246000fd5b6000918252602090912060039091020154601080546001600160a01b03909216918690811061177157634e487b7160e01b600052603260045260246000fd5b906000526020600020906003020160010154601086815481106117a457634e487b7160e01b600052603260045260246000fd5b9060005260206000209060030201600201549250925092509193909250565b68878678326eac9000008110156118325760405162461bcd60e51b815260206004820152602d60248201527f5374616b65506f6f6c236465706f7369743a20554e4445525f4d494e494d554d60448201526c17d4d51052d157d05353d55395609a1b60648201526084016109c3565b610d43338261239a565b6118463383611d89565b6118625760405162461bcd60e51b81526004016109c39061375c565b61186e848484846124f1565b50505050565b6000428211156118de5760405162461bcd60e51b815260206004820152602f60248201527f5374616b65546f6b656e23676574456c696769626c655374616b65416d6f756e60448201526e743a204e4f5f504153545f4441544560881b60648201526084016109c3565b600060015b6007548111611979576118f581611beb565b1561196757600081815260086020908152604091829020825160608101845281548152600182015492810192909252600201549181018290529085101561193c5750611979565b6020810151815160649161194f9161385f565b611959919061384b565b6119639084613833565b9250505b8061197181613913565b9150506118e3565b5092915050565b606061198b82611beb565b6119ef5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016109c3565b6000611a0660408051602081019091526000815290565b90506000815111611a265760405180602001604052806000815250611a51565b80611a3084612524565b604051602001611a41929190613589565b6040516020818303038152906040525b9392505050565b600080611a64836110c7565b1192915050565b6000828152600a6020526040902060010154611a878133612013565b610af983836120fd565b60006108c36000805160206139a983398151915283611377565b6006546001600160a01b03163314611b055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109c3565b6001600160a01b038116611b6a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109c3565b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806108c357506108c38261263e565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611c3d82611050565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600d54611c8e906001600160a01b031683308461268e565b604080516060810182526001600160a01b038481168083526020808401868152428587019081526010805460018101825560009190915295517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672600390970296870180546001600160a01b0319169190961617909455517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67385015591517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67490930192909255915183815290917f7dbc080e4530c8bcf265eb5c9a35ae096ca1eb607b7e802b96581ef4c5e1a703910160405180910390a25050565b6000611d9482611beb565b611df55760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016109c3565b6000611e0083611050565b9050806001600160a01b0316846001600160a01b03161480611e3b5750836001600160a01b0316611e308461095b565b6001600160a01b0316145b80611e6b57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611e8682611050565b6001600160a01b031614611eee5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016109c3565b6001600160a01b038216611f505760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016109c3565b611f5b600082611c08565b6001600160a01b0383166000908152600360205260408120805460019290611f8490849061387e565b90915550506001600160a01b0382166000908152600360205260408120805460019290611fb2908490613833565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61201d8282611377565b610e1757612035816001600160a01b031660146126c6565b6120408360206126c6565b6040516020016120519291906135b8565b60408051601f198184030181529082905262461bcd60e51b82526109c3916004016136ae565b6120818282611377565b610e17576000828152600a602090815260408083206001600160a01b03851684529091529020805460ff191660011790556120b93390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6121078282611377565b15610e17576000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6002600b5414156121875760405162461bcd60e51b81526004016109c3906137fc565b6002600b556001600160a01b03831661219f83611050565b6001600160a01b0316146122015760405162461bcd60e51b815260206004820152602360248201527f5374616b65506f6f6c235f77697468647261773a204e4f5f5354414b455f4f576044820152622722a960e91b60648201526084016109c3565b61220b82826128a8565b600c5460405163a9059cbb60e01b81526001600160a01b038581166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b15801561225957600080fd5b505af115801561226d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122919190613492565b6122e95760405162461bcd60e51b8152602060048201526024808201527f5374616b65506f6f6c235f77697468647261773a205452414e534645525f46416044820152631253115160e21b60648201526084016109c3565b81836001600160a01b03167f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc68360405161232591815260200190565b60405180910390a350506001600b5550565b6040516001600160a01b038316602482015260448101829052610af990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a22565b6002600b5414156123bd5760405162461bcd60e51b81526004016109c3906137fc565b6002600b5560006123cf838342612af4565b600c546040516323b872dd60e01b81526001600160a01b038681166004830152306024830152604482018690529293509116906323b872dd90606401602060405180830381600087803b15801561242557600080fd5b505af1158015612439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245d9190613492565b6124b55760405162461bcd60e51b815260206004820152602360248201527f5374616b65506f6f6c235f6465706f7369743a205452414e534645525f46414960448201526213115160ea1b60648201526084016109c3565b80836001600160a01b03167f73a19dd210f1a7f902193214c0ee91dd35ee5b4d920cba8d519eca65a7b488ca8460405161232591815260200190565b6124fc848484611e73565b61250884848484612bca565b61186e5760405162461bcd60e51b81526004016109c3906136c1565b6060816125485750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612572578061255c81613913565b915061256b9050600a8361384b565b915061254c565b60008167ffffffffffffffff81111561259b57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156125c5576020820181803683370190505b5090505b8415611e6b576125da60018361387e565b91506125e7600a8661392e565b6125f2906030613833565b60f81b81838151811061261557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612637600a8661384b565b94506125c9565b60006001600160e01b031982166380ac58cd60e01b148061266f57506001600160e01b03198216635b5e139f60e01b145b806108c357506301ffc9a760e01b6001600160e01b03198316146108c3565b6040516001600160a01b038085166024830152831660448201526064810182905261186e9085906323b872dd60e01b90608401612363565b606060006126d583600261385f565b6126e0906002613833565b67ffffffffffffffff81111561270657634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612730576020820181803683370190505b509050600360fc1b8160008151811061275957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061279657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006127ba84600261385f565b6127c5906001613833565b90505b6001811115612859576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061280757634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061282b57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93612852816138c1565b90506127c8565b508315611a515760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109c3565b6128b182611beb565b6129165760405162461bcd60e51b815260206004820152603060248201527f5374616b65546f6b656e235f64656372656173655374616b65416d6f756e743a60448201526f0814d51052d157d393d517d193d5539160821b60648201526084016109c3565b60008281526008602052604090205481111561299a5760405162461bcd60e51b815260206004820152603a60248201527f5374616b65546f6b656e235f64656372656173655374616b65416d6f756e743a60448201527f20494e53554646494349454e545f5354414b455f414d4f554e5400000000000060648201526084016109c3565b6000828152600860205260409020548114156129b957610e1782612cd7565b6000828152600860205260409020546129d29082612e82565b6000838152600860209081526040918290209290925580518481529182018390527f9ce0fe3a2c7c141618ca6eb14273c7863eb6cfb1cdbfe0cb511d8006b1c1841a910160405180910390a15050565b6000612a77826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e8e9092919063ffffffff16565b805190915015610af95780806020019051810190612a959190613492565b610af95760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109c3565b6000808311612b455760405162461bcd60e51b815260206004820181905260248201527f5374616b65546f6b656e235f6d696e743a20494e56414c49445f414d4f554e5460448201526064016109c3565b60078054906000612b5583613913565b91905055506000612b64612e9d565b9050612b7285600754612ed9565b6007805460009081526008602090815260408083208881556001808201969096556002018790556001600160a01b03891683526009825282208354815495860182559083529120909201919091555490509392505050565b60006001600160a01b0384163b15612ccc57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612c0e90339089908890889060040161362d565b602060405180830381600087803b158015612c2857600080fd5b505af1925050508015612c58575060408051601f3d908101601f19168201909252612c5591810190613504565b60015b612cb2573d808015612c86576040519150601f19603f3d011682016040523d82523d6000602084013e612c8b565b606091505b508051612caa5760405162461bcd60e51b81526004016109c3906136c1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611e6b565b506001949350505050565b612ce081611beb565b612d365760405162461bcd60e51b815260206004820152602160248201527f5374616b65546f6b656e235f6275726e3a205354414b455f4e4f545f464f554e6044820152601160fa1b60648201526084016109c3565b6000612d4182611050565b9050612d4c8261300c565b6000828152600860209081526040808320838155600181018490556002018390556001600160a01b038416835260099091528120905b815481101561186e5783828281548110612dac57634e487b7160e01b600052603260045260246000fd5b90600052602060002001541415612e70578154612dcb9060019061387e565b8114612e375781548290612de19060019061387e565b81548110612dff57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154828281548110612e2a57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001555b81805480612e5557634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905561186e565b80612e7a81613913565b915050612d82565b6000611a51828461387e565b6060611e6b84846000856130a7565b600061012c6007541015612eb15750607890565b60075461012c11158015612ec85750610fa0600754105b15612ed35750606e90565b50606490565b6001600160a01b038216612f2f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109c3565b612f3881611beb565b15612f855760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109c3565b6001600160a01b0382166000908152600360205260408120805460019290612fae908490613833565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600061301782611050565b9050613024600083611c08565b6001600160a01b038116600090815260036020526040812080546001929061304d90849061387e565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060824710156131085760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109c3565b843b6131565760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109c3565b600080866001600160a01b03168587604051613172919061356d565b60006040518083038185875af1925050503d80600081146131af576040519150601f19603f3d011682016040523d82523d6000602084013e6131b4565b606091505b50915091506131c48282866131cf565b979650505050505050565b606083156131de575081611a51565b8251156131ee5782518084602001fd5b8160405162461bcd60e51b81526004016109c391906136ae565b80356001600160a01b038116811461321f57600080fd5b919050565b60008083601f840112613235578081fd5b50813567ffffffffffffffff81111561324c578182fd5b6020830191508360208260051b850101111561326757600080fd5b9250929050565b60006020828403121561327f578081fd5b611a5182613208565b6000806040838503121561329a578081fd5b6132a383613208565b91506132b160208401613208565b90509250929050565b6000806000606084860312156132ce578081fd5b6132d784613208565b92506132e560208501613208565b9150604084013590509250925092565b6000806000806080858703121561330a578081fd5b61331385613208565b935061332160208601613208565b925060408501359150606085013567ffffffffffffffff80821115613344578283fd5b818701915087601f830112613357578283fd5b8135818111156133695761336961396e565b604051601f8201601f19908116603f011681019083821181831017156133915761339161396e565b816040528281528a60208487010111156133a9578586fd5b82602086016020830137918201602001949094529598949750929550505050565b600080604083850312156133dc578182fd5b6133e583613208565b915060208301356133f581613984565b809150509250929050565b60008060408385031215613412578182fd5b61341b83613208565b946020939093013593505050565b6000806000806040858703121561343e578384fd5b843567ffffffffffffffff80821115613455578586fd5b61346188838901613224565b90965094506020870135915080821115613479578384fd5b5061348687828801613224565b95989497509550505050565b6000602082840312156134a3578081fd5b8151611a5181613984565b6000602082840312156134bf578081fd5b5035919050565b600080604083850312156134d8578182fd5b823591506132b160208401613208565b6000602082840312156134f9578081fd5b8135611a5181613992565b600060208284031215613515578081fd5b8151611a5181613992565b60008060408385031215613532578182fd5b50508035926020909101359150565b60008151808452613559816020860160208601613895565b601f01601f19169290920160200192915050565b6000825161357f818460208701613895565b9190910192915050565b6000835161359b818460208801613895565b8351908301906135af818360208801613895565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516135f0816017850160208801613895565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613621816028840160208801613895565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061366090830184613541565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156136a257835183529284019291840191600101613686565b50909695505050505050565b602081526000611a516020830184613541565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526029908201527f5374616b65506f6f6c236f6e6c7941646d696e3a2043414c4c45525f4e4f5f41604082015268444d494e5f524f4c4560b81b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602f908201527f5374616b65506f6f6c236f6e6c794f70657261746f723a2043414c4c45525f4e60408201526e4f5f4f50455241544f525f524f4c4560881b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000821982111561384657613846613942565b500190565b60008261385a5761385a613958565b500490565b600081600019048311821515161561387957613879613942565b500290565b60008282101561389057613890613942565b500390565b60005b838110156138b0578181015183820152602001613898565b8381111561186e5750506000910152565b6000816138d0576138d0613942565b506000190190565b600181811c908216806138ec57607f821691505b6020821081141561390d57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561392757613927613942565b5060010190565b60008261393d5761393d613958565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610d4357600080fd5b6001600160e01b031981168114610d4357600080fdfe97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929a2646970667358221220cfee7ca41aae620cb725e1b0dc30f436edbe60c9626b3dc9dc3f2d47025f0ced64736f6c63430008040033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000f9c53268e9de692ae1b2ea5216e24e1c3ad7cb1e000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000000000001a496465786f2047656e6572616c205374616b696e6720506f6f6c00000000000000000000000000000000000000000000000000000000000000000000000000044947535000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061038d5760003560e01c80638c25be3d116101de578063c51330a21161010f578063d5a44f86116100ad578063f18876841161007c578063f188768414610830578063f2fde38b14610840578063f5b541a614610853578063f7c618c11461086857600080fd5b8063d5a44f86146107a9578063de1ac2fd146107d8578063e985e9c5146107eb578063eae4c19f1461082757600080fd5b8063ca38f5ef116100e9578063ca38f5ef1461076a578063d4d7b19a14610779578063d547741f1461078c578063d5999a5c1461079f57600080fd5b8063c51330a214610731578063c87b56dd14610744578063c89039c51461075757600080fd5b8063a217fddf1161017c578063b4fc478911610156578063b4fc4789146106e5578063b532c9ed146106f8578063b6b55f251461070b578063b88d4fde1461071e57600080fd5b8063a217fddf146106b7578063a22cb465146106bf578063ac8a584a146106d257600080fd5b806395a07bbb116101b857806395a07bbb1461066957806395d89b411461067c5780639835fc7e146106845780639870d7fe146106a457600080fd5b80638c25be3d146106255780638da5cb5b1461064557806391d148541461065657600080fd5b806336568abe116102c357806370a08231116102615780637bc30dc5116102305780637bc30dc5146105ff578063839145401461060757806386402362146105ff57806386bb8f371461061257600080fd5b806370a08231146105d3578063714cff56146105e6578063715018a6146105ef57806372fbeb50146105f757600080fd5b80634cea7a901161029d5780634cea7a901461057a578063592920ec1461059a57806362c06767146105ad5780636352211e146105c057600080fd5b806336568abe1461054157806342842e0e14610554578063441a3e701461056757600080fd5b80630c2eb403116103305780631e2720ff1161030a5780631e2720ff146104e557806323b872dd146104f8578063248a9ca31461050b5780632f2ff15d1461052e57600080fd5b80630c2eb4031461048d5780630ce72d6e146104a05780631add5ab2146104a857600080fd5b806306fdde031161036c57806306fdde031461040a578063081812fc1461041f578063095ea7b31461044a578063098134821461045f57600080fd5b80627209601461039257806301ffc9a7146103cf578063038c0f77146103f2575b600080fd5b6103a56103a03660046134ae565b61087b565b604080516001600160a01b0390941684526020840192909252908201526060015b60405180910390f35b6103e26103dd3660046134e8565b6108b8565b60405190151581526020016103c6565b6103fc627a9b8081565b6040519081526020016103c6565b6104126108c9565b6040516103c691906136ae565b61043261042d3660046134ae565b61095b565b6040516001600160a01b0390911681526020016103c6565b61045d610458366004613400565b6109e8565b005b61047261046d3660046134ae565b610afe565b604080519384526020840192909252908201526060016103c6565b6103fc61049b36600461326e565b610b8b565b6103fc603281565b6104bb6104b63660046134ae565b610c65565b604080516001600160a01b03909516855260208501939093529183015260608201526080016103c6565b61045d6104f33660046134ae565b610ca9565b61045d6105063660046132ba565b610d46565b6103fc6105193660046134ae565b6000908152600a602052604090206001015490565b61045d61053c3660046134c6565b610d77565b61045d61054f3660046134c6565b610d9d565b61045d6105623660046132ba565b610e1b565b61045d610575366004613520565b610e36565b61058d61058836600461326e565b610eab565b6040516103c6919061366a565b6103fc6105a8366004613400565b610f17565b61045d6105bb3660046132ba565b610f48565b6104326105ce3660046134ae565b611050565b6103fc6105e136600461326e565b6110c7565b6103fc60075481565b61045d61114e565b6103fc606481565b6103fc601981565b6103fc6301e1338081565b61045d610620366004613520565b6111f2565b6103fc6106333660046134ae565b60009081526011602052604090205490565b6006546001600160a01b0316610432565b6103e26106643660046134c6565b611377565b61045d610677366004613429565b6113a2565b61041261146f565b6103fc6106923660046134ae565b60116020526000908152604090205481565b61045d6106b236600461326e565b61147e565b6103fc600081565b61045d6106cd3660046133ca565b611536565b61045d6106e036600461326e565b6115fb565b61045d6106f3366004613520565b6116b1565b6103a56107063660046134ae565b61170c565b61045d6107193660046134ae565b6117c3565b61045d61072c3660046132f5565b61183c565b6103fc61073f3660046134ae565b611874565b6104126107523660046134ae565b611980565b600c54610432906001600160a01b031681565b6103fc670de0b6b3a764000081565b6103e261078736600461326e565b611a58565b61045d61079a3660046134c6565b611a6b565b6103fc6228de8081565b6104726107b73660046134ae565b60086020526000908152604090208054600182015460029092015490919083565b6103e26107e636600461326e565b611a91565b6103e26107f9366004613288565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6103fc600e5481565b6103fc68878678326eac90000081565b61045d61084e36600461326e565b611aab565b6103fc6000805160206139a983398151915281565b600d54610432906001600160a01b031681565b6010818154811061088b57600080fd5b60009182526020909120600390910201805460018201546002909201546001600160a01b03909116925083565b60006108c382611bc6565b92915050565b6060600080546108d8906138d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610904906138d8565b80156109515780601f1061092657610100808354040283529160200191610951565b820191906000526020600020905b81548152906001019060200180831161093457829003601f168201915b5050505050905090565b600061096682611beb565b6109cc5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006109f382611050565b9050806001600160a01b0316836001600160a01b03161415610a615760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016109c3565b336001600160a01b0382161480610a7d5750610a7d81336107f9565b610aef5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016109c3565b610af98383611c08565b505050565b6000806000610b0c84611beb565b610b695760405162461bcd60e51b815260206004820152602860248201527f5374616b65546f6b656e236765745374616b65496e666f3a205354414b455f4e60448201526713d517d193d5539160c21b60648201526084016109c3565b5050506000908152600860205260409020805460018201546002909201549092565b6001600160a01b038116600090815260096020908152604080832080548251818502810185019093528083528493830182828015610be857602002820191906000526020600020905b815481526020019060010190808311610bd4575b50505050509050600080600090505b8251811015610c5d5760086000848381518110610c2457634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000015482610c499190613833565b915080610c5581613913565b915050610bf7565b509392505050565b600f8181548110610c7557600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919084565b610cc16000805160206139a983398151915233611377565b610cdd5760405162461bcd60e51b81526004016109c3906137ad565b60008111610d395760405162461bcd60e51b8152602060048201526024808201527f5374616b65506f6f6c236465706f7369745265776172643a205a45524f5f414d60448201526313d5539560e21b60648201526084016109c3565b610d433382611c76565b50565b610d503382611d89565b610d6c5760405162461bcd60e51b81526004016109c39061375c565b610af9838383611e73565b6000828152600a6020526040902060010154610d938133612013565b610af98383612077565b6001600160a01b0381163314610e0d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016109c3565b610e1782826120fd565b5050565b610af98383836040518060200160405280600081525061183c565b60008111610ea05760405162461bcd60e51b815260206004820152603160248201527f5374616b65506f6f6c2377697468647261773a20554e4445525f4d494e494d556044820152701357d5d2551211149055d7d05353d55395607a1b60648201526084016109c3565b610e17338383612164565b6001600160a01b038116600090815260096020908152604091829020805483518184028101840190945280845260609392830182828015610f0b57602002820191906000526020600020905b815481526020019060010190808311610ef7575b50505050509050919050565b60096020528160005260406000208181548110610f3357600080fd5b90600052602060002001600091509150505481565b610f606000805160206139a983398151915233611377565b610f7c5760405162461bcd60e51b81526004016109c3906137ad565b60405163a9059cbb60e01b81526001600160a01b0383811660048301526024820183905284919082169063a9059cbb90604401602060405180830381600087803b158015610fc957600080fd5b505af1158015610fdd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110019190613492565b50604080516001600160a01b0386811682526020820185905285169133917fddb9e887767e767a0e6a62c15b95f9f09e40e04427f78be916fdf478da1dbc23910160405180910390a350505050565b6000818152600260205260408120546001600160a01b0316806108c35760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016109c3565b60006001600160a01b0382166111325760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016109c3565b506001600160a01b031660009081526003602052604090205490565b6006546001600160a01b031633146111a85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109c3565b6006546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600680546001600160a01b0319169055565b6002600b5414156112155760405162461bcd60e51b81526004016109c3906137fc565b6002600b553361122483611050565b6001600160a01b03161461128f5760405162461bcd60e51b815260206004820152602c60248201527f5374616b65506f6f6c23636c61696d5265776172643a2043414c4c45525f4e4f60448201526b2faa27a5a2a72fa7aba722a960a11b60648201526084016109c3565b6000828152601160205260409020548111156112ff5760405162461bcd60e51b815260206004820152602960248201527f5374616b65506f6f6c23636c61696d5265776172643a20494e53554646494349604482015268454e545f46554e445360b81b60648201526084016109c3565b6000828152601160205260408120805483929061131d90849061387e565b9091555050600d54611339906001600160a01b03163383612337565b60405181815233907f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f72419060200160405180910390a250506001600b55565b6000918252600a602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6113ba6000805160206139a983398151915233611377565b6113d65760405162461bcd60e51b81526004016109c3906137ad565b60005b838110156114685782828281811061140157634e487b7160e01b600052603260045260246000fd5b905060200201356011600087878581811061142c57634e487b7160e01b600052603260045260246000fd5b90506020020135815260200190815260200160002060008282546114509190613833565b9091555081905061146081613913565b9150506113d9565b5050505050565b6060600180546108d8906138d8565b611489600033611377565b6114a55760405162461bcd60e51b81526004016109c390613713565b6114bd6000805160206139a983398151915282611377565b1561151e5760405162461bcd60e51b815260206004820152602b60248201527f5374616b65506f6f6c236164644f70657261746f723a20414c52454144595f4f60448201526a455241544f525f524f4c4560a81b60648201526084016109c3565b610d436000805160206139a983398151915282610d77565b6001600160a01b03821633141561158f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109c3565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b611606600033611377565b6116225760405162461bcd60e51b81526004016109c390613713565b61163a6000805160206139a983398151915282611377565b6116995760405162461bcd60e51b815260206004820152602a60248201527f5374616b65506f6f6c2372656d6f76654f70657261746f723a204e4f5f4f50456044820152695241544f525f524f4c4560b01b60648201526084016109c3565b610d436000805160206139a983398151915282611a6b565b6116c96000805160206139a983398151915233611377565b6116e55760405162461bcd60e51b81526004016109c3906137ad565b60008281526011602052604081208054839290611703908490613833565b90915550505050565b60008060006010848154811061173257634e487b7160e01b600052603260045260246000fd5b6000918252602090912060039091020154601080546001600160a01b03909216918690811061177157634e487b7160e01b600052603260045260246000fd5b906000526020600020906003020160010154601086815481106117a457634e487b7160e01b600052603260045260246000fd5b9060005260206000209060030201600201549250925092509193909250565b68878678326eac9000008110156118325760405162461bcd60e51b815260206004820152602d60248201527f5374616b65506f6f6c236465706f7369743a20554e4445525f4d494e494d554d60448201526c17d4d51052d157d05353d55395609a1b60648201526084016109c3565b610d43338261239a565b6118463383611d89565b6118625760405162461bcd60e51b81526004016109c39061375c565b61186e848484846124f1565b50505050565b6000428211156118de5760405162461bcd60e51b815260206004820152602f60248201527f5374616b65546f6b656e23676574456c696769626c655374616b65416d6f756e60448201526e743a204e4f5f504153545f4441544560881b60648201526084016109c3565b600060015b6007548111611979576118f581611beb565b1561196757600081815260086020908152604091829020825160608101845281548152600182015492810192909252600201549181018290529085101561193c5750611979565b6020810151815160649161194f9161385f565b611959919061384b565b6119639084613833565b9250505b8061197181613913565b9150506118e3565b5092915050565b606061198b82611beb565b6119ef5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016109c3565b6000611a0660408051602081019091526000815290565b90506000815111611a265760405180602001604052806000815250611a51565b80611a3084612524565b604051602001611a41929190613589565b6040516020818303038152906040525b9392505050565b600080611a64836110c7565b1192915050565b6000828152600a6020526040902060010154611a878133612013565b610af983836120fd565b60006108c36000805160206139a983398151915283611377565b6006546001600160a01b03163314611b055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109c3565b6001600160a01b038116611b6a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109c3565b6006546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160e01b03198216637965db0b60e01b14806108c357506108c38261263e565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611c3d82611050565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600d54611c8e906001600160a01b031683308461268e565b604080516060810182526001600160a01b038481168083526020808401868152428587019081526010805460018101825560009190915295517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672600390970296870180546001600160a01b0319169190961617909455517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67385015591517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67490930192909255915183815290917f7dbc080e4530c8bcf265eb5c9a35ae096ca1eb607b7e802b96581ef4c5e1a703910160405180910390a25050565b6000611d9482611beb565b611df55760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016109c3565b6000611e0083611050565b9050806001600160a01b0316846001600160a01b03161480611e3b5750836001600160a01b0316611e308461095b565b6001600160a01b0316145b80611e6b57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611e8682611050565b6001600160a01b031614611eee5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016109c3565b6001600160a01b038216611f505760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016109c3565b611f5b600082611c08565b6001600160a01b0383166000908152600360205260408120805460019290611f8490849061387e565b90915550506001600160a01b0382166000908152600360205260408120805460019290611fb2908490613833565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61201d8282611377565b610e1757612035816001600160a01b031660146126c6565b6120408360206126c6565b6040516020016120519291906135b8565b60408051601f198184030181529082905262461bcd60e51b82526109c3916004016136ae565b6120818282611377565b610e17576000828152600a602090815260408083206001600160a01b03851684529091529020805460ff191660011790556120b93390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6121078282611377565b15610e17576000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6002600b5414156121875760405162461bcd60e51b81526004016109c3906137fc565b6002600b556001600160a01b03831661219f83611050565b6001600160a01b0316146122015760405162461bcd60e51b815260206004820152602360248201527f5374616b65506f6f6c235f77697468647261773a204e4f5f5354414b455f4f576044820152622722a960e91b60648201526084016109c3565b61220b82826128a8565b600c5460405163a9059cbb60e01b81526001600160a01b038581166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b15801561225957600080fd5b505af115801561226d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122919190613492565b6122e95760405162461bcd60e51b8152602060048201526024808201527f5374616b65506f6f6c235f77697468647261773a205452414e534645525f46416044820152631253115160e21b60648201526084016109c3565b81836001600160a01b03167f92ccf450a286a957af52509bc1c9939d1a6a481783e142e41e2499f0bb66ebc68360405161232591815260200190565b60405180910390a350506001600b5550565b6040516001600160a01b038316602482015260448101829052610af990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a22565b6002600b5414156123bd5760405162461bcd60e51b81526004016109c3906137fc565b6002600b5560006123cf838342612af4565b600c546040516323b872dd60e01b81526001600160a01b038681166004830152306024830152604482018690529293509116906323b872dd90606401602060405180830381600087803b15801561242557600080fd5b505af1158015612439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061245d9190613492565b6124b55760405162461bcd60e51b815260206004820152602360248201527f5374616b65506f6f6c235f6465706f7369743a205452414e534645525f46414960448201526213115160ea1b60648201526084016109c3565b80836001600160a01b03167f73a19dd210f1a7f902193214c0ee91dd35ee5b4d920cba8d519eca65a7b488ca8460405161232591815260200190565b6124fc848484611e73565b61250884848484612bca565b61186e5760405162461bcd60e51b81526004016109c3906136c1565b6060816125485750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612572578061255c81613913565b915061256b9050600a8361384b565b915061254c565b60008167ffffffffffffffff81111561259b57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156125c5576020820181803683370190505b5090505b8415611e6b576125da60018361387e565b91506125e7600a8661392e565b6125f2906030613833565b60f81b81838151811061261557634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612637600a8661384b565b94506125c9565b60006001600160e01b031982166380ac58cd60e01b148061266f57506001600160e01b03198216635b5e139f60e01b145b806108c357506301ffc9a760e01b6001600160e01b03198316146108c3565b6040516001600160a01b038085166024830152831660448201526064810182905261186e9085906323b872dd60e01b90608401612363565b606060006126d583600261385f565b6126e0906002613833565b67ffffffffffffffff81111561270657634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612730576020820181803683370190505b509050600360fc1b8160008151811061275957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061279657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006127ba84600261385f565b6127c5906001613833565b90505b6001811115612859576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061280757634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061282b57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93612852816138c1565b90506127c8565b508315611a515760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109c3565b6128b182611beb565b6129165760405162461bcd60e51b815260206004820152603060248201527f5374616b65546f6b656e235f64656372656173655374616b65416d6f756e743a60448201526f0814d51052d157d393d517d193d5539160821b60648201526084016109c3565b60008281526008602052604090205481111561299a5760405162461bcd60e51b815260206004820152603a60248201527f5374616b65546f6b656e235f64656372656173655374616b65416d6f756e743a60448201527f20494e53554646494349454e545f5354414b455f414d4f554e5400000000000060648201526084016109c3565b6000828152600860205260409020548114156129b957610e1782612cd7565b6000828152600860205260409020546129d29082612e82565b6000838152600860209081526040918290209290925580518481529182018390527f9ce0fe3a2c7c141618ca6eb14273c7863eb6cfb1cdbfe0cb511d8006b1c1841a910160405180910390a15050565b6000612a77826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e8e9092919063ffffffff16565b805190915015610af95780806020019051810190612a959190613492565b610af95760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109c3565b6000808311612b455760405162461bcd60e51b815260206004820181905260248201527f5374616b65546f6b656e235f6d696e743a20494e56414c49445f414d4f554e5460448201526064016109c3565b60078054906000612b5583613913565b91905055506000612b64612e9d565b9050612b7285600754612ed9565b6007805460009081526008602090815260408083208881556001808201969096556002018790556001600160a01b03891683526009825282208354815495860182559083529120909201919091555490509392505050565b60006001600160a01b0384163b15612ccc57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612c0e90339089908890889060040161362d565b602060405180830381600087803b158015612c2857600080fd5b505af1925050508015612c58575060408051601f3d908101601f19168201909252612c5591810190613504565b60015b612cb2573d808015612c86576040519150601f19603f3d011682016040523d82523d6000602084013e612c8b565b606091505b508051612caa5760405162461bcd60e51b81526004016109c3906136c1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611e6b565b506001949350505050565b612ce081611beb565b612d365760405162461bcd60e51b815260206004820152602160248201527f5374616b65546f6b656e235f6275726e3a205354414b455f4e4f545f464f554e6044820152601160fa1b60648201526084016109c3565b6000612d4182611050565b9050612d4c8261300c565b6000828152600860209081526040808320838155600181018490556002018390556001600160a01b038416835260099091528120905b815481101561186e5783828281548110612dac57634e487b7160e01b600052603260045260246000fd5b90600052602060002001541415612e70578154612dcb9060019061387e565b8114612e375781548290612de19060019061387e565b81548110612dff57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154828281548110612e2a57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001555b81805480612e5557634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905561186e565b80612e7a81613913565b915050612d82565b6000611a51828461387e565b6060611e6b84846000856130a7565b600061012c6007541015612eb15750607890565b60075461012c11158015612ec85750610fa0600754105b15612ed35750606e90565b50606490565b6001600160a01b038216612f2f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109c3565b612f3881611beb565b15612f855760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109c3565b6001600160a01b0382166000908152600360205260408120805460019290612fae908490613833565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600061301782611050565b9050613024600083611c08565b6001600160a01b038116600090815260036020526040812080546001929061304d90849061387e565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6060824710156131085760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109c3565b843b6131565760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109c3565b600080866001600160a01b03168587604051613172919061356d565b60006040518083038185875af1925050503d80600081146131af576040519150601f19603f3d011682016040523d82523d6000602084013e6131b4565b606091505b50915091506131c48282866131cf565b979650505050505050565b606083156131de575081611a51565b8251156131ee5782518084602001fd5b8160405162461bcd60e51b81526004016109c391906136ae565b80356001600160a01b038116811461321f57600080fd5b919050565b60008083601f840112613235578081fd5b50813567ffffffffffffffff81111561324c578182fd5b6020830191508360208260051b850101111561326757600080fd5b9250929050565b60006020828403121561327f578081fd5b611a5182613208565b6000806040838503121561329a578081fd5b6132a383613208565b91506132b160208401613208565b90509250929050565b6000806000606084860312156132ce578081fd5b6132d784613208565b92506132e560208501613208565b9150604084013590509250925092565b6000806000806080858703121561330a578081fd5b61331385613208565b935061332160208601613208565b925060408501359150606085013567ffffffffffffffff80821115613344578283fd5b818701915087601f830112613357578283fd5b8135818111156133695761336961396e565b604051601f8201601f19908116603f011681019083821181831017156133915761339161396e565b816040528281528a60208487010111156133a9578586fd5b82602086016020830137918201602001949094529598949750929550505050565b600080604083850312156133dc578182fd5b6133e583613208565b915060208301356133f581613984565b809150509250929050565b60008060408385031215613412578182fd5b61341b83613208565b946020939093013593505050565b6000806000806040858703121561343e578384fd5b843567ffffffffffffffff80821115613455578586fd5b61346188838901613224565b90965094506020870135915080821115613479578384fd5b5061348687828801613224565b95989497509550505050565b6000602082840312156134a3578081fd5b8151611a5181613984565b6000602082840312156134bf578081fd5b5035919050565b600080604083850312156134d8578182fd5b823591506132b160208401613208565b6000602082840312156134f9578081fd5b8135611a5181613992565b600060208284031215613515578081fd5b8151611a5181613992565b60008060408385031215613532578182fd5b50508035926020909101359150565b60008151808452613559816020860160208601613895565b601f01601f19169290920160200192915050565b6000825161357f818460208701613895565b9190910192915050565b6000835161359b818460208801613895565b8351908301906135af818360208801613895565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516135f0816017850160208801613895565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613621816028840160208801613895565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061366090830184613541565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156136a257835183529284019291840191600101613686565b50909695505050505050565b602081526000611a516020830184613541565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526029908201527f5374616b65506f6f6c236f6e6c7941646d696e3a2043414c4c45525f4e4f5f41604082015268444d494e5f524f4c4560b81b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602f908201527f5374616b65506f6f6c236f6e6c794f70657261746f723a2043414c4c45525f4e60408201526e4f5f4f50455241544f525f524f4c4560881b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000821982111561384657613846613942565b500190565b60008261385a5761385a613958565b500490565b600081600019048311821515161561387957613879613942565b500290565b60008282101561389057613890613942565b500390565b60005b838110156138b0578181015183820152602001613898565b8381111561186e5750506000910152565b6000816138d0576138d0613942565b506000190190565b600181811c908216806138ec57607f821691505b6020821081141561390d57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561392757613927613942565b5060010190565b60008261393d5761393d613958565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610d4357600080fd5b6001600160e01b031981168114610d4357600080fdfe97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929a2646970667358221220cfee7ca41aae620cb725e1b0dc30f436edbe60c9626b3dc9dc3f2d47025f0ced64736f6c63430008040033

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

000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000f9c53268e9de692ae1b2ea5216e24e1c3ad7cb1e000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000000000000000000000000000000000000000001a496465786f2047656e6572616c205374616b696e6720506f6f6c00000000000000000000000000000000000000000000000000000000000000000000000000044947535000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : stakeTokenName_ (string): Idexo General Staking Pool
Arg [1] : stakeTokenSymbol_ (string): IGSP
Arg [2] : depositToken_ (address): 0xF9c53268e9de692AE1b2ea5216E24e1c3ad7CB1E
Arg [3] : rewardToken_ (address): 0xdAC17F958D2ee523a2206206994597C13D831ec7

-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 000000000000000000000000f9c53268e9de692ae1b2ea5216e24e1c3ad7cb1e
Arg [3] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [4] : 000000000000000000000000000000000000000000000000000000000000001a
Arg [5] : 496465786f2047656e6572616c205374616b696e6720506f6f6c000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [7] : 4947535000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

66829:10465:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68178:37;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;9095:32:1;;;9077:51;;9159:2;9144:18;;9137:34;;;;9187:18;;;9180:34;9065:2;9050:18;68178:37:0;;;;;;;;69357:243;;;;;;:::i;:::-;;:::i;:::-;;;10452:14:1;;10445:22;10427:41;;10415:2;10400:18;69357:243:0;10382:92:1;67081:41:0;;67115:7;67081:41;;;;;10625:25:1;;;10613:2;10598:18;67081:41:0;10580:76:1;38209:100:0;;;:::i;:::-;;;;;;;:::i;39669:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7679:32:1;;;7661:51;;7649:2;7634:18;39669:221:0;7616:102:1;39206:397:0;;;;;;:::i;:::-;;:::i;:::-;;61969:340;;;;;;:::i;:::-;;:::i;:::-;;;;27792:25:1;;;27848:2;27833:18;;27826:34;;;;27876:18;;;27869:34;27780:2;27765:18;61969:340:0;27747:162:1;61113:384:0;;;;;;:::i;:::-;;:::i;67292:47::-;;67337:2;67292:47;;68083:55;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;9474:32:1;;;9456:51;;9538:2;9523:18;;9516:34;;;;9566:18;;;9559:34;9624:2;9609:18;;9602:34;9443:3;9428:19;68083:55:0;9410:232:1;74157:241:0;;;;;;:::i;:::-;;:::i;40559:305::-;;;;;;:::i;:::-;;:::i;24243:123::-;;;;;;:::i;:::-;24309:7;24336:12;;;:6;:12;;;;;:22;;;;24243:123;24628:147;;;;;;:::i;:::-;;:::i;25676:218::-;;;;;;:::i;:::-;;:::i;40935:151::-;;;;;;:::i;:::-;;:::i;72221:257::-;;;;;;:::i;:::-;;:::i;60843:192::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;60471:46::-;;;;;;:::i;:::-;;:::i;76407:323::-;;;;;;:::i;:::-;;:::i;37903:239::-;;;;;;:::i;:::-;;:::i;37633:208::-;;;;;;:::i;:::-;;:::i;60153:23::-;;;;;;50740:148;;;:::i;60183:51::-;;60231:3;60183:51;;67238:47;;67283:2;67238:47;;67129:39;;67160:8;67129:39;;75840:482;;;;;;:::i;:::-;;:::i;74794:178::-;;;;;;:::i;:::-;74905:7;74938:25;;;:16;:25;;;;;;;74794:178;50089:87;50162:6;;-1:-1:-1;;;;;50162:6:0;50089:87;;23241:139;;;;;;:::i;:::-;;:::i;75330:290::-;;;;;;:::i;:::-;;:::i;38378:104::-;;;:::i;68293:51::-;;;;;;:::i;:::-;;;;;;;;;;;;;;70273:320;;;;;;:::i;:::-;;:::i;21206:49::-;;21251:4;21206:49;;39962:295;;;;;;:::i;:::-;;:::i;70706:314::-;;;;;;:::i;:::-;;:::i;75056:185::-;;;;;;:::i;:::-;;:::i;74471:250::-;;;;;;:::i;:::-;;:::i;71608:230::-;;;;;;:::i;:::-;;:::i;41157:285::-;;;;;;:::i;:::-;;:::i;62486:664::-;;;;;;:::i;:::-;;:::i;38553:360::-;;;;;;:::i;:::-;;:::i;67586:26::-;;;;;-1:-1:-1;;;;;67586:26:0;;;67490:53;;67539:4;67490:53;;61614:176;;;;;;:::i;:::-;;:::i;25020:149::-;;;;;;:::i;:::-;;:::i;67035:39::-;;67067:7;67035:39;;60385;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;71150:190;;;;;;:::i;:::-;;:::i;40328:164::-;;;;;;:::i;:::-;-1:-1:-1;;;;;40449:25:0;;;40425:4;40449:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;40328:164;67743:25;;;;;;67429:52;;67470:11;67429:52;;51043:244;;;;;;:::i;:::-;;:::i;66962:66::-;;-1:-1:-1;;;;;;;;;;;66962:66:0;;67652:25;;;;;-1:-1:-1;;;;;67652:25:0;;;68178:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68178:37:0;;;;-1:-1:-1;68178:37:0;:::o;69357:243::-;69527:4;69556:36;69580:11;69556:23;:36::i;:::-;69549:43;69357:243;-1:-1:-1;;69357:243:0:o;38209:100::-;38263:13;38296:5;38289:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38209:100;:::o;39669:221::-;39745:7;39773:16;39781:7;39773;:16::i;:::-;39765:73;;;;-1:-1:-1;;;39765:73:0;;21317:2:1;39765:73:0;;;21299:21:1;21356:2;21336:18;;;21329:30;21395:34;21375:18;;;21368:62;-1:-1:-1;;;21446:18:1;;;21439:42;21498:19;;39765:73:0;;;;;;;;;-1:-1:-1;39858:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;39858:24:0;;39669:221::o;39206:397::-;39287:13;39303:23;39318:7;39303:14;:23::i;:::-;39287:39;;39351:5;-1:-1:-1;;;;;39345:11:0;:2;-1:-1:-1;;;;;39345:11:0;;;39337:57;;;;-1:-1:-1;;;39337:57:0;;22917:2:1;39337:57:0;;;22899:21:1;22956:2;22936:18;;;22929:30;22995:34;22975:18;;;22968:62;-1:-1:-1;;;23046:18:1;;;23039:31;23087:19;;39337:57:0;22889:223:1;39337:57:0;15061:10;-1:-1:-1;;;;;39415:21:0;;;;:62;;-1:-1:-1;39440:37:0;39457:5;15061:10;40328:164;:::i;39440:37::-;39407:154;;;;-1:-1:-1;;;39407:154:0;;18885:2:1;39407:154:0;;;18867:21:1;18924:2;18904:18;;;18897:30;18963:34;18943:18;;;18936:62;19034:26;19014:18;;;19007:54;19078:19;;39407:154:0;18857:246:1;39407:154:0;39574:21;39583:2;39587:7;39574:8;:21::i;:::-;39206:397;;;:::o;61969:340::-;62090:7;62099;62108;62141:16;62149:7;62141;:16::i;:::-;62133:69;;;;-1:-1:-1;;;62133:69:0;;18476:2:1;62133:69:0;;;18458:21:1;18515:2;18495:18;;;18488:30;18554:34;18534:18;;;18527:62;-1:-1:-1;;;18605:18:1;;;18598:38;18653:19;;62133:69:0;18448:230:1;62133:69:0;-1:-1:-1;;;62221:15:0;;;;:6;:15;;;;;:22;;62245:26;;;;62273:27;;;;;62221:22;;61969:340::o;61113:384::-;-1:-1:-1;;;;;61273:18:0;;61220:7;61273:18;;;:9;:18;;;;;;;;61245:46;;;;;;;;;;;;;;;;;61220:7;;61245:46;;61273:18;61245:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61302:24;61342:9;61354:1;61342:13;;61337:119;61361:8;:15;61357:1;:19;61337:119;;;61418:6;:19;61425:8;61434:1;61425:11;;;;;;-1:-1:-1;;;61425:11:0;;;;;;;;;;;;;;;61418:19;;;;;;;;;;;:26;;;61398:46;;;;;:::i;:::-;;-1:-1:-1;61378:3:0;;;;:::i;:::-;;;;61337:119;;;-1:-1:-1;61473:16:0;61113:384;-1:-1:-1;;;61113:384:0:o;68083:55::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;68083:55:0;;;;-1:-1:-1;68083:55:0;;;:::o;74157:241::-;70046:34;-1:-1:-1;;;;;;;;;;;70069:10:0;70046:7;:34::i;:::-;70038:94;;;;-1:-1:-1;;;70038:94:0;;;;;;;:::i;:::-;74303:1:::1;74294:6;:10;74286:59;;;::::0;-1:-1:-1;;;74286:59:0;;12515:2:1;74286:59:0::1;::::0;::::1;12497:21:1::0;12554:2;12534:18;;;12527:30;12593:34;12573:18;;;12566:62;-1:-1:-1;;;12644:18:1;;;12637:34;12688:19;;74286:59:0::1;12487:226:1::0;74286:59:0::1;74356:34;74371:10;74383:6;74356:14;:34::i;:::-;74157:241:::0;:::o;40559:305::-;40720:41;15061:10;40753:7;40720:18;:41::i;:::-;40712:103;;;;-1:-1:-1;;;40712:103:0;;;;;;;:::i;:::-;40828:28;40838:4;40844:2;40848:7;40828:9;:28::i;24628:147::-;24309:7;24336:12;;;:6;:12;;;;;:22;;;22810:30;22821:4;15061:10;22810;:30::i;:::-;24742:25:::1;24753:4;24759:7;24742:10;:25::i;25676:218::-:0;-1:-1:-1;;;;;25772:23:0;;15061:10;25772:23;25764:83;;;;-1:-1:-1;;;25764:83:0;;26941:2:1;25764:83:0;;;26923:21:1;26980:2;26960:18;;;26953:30;27019:34;26999:18;;;26992:62;-1:-1:-1;;;27070:18:1;;;27063:45;27125:19;;25764:83:0;26913:237:1;25764:83:0;25860:26;25872:4;25878:7;25860:11;:26::i;:::-;25676:218;;:::o;40935:151::-;41039:39;41056:4;41062:2;41066:7;41039:39;;;;;;;;;;;;:16;:39::i;72221:257::-;72366:1;72357:6;:10;72349:72;;;;-1:-1:-1;;;72349:72:0;;25746:2:1;72349:72:0;;;25728:21:1;25785:2;25765:18;;;25758:30;25824:34;25804:18;;;25797:62;-1:-1:-1;;;25875:18:1;;;25868:47;25932:19;;72349:72:0;25718:239:1;72349:72:0;72432:38;72442:10;72454:7;72463:6;72432:9;:38::i;60843:192::-;-1:-1:-1;;;;;61009:18:0;;;;;;:9;:18;;;;;;;;;61002:25;;;;;;;;;;;;;;;;;60968:16;;61002:25;;;61009:18;61002:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60843:192;;;:::o;60471:46::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;76407:323::-;70046:34;-1:-1:-1;;;;;;;;;;;70069:10:0;70046:7;:34::i;:::-;70038:94;;;;-1:-1:-1;;;70038:94:0;;;;;;;:::i;:::-;76643:26:::1;::::0;-1:-1:-1;;;76643:26:0;;-1:-1:-1;;;;;8788:32:1;;;76643:26:0::1;::::0;::::1;8770:51:1::0;8837:18;;;8830:34;;;76576:6:0;;76643:14;;::::1;::::0;::::1;::::0;8743:18:1;;76643:26:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;76685:37:0::1;::::0;;-1:-1:-1;;;;;8788:32:1;;;8770:51;;8852:2;8837:18;;8830:34;;;76685:37:0;::::1;::::0;76691:10:::1;::::0;76685:37:::1;::::0;8743:18:1;76685:37:0::1;;;;;;;70143:1;76407:323:::0;;;:::o;37903:239::-;37975:7;38011:16;;;:7;:16;;;;;;-1:-1:-1;;;;;38011:16:0;38046:19;38038:73;;;;-1:-1:-1;;;38038:73:0;;19721:2:1;38038:73:0;;;19703:21:1;19760:2;19740:18;;;19733:30;19799:34;19779:18;;;19772:62;-1:-1:-1;;;19850:18:1;;;19843:39;19899:19;;38038:73:0;19693:231:1;37633:208:0;37705:7;-1:-1:-1;;;;;37733:19:0;;37725:74;;;;-1:-1:-1;;;37725:74:0;;19310:2:1;37725:74:0;;;19292:21:1;19349:2;19329:18;;;19322:30;19388:34;19368:18;;;19361:62;-1:-1:-1;;;19439:18:1;;;19432:40;19489:19;;37725:74:0;19282:232:1;37725:74:0;-1:-1:-1;;;;;;37817:16:0;;;;;:9;:16;;;;;;;37633:208::o;50740:148::-;50162:6;;-1:-1:-1;;;;;50162:6:0;15061:10;50309:23;50301:68;;;;-1:-1:-1;;;50301:68:0;;21730:2:1;50301:68:0;;;21712:21:1;;;21749:18;;;21742:30;21808:34;21788:18;;;21781:62;21860:18;;50301:68:0;21702:182:1;50301:68:0;50831:6:::1;::::0;50810:40:::1;::::0;50847:1:::1;::::0;-1:-1:-1;;;;;50831:6:0::1;::::0;50810:40:::1;::::0;50847:1;;50810:40:::1;50861:6;:19:::0;;-1:-1:-1;;;;;;50861:19:0::1;::::0;;50740:148::o;75840:482::-;29049:1;29646:7;;:19;;29638:63;;;;-1:-1:-1;;;29638:63:0;;;;;;;:::i;:::-;29049:1;29779:7;:18;76004:10:::1;75984:16;75992:7:::0;75984::::1;:16::i;:::-;-1:-1:-1::0;;;;;75984:30:0::1;;75975:89;;;::::0;-1:-1:-1;;;75975:89:0;;20131:2:1;75975:89:0::1;::::0;::::1;20113:21:1::0;20170:2;20150:18;;;20143:30;20209:34;20189:18;;;20182:62;-1:-1:-1;;;20260:18:1;;;20253:42;20312:19;;75975:89:0::1;20103:234:1::0;75975:89:0::1;76083:25;::::0;;;:16:::1;:25;::::0;;;;;:35;-1:-1:-1;76083:35:0::1;76075:89;;;::::0;-1:-1:-1;;;76075:89:0;;24511:2:1;76075:89:0::1;::::0;::::1;24493:21:1::0;24550:2;24530:18;;;24523:30;24589:34;24569:18;;;24562:62;-1:-1:-1;;;24640:18:1;;;24633:39;24689:19;;76075:89:0::1;24483:231:1::0;76075:89:0::1;76175:25;::::0;;;:16:::1;:25;::::0;;;;:35;;76204:6;;76175:25;:35:::1;::::0;76204:6;;76175:35:::1;:::i;:::-;::::0;;;-1:-1:-1;;76221:11:0::1;::::0;:44:::1;::::0;-1:-1:-1;;;;;76221:11:0::1;76246:10;76258:6:::0;76221:24:::1;:44::i;:::-;76281:33;::::0;10625:25:1;;;76295:10:0::1;::::0;76281:33:::1;::::0;10613:2:1;10598:18;76281:33:0::1;;;;;;;-1:-1:-1::0;;29005:1:0;29958:7;:22;75840:482::o;23241:139::-;23319:4;23343:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;23343:29:0;;;;;;;;;;;;;;;23241:139::o;75330:290::-;70046:34;-1:-1:-1;;;;;;;;;;;70069:10:0;70046:7;:34::i;:::-;70038:94;;;;-1:-1:-1;;;70038:94:0;;;;;;;:::i;:::-;75502:9:::1;75497:116;75517:19:::0;;::::1;75497:116;;;75591:7;;75599:1;75591:10;;;;;-1:-1:-1::0;;;75591:10:0::1;;;;;;;;;;;;;;;75558:16;:29;75575:8;;75584:1;75575:11;;;;;-1:-1:-1::0;;;75575:11:0::1;;;;;;;;;;;;;;;75558:29;;;;;;;;;;;;:43;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;75538:3:0;;-1:-1:-1;75538:3:0::1;::::0;::::1;:::i;:::-;;;;75497:116;;;;75330:290:::0;;;;:::o;38378:104::-;38434:13;38467:7;38460:14;;;;;:::i;70273:320::-;69815:39;21251:4;69843:10;69815:7;:39::i;:::-;69807:93;;;;-1:-1:-1;;;69807:93:0;;;;;;;:::i;:::-;70462:31:::1;-1:-1:-1::0;;;;;;;;;;;70485:7:0::1;70462;:31::i;:::-;70461:32;70453:88;;;::::0;-1:-1:-1;;;70453:88:0;;20544:2:1;70453:88:0::1;::::0;::::1;20526:21:1::0;20583:2;20563:18;;;20556:30;20622:34;20602:18;;;20595:62;-1:-1:-1;;;20673:18:1;;;20666:41;20724:19;;70453:88:0::1;20516:233:1::0;70453:88:0::1;70552:33;-1:-1:-1::0;;;;;;;;;;;70577:7:0::1;70552:9;:33::i;39962:295::-:0;-1:-1:-1;;;;;40065:24:0;;15061:10;40065:24;;40057:62;;;;-1:-1:-1;;;40057:62:0;;16892:2:1;40057:62:0;;;16874:21:1;16931:2;16911:18;;;16904:30;16970:27;16950:18;;;16943:55;17015:18;;40057:62:0;16864:175:1;40057:62:0;15061:10;40132:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;40132:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;40132:53:0;;;;;;;;;;40201:48;;10427:41:1;;;40132:42:0;;15061:10;40201:48;;10400:18:1;40201:48:0;;;;;;;39962:295;;:::o;70706:314::-;69815:39;21251:4;69843:10;69815:7;:39::i;:::-;69807:93;;;;-1:-1:-1;;;69807:93:0;;;;;;;:::i;:::-;70889:31:::1;-1:-1:-1::0;;;;;;;;;;;70912:7:0::1;70889;:31::i;:::-;70881:86;;;::::0;-1:-1:-1;;;70881:86:0;;14908:2:1;70881:86:0::1;::::0;::::1;14890:21:1::0;14947:2;14927:18;;;14920:30;14986:34;14966:18;;;14959:62;-1:-1:-1;;;15037:18:1;;;15030:40;15087:19;;70881:86:0::1;14880:232:1::0;70881:86:0::1;70978:34;-1:-1:-1::0;;;;;;;;;;;71004:7:0::1;70978:10;:34::i;75056:185::-:0;70046:34;-1:-1:-1;;;;;;;;;;;70069:10:0;70046:7;:34::i;:::-;70038:94;;;;-1:-1:-1;;;70038:94:0;;;;;;;:::i;:::-;75198:25:::1;::::0;;;:16:::1;:25;::::0;;;;:35;;75227:6;;75198:25;:35:::1;::::0;75227:6;;75198:35:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;75056:185:0:o;74471:250::-;74575:7;74584;74593;74626:14;74641:2;74626:18;;;;;;-1:-1:-1;;;74626:18:0;;;;;;;;;;;;;;;;;;;;;;:27;74655:14;:18;;-1:-1:-1;;;;;74626:27:0;;;;74670:2;;74655:18;;;;-1:-1:-1;;;74655:18:0;;;;;;;;;;;;;;;;;;;:25;;;74682:14;74697:2;74682:18;;;;;;-1:-1:-1;;;74682:18:0;;;;;;;;;;;;;;;;;;;:30;;;74618:95;;;;;;74471:250;;;;;:::o;71608:230::-;67470:11;71717:6;:24;;71709:82;;;;-1:-1:-1;;;71709:82:0;;24921:2:1;71709:82:0;;;24903:21:1;24960:2;24940:18;;;24933:30;24999:34;24979:18;;;24972:62;-1:-1:-1;;;25050:18:1;;;25043:43;25103:19;;71709:82:0;24893:235:1;71709:82:0;71802:28;71811:10;71823:6;71802:8;:28::i;41157:285::-;41289:41;15061:10;41322:7;41289:18;:41::i;:::-;41281:103;;;;-1:-1:-1;;;41281:103:0;;;;;;;:::i;:::-;41395:39;41409:4;41415:2;41419:7;41428:5;41395:13;:39::i;:::-;41157:285;;;;:::o;62486:664::-;62618:7;62663:15;62651:8;:27;;62643:87;;;;-1:-1:-1;;;62643:87:0;;13327:2:1;62643:87:0;;;13309:21:1;13366:2;13346:18;;;13339:30;13405:34;13385:18;;;13378:62;-1:-1:-1;;;13456:18:1;;;13449:45;13511:19;;62643:87:0;13299:237:1;62643:87:0;62741:20;62791:1;62774:337;62799:8;;62794:1;:13;62774:337;;62833:10;62841:1;62833:7;:10::i;:::-;62829:271;;;62864:18;62885:9;;;:6;:9;;;;;;;;;62864:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62917:28;-1:-1:-1;62913:82:0;;;62970:5;;;62913:82;63044:16;;;;63029:12;;60231:3;;63029:31;;;:::i;:::-;:55;;;;:::i;:::-;63013:71;;;;:::i;:::-;;;62829:271;;62809:3;;;;:::i;:::-;;;;62774:337;;;-1:-1:-1;63130:12:0;62486:664;-1:-1:-1;;62486:664:0:o;38553:360::-;38626:13;38660:16;38668:7;38660;:16::i;:::-;38652:76;;;;-1:-1:-1;;;38652:76:0;;22501:2:1;38652:76:0;;;22483:21:1;22540:2;22520:18;;;22513:30;22579:34;22559:18;;;22552:62;-1:-1:-1;;;22630:18:1;;;22623:45;22685:19;;38652:76:0;22473:237:1;38652:76:0;38741:21;38765:10;39127:9;;;;;;;;;-1:-1:-1;39127:9:0;;;39050:94;38765:10;38741:34;;38817:1;38799:7;38793:21;:25;:112;;;;;;;;;;;;;;;;;38858:7;38867:18;:7;:16;:18::i;:::-;38841:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;38793:112;38786:119;38553:360;-1:-1:-1;;;38553:360:0:o;61614:176::-;61731:4;61781:1;61760:18;61770:7;61760:9;:18::i;:::-;:22;;61614:176;-1:-1:-1;;61614:176:0:o;25020:149::-;24309:7;24336:12;;;:6;:12;;;;;:22;;;22810:30;22821:4;15061:10;22810;:30::i;:::-;25135:26:::1;25147:4;25153:7;25135:11;:26::i;71150:190::-:0;71272:4;71301:31;-1:-1:-1;;;;;;;;;;;71324:7:0;71301;:31::i;51043:244::-;50162:6;;-1:-1:-1;;;;;50162:6:0;15061:10;50309:23;50301:68;;;;-1:-1:-1;;;50301:68:0;;21730:2:1;50301:68:0;;;21712:21:1;;;21749:18;;;21742:30;21808:34;21788:18;;;21781:62;21860:18;;50301:68:0;21702:182:1;50301:68:0;-1:-1:-1;;;;;51132:22:0;::::1;51124:73;;;::::0;-1:-1:-1;;;51124:73:0;;12920:2:1;51124:73:0::1;::::0;::::1;12902:21:1::0;12959:2;12939:18;;;12932:30;12998:34;12978:18;;;12971:62;-1:-1:-1;;;13049:18:1;;;13042:36;13095:19;;51124:73:0::1;12892:228:1::0;51124:73:0::1;51234:6;::::0;51213:38:::1;::::0;-1:-1:-1;;;;;51213:38:0;;::::1;::::0;51234:6:::1;::::0;51213:38:::1;::::0;51234:6:::1;::::0;51213:38:::1;51262:6;:17:::0;;-1:-1:-1;;;;;;51262:17:0::1;-1:-1:-1::0;;;;;51262:17:0;;;::::1;::::0;;;::::1;::::0;;51043:244::o;22932:217::-;23017:4;-1:-1:-1;;;;;;23041:47:0;;-1:-1:-1;;;23041:47:0;;:100;;;23105:36;23129:11;23105:23;:36::i;42909:127::-;42974:4;42998:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42998:16:0;:30;;;42909:127::o;46786:174::-;46861:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;46861:29:0;-1:-1:-1;;;;;46861:29:0;;;;;;;;:24;;46915:23;46861:24;46915:14;:23::i;:::-;-1:-1:-1;;;;;46906:46:0;;;;;;;;;;;46786:174;;:::o;76892:393::-;77007:11;;:60;;-1:-1:-1;;;;;77007:11:0;77036:7;77053:4;77060:6;77007:28;:60::i;:::-;77098:130;;;;;;;;-1:-1:-1;;;;;77098:130:0;;;;;;;;;;;;;77201:15;77098:130;;;;;;77078:14;:151;;;;;;;-1:-1:-1;77078:151:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;77078:151:0;;;;;;;;;;;;;;;;;;;;;;;;77245:32;;10625:25:1;;;77098:130:0;;77245:32;;10598:18:1;77245:32:0;;;;;;;76892:393;;:::o;43203:348::-;43296:4;43321:16;43329:7;43321;:16::i;:::-;43313:73;;;;-1:-1:-1;;;43313:73:0;;17653:2:1;43313:73:0;;;17635:21:1;17692:2;17672:18;;;17665:30;17731:34;17711:18;;;17704:62;-1:-1:-1;;;17782:18:1;;;17775:42;17834:19;;43313:73:0;17625:234:1;43313:73:0;43397:13;43413:23;43428:7;43413:14;:23::i;:::-;43397:39;;43466:5;-1:-1:-1;;;;;43455:16:0;:7;-1:-1:-1;;;;;43455:16:0;;:51;;;;43499:7;-1:-1:-1;;;;;43475:31:0;:20;43487:7;43475:11;:20::i;:::-;-1:-1:-1;;;;;43475:31:0;;43455:51;:87;;;-1:-1:-1;;;;;;40449:25:0;;;40425:4;40449:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;43510:32;43447:96;43203:348;-1:-1:-1;;;;43203:348:0:o;46124:544::-;46249:4;-1:-1:-1;;;;;46222:31:0;:23;46237:7;46222:14;:23::i;:::-;-1:-1:-1;;;;;46222:31:0;;46214:85;;;;-1:-1:-1;;;46214:85:0;;22091:2:1;46214:85:0;;;22073:21:1;22130:2;22110:18;;;22103:30;22169:34;22149:18;;;22142:62;-1:-1:-1;;;22220:18:1;;;22213:39;22269:19;;46214:85:0;22063:231:1;46214:85:0;-1:-1:-1;;;;;46318:16:0;;46310:65;;;;-1:-1:-1;;;46310:65:0;;16487:2:1;46310:65:0;;;16469:21:1;16526:2;16506:18;;;16499:30;16565:34;16545:18;;;16538:62;-1:-1:-1;;;16616:18:1;;;16609:34;16660:19;;46310:65:0;16459:226:1;46310:65:0;46492:29;46509:1;46513:7;46492:8;:29::i;:::-;-1:-1:-1;;;;;46534:15:0;;;;;;:9;:15;;;;;:20;;46553:1;;46534:15;:20;;46553:1;;46534:20;:::i;:::-;;;;-1:-1:-1;;;;;;;46565:13:0;;;;;;:9;:13;;;;;:18;;46582:1;;46565:13;:18;;46582:1;;46565:18;:::i;:::-;;;;-1:-1:-1;;46594:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;46594:21:0;-1:-1:-1;;;;;46594:21:0;;;;;;;;;46633:27;;46594:16;;46633:27;;;;;;;46124:544;;;:::o;23670:384::-;23750:22;23758:4;23764:7;23750;:22::i;:::-;23746:301;;23882:41;23910:7;-1:-1:-1;;;;;23882:41:0;23920:2;23882:19;:41::i;:::-;23980:38;24008:4;24015:2;23980:19;:38::i;:::-;23803:230;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;23803:230:0;;;;;;;;;;-1:-1:-1;;;23789:246:0;;;;;;;:::i;26924:229::-;26999:22;27007:4;27013:7;26999;:22::i;:::-;26994:152;;27038:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;27038:29:0;;;;;;;;;:36;;-1:-1:-1;;27038:36:0;27070:4;27038:36;;;27121:12;15061:10;;14981:98;27121:12;-1:-1:-1;;;;;27094:40:0;27112:7;-1:-1:-1;;;;;27094:40:0;27106:4;27094:40;;;;;;;;;;26924:229;;:::o;27161:230::-;27236:22;27244:4;27250:7;27236;:22::i;:::-;27232:152;;;27307:5;27275:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;27275:29:0;;;;;;;;;;:37;;-1:-1:-1;;27275:37:0;;;27332:40;15061:10;;27275:12;;27332:40;;27307:5;27332:40;27161:230;;:::o;73413:472::-;29049:1;29646:7;;:19;;29638:63;;;;-1:-1:-1;;;29638:63:0;;;;;;;:::i;:::-;29049:1;29779:7;:18;-1:-1:-1;;;;;73587:27:0;::::1;:16;73595:7:::0;73587::::1;:16::i;:::-;-1:-1:-1::0;;;;;73587:27:0::1;;73579:75;;;::::0;-1:-1:-1;;;73579:75:0;;13743:2:1;73579:75:0::1;::::0;::::1;13725:21:1::0;13782:2;13762:18;;;13755:30;13821:34;13801:18;;;13794:62;-1:-1:-1;;;13872:18:1;;;13865:33;13915:19;;73579:75:0::1;13715:225:1::0;73579:75:0::1;73665:45;73686:7;73695:14;73665:20;:45::i;:::-;73729:12;::::0;:46:::1;::::0;-1:-1:-1;;;73729:46:0;;-1:-1:-1;;;;;8788:32:1;;;73729:46:0::1;::::0;::::1;8770:51:1::0;8837:18;;;8830:34;;;73729:12:0;;::::1;::::0;:21:::1;::::0;8743:18:1;;73729:46:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73721:95;;;::::0;-1:-1:-1;;;73721:95:0;;15680:2:1;73721:95:0::1;::::0;::::1;15662:21:1::0;15719:2;15699:18;;;15692:30;15758:34;15738:18;;;15731:62;-1:-1:-1;;;15809:18:1;;;15802:34;15853:19;;73721:95:0::1;15652:226:1::0;73721:95:0::1;73853:7;73844;-1:-1:-1::0;;;;;73834:43:0::1;;73862:14;73834:43;;;;10625:25:1::0;;10613:2;10598:18;;10580:76;73834:43:0::1;;;;;;;;-1:-1:-1::0;;29005:1:0;29958:7;:22;-1:-1:-1;73413:472:0:o;11240:177::-;11350:58;;-1:-1:-1;;;;;8788:32:1;;11350:58:0;;;8770:51:1;8837:18;;;8830:34;;;11323:86:0;;11343:5;;-1:-1:-1;;;11373:23:0;8743:18:1;;11350:58:0;;;;-1:-1:-1;;11350:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;11350:58:0;-1:-1:-1;;;;;;11350:58:0;;;;;;;;;;11323:19;:86::i;72627:365::-;29049:1;29646:7;;:19;;29638:63;;;;-1:-1:-1;;;29638:63:0;;;;;;;:::i;:::-;29049:1;29779:7;:18;72758:15:::1;72776:39;72782:7:::0;72791:6;72799:15:::1;72776:5;:39::i;:::-;72834:12;::::0;:57:::1;::::0;-1:-1:-1;;;72834:57:0;;-1:-1:-1;;;;;7981:15:1;;;72834:57:0::1;::::0;::::1;7963:34:1::0;72877:4:0::1;8013:18:1::0;;;8006:43;8065:18;;;8058:34;;;72758:57:0;;-1:-1:-1;72834:12:0;::::1;::::0;:25:::1;::::0;7898:18:1;;72834:57:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;72826:105;;;::::0;-1:-1:-1;;;72826:105:0;;14147:2:1;72826:105:0::1;::::0;::::1;14129:21:1::0;14186:2;14166:18;;;14159:30;14225:34;14205:18;;;14198:62;-1:-1:-1;;;14276:18:1;;;14269:33;14319:19;;72826:105:0::1;14119:225:1::0;72826:105:0::1;72968:7;72959;-1:-1:-1::0;;;;;72949:35:0::1;;72977:6;72949:35;;;;10625:25:1::0;;10613:2;10598:18;;10580:76;42324:272:0;42438:28;42448:4;42454:2;42458:7;42438:9;:28::i;:::-;42485:48;42508:4;42514:2;42518:7;42527:5;42485:22;:48::i;:::-;42477:111;;;;-1:-1:-1;;;42477:111:0;;;;;;;:::i;15551:723::-;15607:13;15828:10;15824:53;;-1:-1:-1;;15855:10:0;;;;;;;;;;;;-1:-1:-1;;;15855:10:0;;;;;15551:723::o;15824:53::-;15902:5;15887:12;15943:78;15950:9;;15943:78;;15976:8;;;;:::i;:::-;;-1:-1:-1;15999:10:0;;-1:-1:-1;16007:2:0;15999:10;;:::i;:::-;;;15943:78;;;16031:19;16063:6;16053:17;;;;;;-1:-1:-1;;;16053:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16053:17:0;;16031:39;;16081:154;16088:10;;16081:154;;16115:11;16125:1;16115:11;;:::i;:::-;;-1:-1:-1;16184:10:0;16192:2;16184:5;:10;:::i;:::-;16171:24;;:2;:24;:::i;:::-;16158:39;;16141:6;16148;16141:14;;;;;;-1:-1:-1;;;16141:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;16141:56:0;;;;;;;;-1:-1:-1;16212:11:0;16221:2;16212:11;;:::i;:::-;;;16081:154;;37277:292;37379:4;-1:-1:-1;;;;;;37403:40:0;;-1:-1:-1;;;37403:40:0;;:105;;-1:-1:-1;;;;;;;37460:48:0;;-1:-1:-1;;;37460:48:0;37403:105;:158;;;-1:-1:-1;;;;;;;;;;18865:40:0;;;37525:36;18756:157;11425:205;11553:68;;-1:-1:-1;;;;;7981:15:1;;;11553:68:0;;;7963:34:1;8033:15;;8013:18;;;8006:43;8065:18;;;8058:34;;;11526:96:0;;11546:5;;-1:-1:-1;;;11576:27:0;7898:18:1;;11553:68:0;7880:218:1;16852:447:0;16927:13;16953:19;16985:10;16989:6;16985:1;:10;:::i;:::-;:14;;16998:1;16985:14;:::i;:::-;16975:25;;;;;;-1:-1:-1;;;16975:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16975:25:0;;16953:47;;-1:-1:-1;;;17011:6:0;17018:1;17011:9;;;;;;-1:-1:-1;;;17011:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;17011:15:0;;;;;;;;;-1:-1:-1;;;17037:6:0;17044:1;17037:9;;;;;;-1:-1:-1;;;17037:9:0;;;;;;;;;;;;:15;-1:-1:-1;;;;;17037:15:0;;;;;;;;-1:-1:-1;17068:9:0;17080:10;17084:6;17080:1;:10;:::i;:::-;:14;;17093:1;17080:14;:::i;:::-;17068:26;;17063:131;17100:1;17096;:5;17063:131;;;-1:-1:-1;;;17144:5:0;17152:3;17144:11;17135:21;;;;;-1:-1:-1;;;17135:21:0;;;;;;;;;;;;17123:6;17130:1;17123:9;;;;;;-1:-1:-1;;;17123:9:0;;;;;;;;;;;;:33;-1:-1:-1;;;;;17123:33:0;;;;;;;;-1:-1:-1;17181:1:0;17171:11;;;;;17103:3;;;:::i;:::-;;;17063:131;;;-1:-1:-1;17212:10:0;;17204:55;;;;-1:-1:-1;;;17204:55:0;;11308:2:1;17204:55:0;;;11290:21:1;;;11327:18;;;11320:30;11386:34;11366:18;;;11359:62;11438:18;;17204:55:0;11280:182:1;65671:576:0;65818:16;65826:7;65818;:16::i;:::-;65810:77;;;;-1:-1:-1;;;65810:77:0;;26524:2:1;65810:77:0;;;26506:21:1;26563:2;26543:18;;;26536:30;26602:34;26582:18;;;26575:62;-1:-1:-1;;;26653:18:1;;;26646:46;26709:19;;65810:77:0;26496:238:1;65810:77:0;65916:15;;;;:6;:15;;;;;:22;65906:32;;;65898:103;;;;-1:-1:-1;;;65898:103:0;;11669:2:1;65898:103:0;;;11651:21:1;11708:2;11688:18;;;11681:30;11747:34;11727:18;;;11720:62;11818:28;11798:18;;;11791:56;11864:19;;65898:103:0;11641:248:1;65898:103:0;66026:15;;;;:6;:15;;;;;:22;66016:32;;66012:228;;;66065:14;66071:7;66065:5;:14::i;66012:228::-;66137:15;;;;:6;:15;;;;;:22;:34;;66164:6;66137:26;:34::i;:::-;66112:15;;;;:6;:15;;;;;;;;;:59;;;;66191:37;;27511:25:1;;;27552:18;;;27545:34;;;66191:37:0;;27484:18:1;66191:37:0;;;;;;;65671:576;;:::o;13674:761::-;14098:23;14124:69;14152:4;14124:69;;;;;;;;;;;;;;;;;14132:5;-1:-1:-1;;;;;14124:27:0;;;:69;;;;;:::i;:::-;14208:17;;14098:95;;-1:-1:-1;14208:21:0;14204:224;;14350:10;14339:30;;;;;;;;;;;;:::i;:::-;14331:85;;;;-1:-1:-1;;;14331:85:0;;25335:2:1;14331:85:0;;;25317:21:1;25374:2;25354:18;;;25347:30;25413:34;25393:18;;;25386:62;-1:-1:-1;;;25464:18:1;;;25457:40;25514:19;;14331:85:0;25307:232:1;63958:601:0;64114:7;64156:1;64147:6;:10;64139:55;;;;-1:-1:-1;;;64139:55:0;;15319:2:1;64139:55:0;;;15301:21:1;;;15338:18;;;15331:30;15397:34;15377:18;;;15370:62;15449:18;;64139:55:0;15291:182:1;64139:55:0;64205:8;:10;;;:8;:10;;;:::i;:::-;;;;;;64226:18;64247:16;:14;:16::i;:::-;64226:37;;64274:30;64286:7;64295:8;;64274:11;:30::i;:::-;64347:8;;;64315:22;64340:16;;;:6;:16;;;;;;;;64367:24;;;64402:19;;;;:32;;;;64445:20;;:34;;;-1:-1:-1;;;;;64490:18:0;;;;:9;:18;;;;64514:8;;64490:33;;;;;;;;;;;;;;;;;;;64543:8;;-1:-1:-1;63958:601:0;;;;;:::o;47525:843::-;47646:4;-1:-1:-1;;;;;47672:13:0;;3822:20;3861:8;47668:693;;47708:72;;-1:-1:-1;;;47708:72:0;;-1:-1:-1;;;;;47708:36:0;;;;;:72;;15061:10;;47759:4;;47765:7;;47774:5;;47708:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47708:72:0;;;;;;;;-1:-1:-1;;47708:72:0;;;;;;;;;;;;:::i;:::-;;;47704:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47954:13:0;;47950:341;;47997:60;;-1:-1:-1;;;47997:60:0;;;;;;;:::i;47950:341::-;48241:6;48235:13;48226:6;48222:2;48218:15;48211:38;47704:602;-1:-1:-1;;;;;;47831:55:0;-1:-1:-1;;;47831:55:0;;-1:-1:-1;47824:62:0;;47668:693;-1:-1:-1;48345:4:0;47525:843;;;;;;:::o;64733:660::-;64841:16;64849:7;64841;:16::i;:::-;64833:62;;;;-1:-1:-1;;;64833:62:0;;16085:2:1;64833:62:0;;;16067:21:1;16124:2;16104:18;;;16097:30;16163:34;16143:18;;;16136:62;-1:-1:-1;;;16214:18:1;;;16207:31;16255:19;;64833:62:0;16057:223:1;64833:62:0;64906:18;64927:16;64935:7;64927;:16::i;:::-;64906:37;;64954:20;64966:7;64954:11;:20::i;:::-;64992:15;;;;:6;:15;;;;;;;;64985:22;;;;;;;;;;;;;;-1:-1:-1;;;;;65047:21:0;;;;:9;:21;;;;;;65079:307;65103:15;;65099:19;;65079:307;;;65159:7;65144:8;65153:1;65144:11;;;;;;-1:-1:-1;;;65144:11:0;;;;;;;;;;;;;;;;;:22;65140:235;;;65196:15;;:19;;65214:1;;65196:19;:::i;:::-;65191:1;:24;65187:116;;65263:15;;65254:8;;65263:19;;65281:1;;65263:19;:::i;:::-;65254:29;;;;;;-1:-1:-1;;;65254:29:0;;;;;;;;;;;;;;;;;65240:8;65249:1;65240:11;;;;;;-1:-1:-1;;;65240:11:0;;;;;;;;;;;;;;;;;;:43;65187:116;65321:8;:14;;;;;-1:-1:-1;;;65321:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;65354:5;;65140:235;65120:3;;;;:::i;:::-;;;;65079:307;;55604:98;55662:7;55689:5;55693:1;55689;:5;:::i;6373:195::-;6476:12;6508:52;6530:6;6538:4;6544:1;6547:12;6508:21;:52::i;63330:290::-;63405:7;63445:3;63434:8;;:14;63430:183;;;-1:-1:-1;63472:3:0;;63330:290::o;63430:183::-;63504:8;;63497:3;:15;;:34;;;;;63527:4;63516:8;;:15;63497:34;63493:120;;;-1:-1:-1;63555:3:0;;63330:290::o;63493:120::-;-1:-1:-1;63598:3:0;;63330:290::o;44816:382::-;-1:-1:-1;;;;;44896:16:0;;44888:61;;;;-1:-1:-1;;;44888:61:0;;20956:2:1;44888:61:0;;;20938:21:1;;;20975:18;;;20968:30;21034:34;21014:18;;;21007:62;21086:18;;44888:61:0;20928:182:1;44888:61:0;44969:16;44977:7;44969;:16::i;:::-;44968:17;44960:58;;;;-1:-1:-1;;;44960:58:0;;14551:2:1;44960:58:0;;;14533:21:1;14590:2;14570:18;;;14563:30;14629;14609:18;;;14602:58;14677:18;;44960:58:0;14523:178:1;44960:58:0;-1:-1:-1;;;;;45089:13:0;;;;;;:9;:13;;;;;:18;;45106:1;;45089:13;:18;;45106:1;;45089:18;:::i;:::-;;;;-1:-1:-1;;45118:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;45118:21:0;-1:-1:-1;;;;;45118:21:0;;;;;;;;45157:33;;45118:16;;;45157:33;;45118:16;;45157:33;44816:382;;:::o;45427:360::-;45487:13;45503:23;45518:7;45503:14;:23::i;:::-;45487:39;;45628:29;45645:1;45649:7;45628:8;:29::i;:::-;-1:-1:-1;;;;;45670:16:0;;;;;;:9;:16;;;;;:21;;45690:1;;45670:16;:21;;45690:1;;45670:21;:::i;:::-;;;;-1:-1:-1;;45709:16:0;;;;:7;:16;;;;;;45702:23;;-1:-1:-1;;;;;;45702:23:0;;;45743:36;45717:7;;45709:16;-1:-1:-1;;;;;45743:36:0;;;;;45709:16;;45743:36;45427:360;;:::o;7425:530::-;7552:12;7610:5;7585:21;:30;;7577:81;;;;-1:-1:-1;;;7577:81:0;;17246:2:1;7577:81:0;;;17228:21:1;17285:2;17265:18;;;17258:30;17324:34;17304:18;;;17297:62;-1:-1:-1;;;17375:18:1;;;17368:36;17421:19;;7577:81:0;17218:228:1;7577:81:0;3822:20;;7669:60;;;;-1:-1:-1;;;7669:60:0;;23737:2:1;7669:60:0;;;23719:21:1;23776:2;23756:18;;;23749:30;23815:31;23795:18;;;23788:59;23864:18;;7669:60:0;23709:179:1;7669:60:0;7803:12;7817:23;7844:6;-1:-1:-1;;;;;7844:11:0;7864:5;7872:4;7844:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7802:75;;;;7895:52;7913:7;7922:10;7934:12;7895:17;:52::i;:::-;7888:59;7425:530;-1:-1:-1;;;;;;;7425:530:0:o;9965:742::-;10080:12;10109:7;10105:595;;;-1:-1:-1;10140:10:0;10133:17;;10105:595;10254:17;;:21;10250:439;;10517:10;10511:17;10578:15;10565:10;10561:2;10557:19;10550:44;10465:148;10660:12;10653:20;;-1:-1:-1;;;10653:20:0;;;;;;;;:::i;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:2;;177:1;174;167:12;111:2;63:124;;;:::o;192:391::-;255:8;265:6;319:3;312:4;304:6;300:17;296:27;286:2;;342:6;334;327:22;286:2;-1:-1:-1;370:20:1;;413:18;402:30;;399:2;;;452:8;442;435:26;399:2;496:4;488:6;484:17;472:29;;556:3;549:4;539:6;536:1;532:14;524:6;520:27;516:38;513:47;510:2;;;573:1;570;563:12;510:2;276:307;;;;;:::o;588:196::-;647:6;700:2;688:9;679:7;675:23;671:32;668:2;;;721:6;713;706:22;668:2;749:29;768:9;749:29;:::i;789:270::-;857:6;865;918:2;906:9;897:7;893:23;889:32;886:2;;;939:6;931;924:22;886:2;967:29;986:9;967:29;:::i;:::-;957:39;;1015:38;1049:2;1038:9;1034:18;1015:38;:::i;:::-;1005:48;;876:183;;;;;:::o;1064:338::-;1141:6;1149;1157;1210:2;1198:9;1189:7;1185:23;1181:32;1178:2;;;1231:6;1223;1216:22;1178:2;1259:29;1278:9;1259:29;:::i;:::-;1249:39;;1307:38;1341:2;1330:9;1326:18;1307:38;:::i;:::-;1297:48;;1392:2;1381:9;1377:18;1364:32;1354:42;;1168:234;;;;;:::o;1407:1183::-;1502:6;1510;1518;1526;1579:3;1567:9;1558:7;1554:23;1550:33;1547:2;;;1601:6;1593;1586:22;1547:2;1629:29;1648:9;1629:29;:::i;:::-;1619:39;;1677:38;1711:2;1700:9;1696:18;1677:38;:::i;:::-;1667:48;;1762:2;1751:9;1747:18;1734:32;1724:42;;1817:2;1806:9;1802:18;1789:32;1840:18;1881:2;1873:6;1870:14;1867:2;;;1902:6;1894;1887:22;1867:2;1945:6;1934:9;1930:22;1920:32;;1990:7;1983:4;1979:2;1975:13;1971:27;1961:2;;2017:6;2009;2002:22;1961:2;2058;2045:16;2080:2;2076;2073:10;2070:2;;;2086:18;;:::i;:::-;2161:2;2155:9;2129:2;2215:13;;-1:-1:-1;;2211:22:1;;;2235:2;2207:31;2203:40;2191:53;;;2259:18;;;2279:22;;;2256:46;2253:2;;;2305:18;;:::i;:::-;2345:10;2341:2;2334:22;2380:2;2372:6;2365:18;2420:7;2415:2;2410;2406;2402:11;2398:20;2395:33;2392:2;;;2446:6;2438;2431:22;2392:2;2507;2502;2498;2494:11;2489:2;2481:6;2477:15;2464:46;2530:15;;;2547:2;2526:24;2519:40;;;;1537:1053;;;;-1:-1:-1;1537:1053:1;;-1:-1:-1;;;;1537:1053:1:o;2595:325::-;2660:6;2668;2721:2;2709:9;2700:7;2696:23;2692:32;2689:2;;;2742:6;2734;2727:22;2689:2;2770:29;2789:9;2770:29;:::i;:::-;2760:39;;2849:2;2838:9;2834:18;2821:32;2862:28;2884:5;2862:28;:::i;:::-;2909:5;2899:15;;;2679:241;;;;;:::o;2925:264::-;2993:6;3001;3054:2;3042:9;3033:7;3029:23;3025:32;3022:2;;;3075:6;3067;3060:22;3022:2;3103:29;3122:9;3103:29;:::i;:::-;3093:39;3179:2;3164:18;;;;3151:32;;-1:-1:-1;;;3012:177:1:o;3194:803::-;3316:6;3324;3332;3340;3393:2;3381:9;3372:7;3368:23;3364:32;3361:2;;;3414:6;3406;3399:22;3361:2;3459:9;3446:23;3488:18;3529:2;3521:6;3518:14;3515:2;;;3550:6;3542;3535:22;3515:2;3594:70;3656:7;3647:6;3636:9;3632:22;3594:70;:::i;:::-;3683:8;;-1:-1:-1;3568:96:1;-1:-1:-1;3771:2:1;3756:18;;3743:32;;-1:-1:-1;3787:16:1;;;3784:2;;;3821:6;3813;3806:22;3784:2;;3865:72;3929:7;3918:8;3907:9;3903:24;3865:72;:::i;:::-;3351:646;;;;-1:-1:-1;3956:8:1;-1:-1:-1;;;;3351:646:1:o;4002:255::-;4069:6;4122:2;4110:9;4101:7;4097:23;4093:32;4090:2;;;4143:6;4135;4128:22;4090:2;4180:9;4174:16;4199:28;4221:5;4199:28;:::i;4262:190::-;4321:6;4374:2;4362:9;4353:7;4349:23;4345:32;4342:2;;;4395:6;4387;4380:22;4342:2;-1:-1:-1;4423:23:1;;4332:120;-1:-1:-1;4332:120:1:o;4457:264::-;4525:6;4533;4586:2;4574:9;4565:7;4561:23;4557:32;4554:2;;;4607:6;4599;4592:22;4554:2;4648:9;4635:23;4625:33;;4677:38;4711:2;4700:9;4696:18;4677:38;:::i;4726:255::-;4784:6;4837:2;4825:9;4816:7;4812:23;4808:32;4805:2;;;4858:6;4850;4843:22;4805:2;4902:9;4889:23;4921:30;4945:5;4921:30;:::i;4986:259::-;5055:6;5108:2;5096:9;5087:7;5083:23;5079:32;5076:2;;;5129:6;5121;5114:22;5076:2;5166:9;5160:16;5185:30;5209:5;5185:30;:::i;5445:258::-;5513:6;5521;5574:2;5562:9;5553:7;5549:23;5545:32;5542:2;;;5595:6;5587;5580:22;5542:2;-1:-1:-1;;5623:23:1;;;5693:2;5678:18;;;5665:32;;-1:-1:-1;5532:171:1:o;5708:257::-;5749:3;5787:5;5781:12;5814:6;5809:3;5802:19;5830:63;5886:6;5879:4;5874:3;5870:14;5863:4;5856:5;5852:16;5830:63;:::i;:::-;5947:2;5926:15;-1:-1:-1;;5922:29:1;5913:39;;;;5954:4;5909:50;;5757:208;-1:-1:-1;;5757:208:1:o;5970:274::-;6099:3;6137:6;6131:13;6153:53;6199:6;6194:3;6187:4;6179:6;6175:17;6153:53;:::i;:::-;6222:16;;;;;6107:137;-1:-1:-1;;6107:137:1:o;6249:470::-;6428:3;6466:6;6460:13;6482:53;6528:6;6523:3;6516:4;6508:6;6504:17;6482:53;:::i;:::-;6598:13;;6557:16;;;;6620:57;6598:13;6557:16;6654:4;6642:17;;6620:57;:::i;:::-;6693:20;;6436:283;-1:-1:-1;;;;6436:283:1:o;6724:786::-;7135:25;7130:3;7123:38;7105:3;7190:6;7184:13;7206:62;7261:6;7256:2;7251:3;7247:12;7240:4;7232:6;7228:17;7206:62;:::i;:::-;-1:-1:-1;;;7327:2:1;7287:16;;;7319:11;;;7312:40;7377:13;;7399:63;7377:13;7448:2;7440:11;;7433:4;7421:17;;7399:63;:::i;:::-;7482:17;7501:2;7478:26;;7113:397;-1:-1:-1;;;;7113:397:1:o;8103:488::-;-1:-1:-1;;;;;8372:15:1;;;8354:34;;8424:15;;8419:2;8404:18;;8397:43;8471:2;8456:18;;8449:34;;;8519:3;8514:2;8499:18;;8492:31;;;8297:4;;8540:45;;8565:19;;8557:6;8540:45;:::i;:::-;8532:53;8306:285;-1:-1:-1;;;;;;8306:285:1:o;9647:635::-;9818:2;9870:21;;;9940:13;;9843:18;;;9962:22;;;9789:4;;9818:2;10041:15;;;;10015:2;10000:18;;;9789:4;10087:169;10101:6;10098:1;10095:13;10087:169;;;10162:13;;10150:26;;10231:15;;;;10196:12;;;;10123:1;10116:9;10087:169;;;-1:-1:-1;10273:3:1;;9798:484;-1:-1:-1;;;;;;9798:484:1:o;10882:219::-;11031:2;11020:9;11013:21;10994:4;11051:44;11091:2;11080:9;11076:18;11068:6;11051:44;:::i;11894:414::-;12096:2;12078:21;;;12135:2;12115:18;;;12108:30;12174:34;12169:2;12154:18;;12147:62;-1:-1:-1;;;12240:2:1;12225:18;;12218:48;12298:3;12283:19;;12068:240::o;17864:405::-;18066:2;18048:21;;;18105:2;18085:18;;;18078:30;18144:34;18139:2;18124:18;;18117:62;-1:-1:-1;;;18210:2:1;18195:18;;18188:39;18259:3;18244:19;;18038:231::o;23117:413::-;23319:2;23301:21;;;23358:2;23338:18;;;23331:30;23397:34;23392:2;23377:18;;23370:62;-1:-1:-1;;;23463:2:1;23448:18;;23441:47;23520:3;23505:19;;23291:239::o;23893:411::-;24095:2;24077:21;;;24134:2;24114:18;;;24107:30;24173:34;24168:2;24153:18;;24146:62;-1:-1:-1;;;24239:2:1;24224:18;;24217:45;24294:3;24279:19;;24067:237::o;25962:355::-;26164:2;26146:21;;;26203:2;26183:18;;;26176:30;26242:33;26237:2;26222:18;;26215:61;26308:2;26293:18;;26136:181::o;27914:128::-;27954:3;27985:1;27981:6;27978:1;27975:13;27972:2;;;27991:18;;:::i;:::-;-1:-1:-1;28027:9:1;;27962:80::o;28047:120::-;28087:1;28113;28103:2;;28118:18;;:::i;:::-;-1:-1:-1;28152:9:1;;28093:74::o;28172:168::-;28212:7;28278:1;28274;28270:6;28266:14;28263:1;28260:21;28255:1;28248:9;28241:17;28237:45;28234:2;;;28285:18;;:::i;:::-;-1:-1:-1;28325:9:1;;28224:116::o;28345:125::-;28385:4;28413:1;28410;28407:8;28404:2;;;28418:18;;:::i;:::-;-1:-1:-1;28455:9:1;;28394:76::o;28475:258::-;28547:1;28557:113;28571:6;28568:1;28565:13;28557:113;;;28647:11;;;28641:18;28628:11;;;28621:39;28593:2;28586:10;28557:113;;;28688:6;28685:1;28682:13;28679:2;;;-1:-1:-1;;28723:1:1;28705:16;;28698:27;28528:205::o;28738:136::-;28777:3;28805:5;28795:2;;28814:18;;:::i;:::-;-1:-1:-1;;;28850:18:1;;28785:89::o;28879:380::-;28958:1;28954:12;;;;29001;;;29022:2;;29076:4;29068:6;29064:17;29054:27;;29022:2;29129;29121:6;29118:14;29098:18;29095:38;29092:2;;;29175:10;29170:3;29166:20;29163:1;29156:31;29210:4;29207:1;29200:15;29238:4;29235:1;29228:15;29092:2;;28934:325;;;:::o;29264:135::-;29303:3;-1:-1:-1;;29324:17:1;;29321:2;;;29344:18;;:::i;:::-;-1:-1:-1;29391:1:1;29380:13;;29311:88::o;29404:112::-;29436:1;29462;29452:2;;29467:18;;:::i;:::-;-1:-1:-1;29501:9:1;;29442:74::o;29521:127::-;29582:10;29577:3;29573:20;29570:1;29563:31;29613:4;29610:1;29603:15;29637:4;29634:1;29627:15;29653:127;29714:10;29709:3;29705:20;29702:1;29695:31;29745:4;29742:1;29735:15;29769:4;29766:1;29759:15;29785:127;29846:10;29841:3;29837:20;29834:1;29827:31;29877:4;29874:1;29867:15;29901:4;29898:1;29891:15;29917:118;30003:5;29996:13;29989:21;29982:5;29979:32;29969:2;;30025:1;30022;30015:12;30040:131;-1:-1:-1;;;;;;30114:32:1;;30104:43;;30094:2;;30161:1;30158;30151:12

Swarm Source

ipfs://cfee7ca41aae620cb725e1b0dc30f436edbe60c9626b3dc9dc3f2d47025f0ced
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.