APE Price: $1.12 (+4.40%)

Contract

0x7151e068db67073Eee2E6b6C3b40068D349bd7dB

Overview

APE Balance

Apechain LogoApechain LogoApechain Logo0 APE

APE Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Stake Batch79283832025-01-10 20:52:031 sec ago1736542323IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79283782025-01-10 20:51:586 secs ago1736542318IN
0x7151e068...D349bd7dB
0 APE0.0077427325.42069
Stake Batch79283742025-01-10 20:51:5311 secs ago1736542313IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79283692025-01-10 20:51:4816 secs ago1736542308IN
0x7151e068...D349bd7dB
0 APE0.0077427325.42069
Stake Batch79283612025-01-10 20:51:3727 secs ago1736542297IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79283562025-01-10 20:51:3034 secs ago1736542290IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79283482025-01-10 20:51:2044 secs ago1736542280IN
0x7151e068...D349bd7dB
0 APE0.0077427325.42069
Stake Batch79283372025-01-10 20:51:1252 secs ago1736542272IN
0x7151e068...D349bd7dB
0 APE0.0077426825.42069
Stake Batch79282792025-01-10 20:50:061 min ago1736542206IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79282692025-01-10 20:49:562 mins ago1736542196IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79282582025-01-10 20:49:432 mins ago1736542183IN
0x7151e068...D349bd7dB
0 APE0.0077427325.42069
Stake Batch79282512025-01-10 20:49:282 mins ago1736542168IN
0x7151e068...D349bd7dB
0 APE0.0077427625.42069
Stake Batch79282412025-01-10 20:49:242 mins ago1736542164IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79282352025-01-10 20:49:132 mins ago1736542153IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79282232025-01-10 20:49:043 mins ago1736542144IN
0x7151e068...D349bd7dB
0 APE0.0076715525.42069
Stake Batch79279362025-01-10 20:42:329 mins ago1736541752IN
0x7151e068...D349bd7dB
0 APE0.0077427325.42069
Stake Batch79279252025-01-10 20:42:249 mins ago1736541744IN
0x7151e068...D349bd7dB
0 APE0.0077423725.42069
Stake Batch79278842025-01-10 20:41:3910 mins ago1736541699IN
0x7151e068...D349bd7dB
0 APE0.0066592525.42069
Stake Batch79270492025-01-10 20:22:4229 mins ago1736540562IN
0x7151e068...D349bd7dB
0 APE0.0065372125.42069
Stake Batch79265942025-01-10 20:14:5337 mins ago1736540093IN
0x7151e068...D349bd7dB
0 APE0.006730425.42069
Stake Batch79265812025-01-10 20:14:4037 mins ago1736540080IN
0x7151e068...D349bd7dB
0 APE0.0067304325.42069
Stake Batch79265392025-01-10 20:14:0837 mins ago1736540048IN
0x7151e068...D349bd7dB
0 APE0.006730425.42069
Stake Batch79264982025-01-10 20:13:4238 mins ago1736540022IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79264522025-01-10 20:12:5739 mins ago1736539977IN
0x7151e068...D349bd7dB
0 APE0.0077427125.42069
Stake Batch79264222025-01-10 20:12:2739 mins ago1736539947IN
0x7151e068...D349bd7dB
0 APE0.0075495125.42069
View all transactions

Parent Transaction Hash Block From To
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
OOGIESstaking

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at apescan.io on 2025-01-10
*/

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.20;


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

    /**
     * @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 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: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * 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 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 address zero.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) external;

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

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

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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 Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

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

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

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)

pragma solidity ^0.8.20;

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

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

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;


/**
 * @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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

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

// File: contracts/OOGIESstaking.sol


pragma solidity ^0.8.17;





/**
 * @title NFTStaking
 * @notice Stake ERC721 tokens to earn ERC20 rewards (AFTR) from this contract's balance,
 *         with optional locks of 30/60/90 days at higher multipliers (1.5x, 2x, 2.5x).
 */
contract OOGIESstaking is ReentrancyGuard, Ownable {
    // ----------------------------------------
    // State Variables
    // ----------------------------------------

    /// @notice The ERC721 contract whose NFTs we are staking.
    IERC721 public nftContract = IERC721(0x214cAE51c3BAE88515aAEfd8e1867E64502B0342);

    /// @notice The ERC20 token used as the reward (must be deposited into this contract).
    IERC20 public rewardToken = IERC20(0xA0a3b1Fdb070B4b99E76E23D983F3000F093A102);

    /// @notice Number of seconds in 1 day (used for integer division).
    uint256 public dayInSeconds = 1 days;

    /**
     * @notice Base daily reward rate (in wei).
     *         e.g. 1 ether = 1 token/day if token has 18 decimals.
     */
    uint256 public rewardRateNormal = 5 ether;

    /**
     * @notice Lock durations and multipliers (all editable by admin).
     *         Example multipliers: 150 = 1.5x, 200 = 2x, 250 = 2.5x.
     */
    uint256 public lockDuration30 = 30 days;
    uint256 public lockMultiplier30 = 150; // 1.5x

    uint256 public lockDuration60 = 60 days;
    uint256 public lockMultiplier60 = 200; // 2.0x

    uint256 public lockDuration90 = 90 days;
    uint256 public lockMultiplier90 = 250; // 2.5x

    /**
     * @notice NFT-specific multipliers: e.g., 150 = 1.5x, 200 = 2x. 
     *         If 0, treat it as 100 (1x).
     */
    mapping(uint256 => uint256) public nftMultiplier;

    /// @notice Lock option choices
    enum LockOption {
        None,   // no lock (normal staking)
        Lock30, // 30-day lock at lockMultiplier30
        Lock60, // 60-day lock at lockMultiplier60
        Lock90  // 90-day lock at lockMultiplier90
    }

    /// @notice Info about each staked NFT.
    struct StakedNFT {
        address owner;          // who staked it
        uint256 tokenId;        // which token
        uint256 stakedAt;       // when it was staked
        uint256 lastClaimedAt;  // last time rewards were claimed
        LockOption lockOption;  // which lock type
        uint256 lockStartedAt;  // when current lock was set
    }

    /// @notice tokenId => staking info
    mapping(uint256 => StakedNFT) public stakedNFTs;

    /// @notice Keep track of all currently staked tokenIds (for enumerations).
    uint256[] private allStakedTokenIds;
    /// @notice tokenId => index in allStakedTokenIds
    mapping(uint256 => uint256) private allStakedTokenIndex;

    /// @notice For easy lookup of which tokenIds a user has staked.
    mapping(address => uint256[]) private userStakedTokens;
    /// @notice tokenId => index in userStakedTokens[user]
    mapping(uint256 => uint256) private userStakedTokensIndex;

    // ----------------------------------------
    // Events
    // ----------------------------------------
    event Staked(address indexed user, uint256 tokenId, LockOption lockOption);
    event Unstaked(address indexed user, uint256 tokenId);
    event RewardClaimed(address indexed user, uint256 tokenId, uint256 amount);
    event LockOptionChanged(address indexed user, uint256 tokenId, LockOption newLockOption);
    event TokensDeposited(address indexed from, uint256 amount);

    // ----------------------------------------
    // Constructor
    // ----------------------------------------
    constructor(address _initialOwner) Ownable(_initialOwner) {}

    // ----------------------------------------
    // Owner-Only Functions
    // ----------------------------------------

    function setNftContract(IERC721 _nftContract) external onlyOwner {
        nftContract = _nftContract;
    }

    function setRewardToken(IERC20 _rewardToken) external onlyOwner {
        rewardToken = _rewardToken;
    }

    function setDayInSeconds(uint256 _seconds) external onlyOwner {
        dayInSeconds = _seconds;
    }

    function setRewardRateNormal(uint256 _normal) external onlyOwner {
        rewardRateNormal = _normal;
    }

    /**
     * @notice Update lock durations and/or multipliers for 30, 60, and 90 days.
     *         Example multipliers: 150 => 1.5x, 200 => 2x, 250 => 2.5x.
     */
    function setLockParams(
        uint256 _lockDuration30,
        uint256 _lockMultiplier30,
        uint256 _lockDuration60,
        uint256 _lockMultiplier60,
        uint256 _lockDuration90,
        uint256 _lockMultiplier90
    ) external onlyOwner {
        lockDuration30 = _lockDuration30;
        lockMultiplier30 = _lockMultiplier30;

        lockDuration60 = _lockDuration60;
        lockMultiplier60 = _lockMultiplier60;

        lockDuration90 = _lockDuration90;
        lockMultiplier90 = _lockMultiplier90;
    }

    /**
     * @notice Set multipliers for multiple NFTs at once.
     * @param _tokenIds array of token IDs
     * @param _multipliers array of multipliers (e.g. 150 = 1.5x), must match length of _tokenIds
     */
    function setNFTMultiplierBatch(uint256[] calldata _tokenIds, uint256[] calldata _multipliers) external onlyOwner {
        require(_tokenIds.length == _multipliers.length, "Array length mismatch");
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            nftMultiplier[_tokenIds[i]] = _multipliers[i];
        }
    }

    // ----------------------------------
    // Rescue functions
    // ----------------------------------

    function rescueNative(uint256 _amount) external onlyOwner {
        require(address(this).balance >= _amount, "Not enough native balance");
        payable(msg.sender).transfer(_amount);
    }

    function rescueERC20(address _token, uint256 _amount) external onlyOwner {
        IERC20(_token).transfer(msg.sender, _amount);
    }

    // ----------------------------------------
    // Deposit Rewards (ERC20)
    // ----------------------------------------

    function depositTokens(uint256 amount) external nonReentrant {
        require(amount > 0, "Cannot deposit 0");
        bool success = rewardToken.transferFrom(msg.sender, address(this), amount);
        require(success, "transferFrom failed");
        emit TokensDeposited(msg.sender, amount);
    }

    function getContractBalance() external view returns (uint256) {
        return rewardToken.balanceOf(address(this));
    }

    // ----------------------------------------
    // Batch Operations
    // ----------------------------------------

    /**
     * @notice Stake multiple NFTs at once with a chosen lock option (None, Lock30, Lock60, Lock90).
     * @param _tokenIds    array of token IDs
     * @param _lockOptions array of lock options
     */
    function stakeBatch(uint256[] calldata _tokenIds, LockOption[] calldata _lockOptions) external nonReentrant {
        require(_tokenIds.length == _lockOptions.length, "Array length mismatch");
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            _stakeInternal(_tokenIds[i], _lockOptions[i]);
        }
    }

    /**
     * @notice Unstake multiple NFTs at once.
     *         Reverts if the lock period has not ended yet.
     */
    function unstakeBatch(uint256[] calldata _tokenIds) external nonReentrant {
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            uint256 tokenId = _tokenIds[i];
            require(stakedNFTs[tokenId].owner == msg.sender, "Not staker");
            _unstakeInternal(tokenId);
        }
    }

    /**
     * @notice Claim rewards for multiple NFTs at once.
     */
    function claimRewardsBatch(uint256[] calldata _tokenIds) external nonReentrant {
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            uint256 tokenId = _tokenIds[i];
            require(stakedNFTs[tokenId].owner == msg.sender, "Not staker");
            _claimRewards(tokenId);
        }
    }

    /**
     * @notice Lock multiple NFTs that are currently staked but unlocked (None).
     *         Or if they were locked and the lock is finished, this also acts as “re-lock.”
     * @dev If the lock is still active and not finished, this will revert.
     */
    function lockStakedNFTBatch(uint256[] calldata _tokenIds, LockOption[] calldata _lockOptions) 
        external 
        nonReentrant 
    {
        require(_tokenIds.length == _lockOptions.length, "Array length mismatch");
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            uint256 tokenId = _tokenIds[i];
            require(stakedNFTs[tokenId].owner == msg.sender, "Not staker");
            _lockStakedNFTInternal(tokenId, _lockOptions[i]);
        }
    }

    /**
     * @notice Re-lock multiple NFTs (choose any lock option) once your previous lock ended.
     * @dev If lock not ended, will revert; if not locked at all, will revert.
     */
    function reLockBatch(uint256[] calldata _tokenIds, LockOption[] calldata _newLockOptions) external nonReentrant {
        require(_tokenIds.length == _newLockOptions.length, "Array length mismatch");
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            uint256 tokenId = _tokenIds[i];
            require(stakedNFTs[tokenId].owner == msg.sender, "Not staker");
            _reLockInternal(tokenId, _newLockOptions[i]);
        }
    }

    // ----------------------------------------
    // Batch Views (Claimable Rewards, etc.)
    // ----------------------------------------
    
    /**
     * @notice Returns an array of claimable rewards for the given NFT IDs, in the same order.
     */
    function claimableRewardsBatch(uint256[] calldata _tokenIds) external view returns (uint256[] memory) {
        uint256[] memory amounts = new uint256[](_tokenIds.length);
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            amounts[i] = _claimableRewardsView(_tokenIds[i]);
        }
        return amounts;
    }

    /**
     * @notice Returns how many tokens (AFTR) this user generates per full day 
     *         across all staked NFTs, factoring in lock options and NFT multipliers.
     */
    function generatingPerDay(address _user) external view returns (uint256) {
        uint256 totalDailyRate = 0;
        uint256[] memory tokenIds = userStakedTokens[_user];

        for (uint256 i = 0; i < tokenIds.length; i++) {
            uint256 tokenId = tokenIds[i];
            StakedNFT storage info = stakedNFTs[tokenId];

            // sanity check
            if (info.owner != _user) continue;

            // figure out if still in lock period
            (uint256 chosenLockMult, bool inLock) = _getLockMultiplierAndStatus(info);
            uint256 baseDaily;

            if (inLock) {
                // still in lock => base rate * chosenLockMult
                baseDaily = (rewardRateNormal * chosenLockMult) / 100;
            } else {
                // not locked or lock ended => normal rate
                baseDaily = rewardRateNormal;
            }

            // apply NFT-specific multiplier
            uint256 nftMult = nftMultiplier[tokenId];
            if (nftMult == 0) nftMult = 100;

            uint256 finalRate = (baseDaily * nftMult) / 100;
            totalDailyRate += finalRate;
        }

        return totalDailyRate;
    }

    // ----------------------------------------
    // Internal (Single-Token) Logic
    // ----------------------------------------
    // Called by the batch functions above.

    function _stakeInternal(uint256 _tokenId, LockOption _lockOption) internal {
        // Transfer NFT from user to this contract
        nftContract.transferFrom(msg.sender, address(this), _tokenId);

        // Record staking info
        StakedNFT storage info = stakedNFTs[_tokenId];
        info.owner = msg.sender;
        info.tokenId = _tokenId;
        info.stakedAt = block.timestamp;
        info.lastClaimedAt = block.timestamp;
        info.lockOption = _lockOption;
        info.lockStartedAt = (_lockOption == LockOption.None) ? 0 : block.timestamp;

        // Add to global and user tracking
        _addToAllStakedTokenIds(_tokenId);
        _addToUserStakedTokens(msg.sender, _tokenId);

        emit Staked(msg.sender, _tokenId, _lockOption);
    }

    function _unstakeInternal(uint256 _tokenId) internal {
        StakedNFT storage info = stakedNFTs[_tokenId];

        // if locked, ensure lock period ended
        if (info.lockOption != LockOption.None) {
            uint256 lockEnd = info.lockStartedAt + _getLockDuration(info.lockOption);
            require(block.timestamp >= lockEnd, "Lock period not over. Cannot unstake yet.");
        }

        // claim all rewards up to now
        _claimRewards(_tokenId);

        // transfer NFT back
        nftContract.transferFrom(address(this), info.owner, _tokenId);

        // cleanup
        _removeFromAllStakedTokenIds(_tokenId);
        _removeFromUserStakedTokens(info.owner, _tokenId);
        delete stakedNFTs[_tokenId];

        emit Unstaked(info.owner, _tokenId);
    }

    /**
     * @dev Lock an NFT that is currently staked but:
     *      - either has never been locked (lockOption == None), or
     *      - was locked and its lock period is finished (so effectively “re-lock”).
     *      If it's still locked and not finished, this reverts.
     */
    function _lockStakedNFTInternal(uint256 _tokenId, LockOption _newLockOption) internal {
        StakedNFT storage info = stakedNFTs[_tokenId];

        // Must be staked
        require(info.owner != address(0), "Not staked");

        // If it's currently locked, check if the lock ended
        if (info.lockOption != LockOption.None) {
            uint256 lockEnd = info.lockStartedAt + _getLockDuration(info.lockOption);
            require(block.timestamp >= lockEnd, "Current lock not finished");
        }

        // First claim everything earned so far (including any unlocked days)
        _claimRewards(_tokenId);

        // Set new lock
        info.lockOption = _newLockOption;
        info.lockStartedAt = block.timestamp;
        info.lastClaimedAt = block.timestamp; // so we start fresh

        emit LockOptionChanged(info.owner, _tokenId, _newLockOption);
    }

    /**
     * @dev Re-lock an NFT that was already locked, picking a new lock option
     *      after the old lock has ended. Reverts if lock not over or was never locked.
     */
    function _reLockInternal(uint256 _tokenId, LockOption _newLockOption) internal {
        StakedNFT storage info = stakedNFTs[_tokenId];

        // Must already be locked with some option
        require(info.lockOption != LockOption.None, "NFT not currently locked");

        // Ensure old lock ended
        uint256 lockEnd = info.lockStartedAt + _getLockDuration(info.lockOption);
        require(block.timestamp >= lockEnd, "Current lock not finished");

        // Claim all rewards up to now
        _claimRewards(_tokenId);

        // Re-lock with the new option
        info.lockOption = _newLockOption;
        info.lockStartedAt = block.timestamp;
        info.lastClaimedAt = block.timestamp;

        emit LockOptionChanged(info.owner, _tokenId, _newLockOption);
    }

    // ----------------------------------------
    // Reward Logic
    // ----------------------------------------
    
    /**
     * @dev Internal function to calculate and transfer rewards from the contract’s balance.
     */
    function _claimRewards(uint256 _tokenId) internal returns (uint256) {
        StakedNFT storage info = stakedNFTs[_tokenId];

        uint256 currentTime = block.timestamp;
        uint256 lastClaimed = info.lastClaimedAt;

        // no time passed => no rewards
        if (currentTime <= lastClaimed) {
            return 0;
        }

        uint256 timeDiff = currentTime - lastClaimed;
        uint256 totalReward = 0;

        // figure out lock end
        uint256 lockEnd = (info.lockOption == LockOption.None)
            ? 0
            : (info.lockStartedAt + _getLockDuration(info.lockOption));

        // break the time into possible segments: locked vs. unlocked
        if (info.lockOption != LockOption.None) {
            // some lock option
            if (lastClaimed < lockEnd) {
                // portion in lock
                uint256 lockedSegmentEnd = (currentTime < lockEnd) ? currentTime : lockEnd;
                uint256 lockedTime = (lockedSegmentEnd > lastClaimed)
                    ? lockedSegmentEnd - lastClaimed
                    : 0;

                uint256 lockedDays = lockedTime / dayInSeconds;
                uint256 lockedMult = _getLockMultiplier(info.lockOption);

                // locked portion daily rate = rewardRateNormal * lockedMult/100
                // we apply the NFT multiplier below
                uint256 lockedDailyRate = (rewardRateNormal * lockedMult) / 100;

                // NFT-specific multiplier
                uint256 nftMult = nftMultiplier[_tokenId];
                if (nftMult == 0) nftMult = 100;

                // final locked portion = lockedDays * lockedDailyRate * (nftMult/100)
                uint256 lockedReward = lockedDays * ((lockedDailyRate * nftMult) / 100);
                totalReward += lockedReward;

                // portion after lock (if currentTime > lockEnd)
                if (currentTime > lockEnd) {
                    uint256 postLockTime = currentTime - lockEnd;
                    uint256 postLockDays = postLockTime / dayInSeconds;

                    // post-lock daily rate => normal rate * NFT multiplier
                    uint256 postLockDailyRate = (rewardRateNormal * nftMult) / 100;
                    totalReward += postLockDays * postLockDailyRate;
                }
            } else {
                // entire interval is after lock ended
                uint256 daysCount = timeDiff / dayInSeconds;
                uint256 nftMult = nftMultiplier[_tokenId];
                if (nftMult == 0) nftMult = 100;

                uint256 postLockDaily = (rewardRateNormal * nftMult) / 100;
                totalReward += daysCount * postLockDaily;
            }
        } else {
            // no lock => purely normal
            uint256 daysCount = timeDiff / dayInSeconds;
            uint256 nftMult = nftMultiplier[_tokenId];
            if (nftMult == 0) nftMult = 100;

            uint256 daily = (rewardRateNormal * nftMult) / 100;
            totalReward += daysCount * daily;
        }

        // update lastClaimed
        info.lastClaimedAt = currentTime;

        // transfer from contract to staker
        if (totalReward > 0) {
            uint256 contractBal = rewardToken.balanceOf(address(this));
            require(contractBal >= totalReward, "Not enough reward tokens in contract");
            rewardToken.transfer(info.owner, totalReward);

            emit RewardClaimed(info.owner, _tokenId, totalReward);
        }

        return totalReward;
    }

    /**
     * @dev View-only version of claiming logic (no state changes).
     */
    function _claimableRewardsView(uint256 _tokenId) internal view returns (uint256) {
        StakedNFT storage info = stakedNFTs[_tokenId];
        if (info.owner == address(0)) return 0; // not staked

        uint256 currentTime = block.timestamp;
        uint256 lastClaimed = info.lastClaimedAt;
        if (currentTime <= lastClaimed) return 0;

        uint256 timeDiff = currentTime - lastClaimed;
        uint256 totalReward = 0;

        uint256 lockEnd = (info.lockOption == LockOption.None)
            ? 0
            : (info.lockStartedAt + _getLockDuration(info.lockOption));

        if (info.lockOption != LockOption.None) {
            if (lastClaimed < lockEnd) {
                uint256 lockedSegmentEnd = (currentTime < lockEnd) ? currentTime : lockEnd;
                uint256 lockedTime = (lockedSegmentEnd > lastClaimed)
                    ? lockedSegmentEnd - lastClaimed
                    : 0;

                uint256 lockedDays = lockedTime / dayInSeconds;
                uint256 lockedMult = _getLockMultiplier(info.lockOption);

                uint256 lockedDailyRate = (rewardRateNormal * lockedMult) / 100;

                uint256 nftMult = nftMultiplier[_tokenId];
                if (nftMult == 0) nftMult = 100;

                uint256 lockedReward = lockedDays * ((lockedDailyRate * nftMult) / 100);
                totalReward += lockedReward;

                if (currentTime > lockEnd) {
                    uint256 postLockTime = currentTime - lockEnd;
                    uint256 postLockDays = postLockTime / dayInSeconds;
                    uint256 postLockDaily = (rewardRateNormal * nftMult) / 100;
                    totalReward += postLockDays * postLockDaily;
                }
            } else {
                // entire interval after lock
                uint256 daysCount = timeDiff / dayInSeconds;
                uint256 nftMult = nftMultiplier[_tokenId];
                if (nftMult == 0) nftMult = 100;

                uint256 postLockDaily = (rewardRateNormal * nftMult) / 100;
                totalReward += daysCount * postLockDaily;
            }
        } else {
            // no lock
            uint256 daysCount = timeDiff / dayInSeconds;
            uint256 nftMult = nftMultiplier[_tokenId];
            if (nftMult == 0) nftMult = 100;

            uint256 daily = (rewardRateNormal * nftMult) / 100;
            totalReward += daysCount * daily;
        }

        return totalReward;
    }

    // ----------------------------------------
    // View Functions (Enumeration, etc.)
    // ----------------------------------------

    function totalStaked() external view returns (uint256) {
        return allStakedTokenIds.length;
    }

    function getAllStakedNFTs() external view returns (StakedNFT[] memory) {
        uint256 length = allStakedTokenIds.length;
        StakedNFT[] memory result = new StakedNFT[](length);
        for (uint256 i = 0; i < length; i++) {
            uint256 tokenId = allStakedTokenIds[i];
            result[i] = stakedNFTs[tokenId];
        }
        return result;
    }

    function getStakedNFTsOf(address _wallet) external view returns (StakedNFT[] memory) {
        uint256[] storage tokenIds = userStakedTokens[_wallet];
        uint256 length = tokenIds.length;
        StakedNFT[] memory result = new StakedNFT[](length);
        for (uint256 i = 0; i < length; i++) {
            uint256 tokenId = tokenIds[i];
            result[i] = stakedNFTs[tokenId];
        }
        return result;
    }

    // ----------------------------------------
    // Internal Helpers
    // ----------------------------------------

    function _addToAllStakedTokenIds(uint256 _tokenId) internal {
        allStakedTokenIndex[_tokenId] = allStakedTokenIds.length;
        allStakedTokenIds.push(_tokenId);
    }

    function _removeFromAllStakedTokenIds(uint256 _tokenId) internal {
        uint256 idx = allStakedTokenIndex[_tokenId];
        uint256 lastIndex = allStakedTokenIds.length - 1;
        if (idx != lastIndex) {
            uint256 lastTokenId = allStakedTokenIds[lastIndex];
            allStakedTokenIds[idx] = lastTokenId;
            allStakedTokenIndex[lastTokenId] = idx;
        }
        allStakedTokenIds.pop();
        delete allStakedTokenIndex[_tokenId];
    }

    function _addToUserStakedTokens(address _user, uint256 _tokenId) internal {
        userStakedTokensIndex[_tokenId] = userStakedTokens[_user].length;
        userStakedTokens[_user].push(_tokenId);
    }

    function _removeFromUserStakedTokens(address _user, uint256 _tokenId) internal {
        uint256 idx = userStakedTokensIndex[_tokenId];
        uint256 lastIndex = userStakedTokens[_user].length - 1;

        if (idx != lastIndex) {
            uint256 lastTokenId = userStakedTokens[_user][lastIndex];
            userStakedTokens[_user][idx] = lastTokenId;
            userStakedTokensIndex[lastTokenId] = idx;
        }
        userStakedTokens[_user].pop();
        delete userStakedTokensIndex[_tokenId];
    }

    /**
     * @dev Returns the configured lock duration (in seconds) for the chosen option.
     */
    function _getLockDuration(LockOption option) internal view returns (uint256) {
        if (option == LockOption.Lock30) {
            return lockDuration30;
        } else if (option == LockOption.Lock60) {
            return lockDuration60;
        } else if (option == LockOption.Lock90) {
            return lockDuration90;
        }
        return 0;
    }

    /**
     * @dev Returns the lock multiplier (e.g. 150 => 1.5×) for the chosen lock option.
     */
    function _getLockMultiplier(LockOption option) internal view returns (uint256) {
        if (option == LockOption.Lock30) {
            return lockMultiplier30;
        } else if (option == LockOption.Lock60) {
            return lockMultiplier60;
        } else if (option == LockOption.Lock90) {
            return lockMultiplier90;
        }
        return 100; // None => normal
    }

    /**
     * @dev Helper to see if a given staked NFT is still within its lock period, 
     *      plus the chosen lock multiplier.
     */
    function _getLockMultiplierAndStatus(
        StakedNFT storage info
    ) 
        internal 
        view 
        returns (uint256 chosenMultiplier, bool stillInLock) 
    {
        if (info.lockOption == LockOption.None) {
            return (100, false);
        }
        uint256 duration = _getLockDuration(info.lockOption);
        uint256 endTime = info.lockStartedAt + duration;
        bool inLockPeriod = (block.timestamp < endTime);
        uint256 lockMult = _getLockMultiplier(info.lockOption);
        return (lockMult, inLockPeriod);
    }
    /**
     * @notice Forcibly return an array of staked NFTs to their respective owners.
     *         No rewards are claimed or paid. Resets all internal tracking.
     * @param _tokenIds Array of token IDs to be returned.
     */
    function emergencyReturnBatch(uint256[] calldata _tokenIds) external onlyOwner nonReentrant {
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            uint256 tokenId = _tokenIds[i];
            StakedNFT storage info = stakedNFTs[tokenId];

            // If it's actually staked (owner != address(0))
            if (info.owner != address(0)) {
                // Transfer NFT back to staker
                nftContract.transferFrom(address(this), info.owner, tokenId);

                // Remove from global array
                _removeFromAllStakedTokenIds(tokenId);
                // Remove from user array
                _removeFromUserStakedTokens(info.owner, tokenId);
                // Clear staking info (no rewards)
                delete stakedNFTs[tokenId];
            }
        }
    }

    /**
     * @notice Forcibly return ALL currently staked NFTs to their respective owners.
     *         No rewards are claimed or paid. Resets all internal tracking for each NFT.
     */
    function emergencyReturnAllStaked() external onlyOwner nonReentrant {
        // Keep removing from the end of allStakedTokenIds until empty
        while (allStakedTokenIds.length > 0) {
            uint256 lastIndex = allStakedTokenIds.length - 1;
            uint256 tokenId = allStakedTokenIds[lastIndex];
            StakedNFT storage info = stakedNFTs[tokenId];

            if (info.owner != address(0)) {
                // Transfer NFT back to staker
                nftContract.transferFrom(address(this), info.owner, tokenId);

                // Remove from user array
                _removeFromUserStakedTokens(info.owner, tokenId);
                // Clear staking info
                delete stakedNFTs[tokenId];
            }

            // Finally remove it from the global array
            allStakedTokenIds.pop();
        }
    }

    /**
     * @notice Allow contract owner to withdraw any NFT directly to their own wallet,
     *         ignoring normal staking rules. Use with care!
     * @param _tokenId Token ID to withdraw to the owner's wallet.
     */
    function emergencyWithdrawNFT(uint256 _tokenId) external onlyOwner nonReentrant {
        nftContract.transferFrom(address(this), owner(), _tokenId);
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"enum OOGIESstaking.LockOption","name":"newLockOption","type":"uint8"}],"name":"LockOptionChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"enum OOGIESstaking.LockOption","name":"lockOption","type":"uint8"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Unstaked","type":"event"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"claimRewardsBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"claimableRewardsBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dayInSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyReturnAllStaked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"emergencyReturnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"emergencyWithdrawNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"generatingPerDay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllStakedNFTs","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"stakedAt","type":"uint256"},{"internalType":"uint256","name":"lastClaimedAt","type":"uint256"},{"internalType":"enum OOGIESstaking.LockOption","name":"lockOption","type":"uint8"},{"internalType":"uint256","name":"lockStartedAt","type":"uint256"}],"internalType":"struct OOGIESstaking.StakedNFT[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"getStakedNFTsOf","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"stakedAt","type":"uint256"},{"internalType":"uint256","name":"lastClaimedAt","type":"uint256"},{"internalType":"enum OOGIESstaking.LockOption","name":"lockOption","type":"uint8"},{"internalType":"uint256","name":"lockStartedAt","type":"uint256"}],"internalType":"struct OOGIESstaking.StakedNFT[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDuration30","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDuration60","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockDuration90","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockMultiplier30","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockMultiplier60","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockMultiplier90","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"enum OOGIESstaking.LockOption[]","name":"_lockOptions","type":"uint8[]"}],"name":"lockStakedNFTBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nftContract","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"enum OOGIESstaking.LockOption[]","name":"_newLockOptions","type":"uint8[]"}],"name":"reLockBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rescueNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardRateNormal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_seconds","type":"uint256"}],"name":"setDayInSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockDuration30","type":"uint256"},{"internalType":"uint256","name":"_lockMultiplier30","type":"uint256"},{"internalType":"uint256","name":"_lockDuration60","type":"uint256"},{"internalType":"uint256","name":"_lockMultiplier60","type":"uint256"},{"internalType":"uint256","name":"_lockDuration90","type":"uint256"},{"internalType":"uint256","name":"_lockMultiplier90","type":"uint256"}],"name":"setLockParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_multipliers","type":"uint256[]"}],"name":"setNFTMultiplierBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC721","name":"_nftContract","type":"address"}],"name":"setNftContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_normal","type":"uint256"}],"name":"setRewardRateNormal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_rewardToken","type":"address"}],"name":"setRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"enum OOGIESstaking.LockOption[]","name":"_lockOptions","type":"uint8[]"}],"name":"stakeBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakedNFTs","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"stakedAt","type":"uint256"},{"internalType":"uint256","name":"lastClaimedAt","type":"uint256"},{"internalType":"enum OOGIESstaking.LockOption","name":"lockOption","type":"uint8"},{"internalType":"uint256","name":"lockStartedAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"unstakeBatch","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600280546001600160a01b031990811673214cae51c3bae88515aaefd8e1867e64502b0342179091556003805490911673a0a3b1fdb070b4b99e76e23d983f3000f093a10217905562015180600455674563918244f4000060055562278d006006556096600755624f1a0060085560c86009556276a700600a5560fa600b553480156200008f575f80fd5b5060405162002b5238038062002b52833981016040819052620000b29162000149565b60015f55806001600160a01b038116620000e557604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b620000f081620000f8565b505062000178565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f602082840312156200015a575f80fd5b81516001600160a01b038116811462000171575f80fd5b9392505050565b6129cc80620001865f395ff3fe608060405234801561000f575f80fd5b5060043610610229575f3560e01c80638da5cb5b1161012a578063dbb7a621116100b4578063f7c618c111610079578063f7c618c1146104c9578063f7e455d7146104dc578063fae40fa0146104fc578063fb64455b14610505578063ffd2d8291461050d575f80fd5b8063dbb7a62114610475578063dd49756e1461047d578063e64a21f314610490578063efdd78e1146104a3578063f2fde38b146104b6575f80fd5b8063b2040612116100fa578063b2040612146103cf578063b865749d146103d8578063bf4bac391461043c578063d3abfe121461044f578063d56d229d14610462575f80fd5b80638da5cb5b1461038f57806399ba918d146103b45780639ce98f0e146103bd578063ae63586c146103c6575f80fd5b806370becf5d116101b6578063817b1cd21161017b578063817b1cd21461032e578063888ce4af1461033657806388c0771b146103565780638aee8127146103695780638cd4426d1461037c575f80fd5b806370becf5d146102d8578063715018a6146102e1578063760edace146102e95780637dc3db8f146102fc5780637f4ca1d71461030f575f80fd5b8063454aa669116101fc578063454aa6691461028457806352f5ad7714610297578063646e6f8b146102aa57806366e4664a146102bd5780636f9fb98a146102d0575f80fd5b80630dfa1e961461022d578063224eb12914610249578063398612b81461025e5780633af7a79514610271575b5f80fd5b61023660085481565b6040519081526020015b60405180910390f35b61025c610257366004612523565b610516565b005b61025c61026c366004612582565b610523565b61025c61027f366004612582565b6105fd565b61025c610292366004612523565b610684565b61025c6102a53660046125fd565b61070a565b61025c6102b836600461261f565b610734565b61025c6102cb366004612582565b6107ba565b61023661083b565b610236600a5481565b61025c6108aa565b6102366102f73660046125fd565b6108bd565b61025c61030a366004612523565b610a0e565b61023661031d366004612523565b600c6020525f908152604090205481565b600e54610236565b6103496103443660046125fd565b610a1b565b6040516102409190612692565b61025c610364366004612523565b610b6c565b61025c6103773660046125fd565b610bf8565b61025c61038a36600461271c565b610c22565b6001546001600160a01b03165b6040516001600160a01b039091168152602001610240565b61023660055481565b61023660065481565b61023660045481565b610236600b5481565b61042a6103e6366004612523565b600d6020525f90815260409020805460018201546002830154600384015460048501546005909501546001600160a01b039094169492939192909160ff9091169086565b60405161024096959493929190612746565b61025c61044a366004612582565b610c9d565b61025c61045d36600461261f565b610d5e565b60025461039c906001600160a01b031681565b61025c610e87565b61025c61048b366004612523565b610fe5565b61025c61049e36600461261f565b611127565b61025c6104b1366004612789565b6111a2565b61025c6104c43660046125fd565b6111c7565b60035461039c906001600160a01b031681565b6104ef6104ea36600461261f565b611201565b60405161024091906127c8565b61023660095481565b6103496112a3565b61023660075481565b61051e6113de565b600455565b61052b61140b565b8281146105535760405162461bcd60e51b815260040161054a9061280b565b60405180910390fd5b5f5b838110156105ed575f8585838181106105705761057061283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b031633146105b45760405162461bcd60e51b815260040161054a9061284e565b6105e4818585858181106105ca576105ca61283a565b90506020020160208101906105df9190612872565b611462565b50600101610555565b506105f760015f55565b50505050565b6106056113de565b8281146106245760405162461bcd60e51b815260040161054a9061280b565b5f5b8381101561067d578282828181106106405761064061283a565b90506020020135600c5f87878581811061065c5761065c61283a565b602090810292909201358352508101919091526040015f2055600101610626565b5050505050565b61068c6113de565b804710156106dc5760405162461bcd60e51b815260206004820152601960248201527f4e6f7420656e6f756768206e61746976652062616c616e636500000000000000604482015260640161054a565b604051339082156108fc029083905f818181858888f19350505050158015610706573d5f803e3d5ffd5b5050565b6107126113de565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b61073c61140b565b5f5b818110156107b0575f8383838181106107595761075961283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b0316331461079d5760405162461bcd60e51b815260040161054a9061284e565b6107a6816115ce565b505060010161073e565b5061070660015f55565b6107c261140b565b8281146107e15760405162461bcd60e51b815260040161054a9061280b565b5f5b838110156105ed576108338585838181106108005761080061283a565b905060200201358484848181106108195761081961283a565b905060200201602081019061082e9190612872565b6119fa565b6001016107e3565b6003546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015610881573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a59190612890565b905090565b6108b26113de565b6108bb5f611b87565b565b6001600160a01b0381165f90815260106020908152604080832080548251818502810185019093528083528493849392919083018282801561091c57602002820191905f5260205f20905b815481526020019060010190808311610908575b505050505090505f5b8151811015610a05575f8282815181106109415761094161283a565b6020908102919091018101515f818152600d90925260409091208054919250906001600160a01b0388811691161461097a5750506109fd565b5f8061098583611bd8565b915091505f81156109b1576064836005546109a091906128bb565b6109aa91906128d2565b90506109b6565b506005545b5f858152600c6020526040812054908190036109d0575060645b5f60646109dd83856128bb565b6109e791906128d2565b90506109f3818b6128f1565b9950505050505050505b600101610925565b50909392505050565b610a166113de565b600555565b6001600160a01b0381165f90815260106020526040812080546060928167ffffffffffffffff811115610a5057610a50612904565b604051908082528060200260200182016040528015610a8957816020015b610a766124d9565b815260200190600190039081610a6e5790505b5090505f5b82811015610b63575f848281548110610aa957610aa961283a565b5f918252602080832090910154808352600d8252604092839020835160c08101855281546001600160a01b0316815260018201549381019390935260028101549383019390935260038084015460608401526004840154919450919291608084019160ff1690811115610b1e57610b1e61265e565b6003811115610b2f57610b2f61265e565b8152602001600582015481525050838381518110610b4f57610b4f61283a565b602090810291909101015250600101610a8e565b50949350505050565b610b746113de565b610b7c61140b565b6002546001600160a01b03166323b872dd30610ba06001546001600160a01b031690565b846040518463ffffffff1660e01b8152600401610bbf93929190612918565b5f604051808303815f87803b158015610bd6575f80fd5b505af1158015610be8573d5f803e3d5ffd5b50505050610bf560015f55565b50565b610c006113de565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b610c2a6113de565b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303815f875af1158015610c74573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c98919061293c565b505050565b610ca561140b565b828114610cc45760405162461bcd60e51b815260040161054a9061280b565b5f5b838110156105ed575f858583818110610ce157610ce161283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b03163314610d255760405162461bcd60e51b815260040161054a9061284e565b610d5581858585818110610d3b57610d3b61283a565b9050602002016020810190610d509190612872565b611c51565b50600101610cc6565b610d666113de565b610d6e61140b565b5f5b818110156107b0575f838383818110610d8b57610d8b61283a565b602090810292909201355f818152600d90935260409092208054929350916001600160a01b0316159050610e7d5760025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92610df1923092909116908790600401612918565b5f604051808303815f87803b158015610e08575f80fd5b505af1158015610e1a573d5f803e3d5ffd5b50505050610e2782611dc0565b8054610e3c906001600160a01b031683611e76565b5f828152600d6020526040812080546001600160a01b031916815560018101829055600281018290556003810182905560048101805460ff19169055600501555b5050600101610d70565b610e8f6113de565b610e9761140b565b600e5415610fdc57600e545f90610eb09060019061295b565b90505f600e8281548110610ec657610ec661283a565b5f918252602080832090910154808352600d90915260409091208054919250906001600160a01b031615610fb05760025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92610f2c923092909116908790600401612918565b5f604051808303815f87803b158015610f43575f80fd5b505af1158015610f55573d5f803e3d5ffd5b50508254610f6f92506001600160a01b0316905083611e76565b5f828152600d6020526040812080546001600160a01b031916815560018101829055600281018290556003810182905560048101805460ff19169055600501555b600e805480610fc157610fc161296e565b600190038181905f5260205f20015f90559055505050610e97565b6108bb60015f55565b610fed61140b565b5f811161102f5760405162461bcd60e51b815260206004820152601060248201526f043616e6e6f74206465706f73697420360841b604482015260640161054a565b6003546040516323b872dd60e01b81525f916001600160a01b0316906323b872dd9061106390339030908790600401612918565b6020604051808303815f875af115801561107f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a3919061293c565b9050806110e85760405162461bcd60e51b81526020600482015260136024820152721d1c985b9cd9995c919c9bdb4819985a5b1959606a1b604482015260640161054a565b60405182815233907f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e9060200160405180910390a250610bf560015f55565b61112f61140b565b5f5b818110156107b0575f83838381811061114c5761114c61283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b031633146111905760405162461bcd60e51b815260040161054a9061284e565b61119981611f8c565b50600101611131565b6111aa6113de565b600695909555600793909355600891909155600955600a55600b55565b6111cf6113de565b6001600160a01b0381166111f857604051631e4fbdf760e01b81525f600482015260240161054a565b610bf581611b87565b60605f8267ffffffffffffffff81111561121d5761121d612904565b604051908082528060200260200182016040528015611246578160200160208202803683370190505b5090505f5b83811015611299576112748585838181106112685761126861283a565b90506020020135612155565b8282815181106112865761128661283a565b602090810291909101015260010161124b565b5090505b92915050565b600e546060905f8167ffffffffffffffff8111156112c3576112c3612904565b6040519080825280602002602001820160405280156112fc57816020015b6112e96124d9565b8152602001906001900390816112e15790505b5090505f5b828110156113d7575f600e828154811061131d5761131d61283a565b5f918252602080832090910154808352600d8252604092839020835160c08101855281546001600160a01b0316815260018201549381019390935260028101549383019390935260038084015460608401526004840154919450919291608084019160ff16908111156113925761139261265e565b60038111156113a3576113a361265e565b81526020016005820154815250508383815181106113c3576113c361283a565b602090810291909101015250600101611301565b5092915050565b6001546001600160a01b031633146108bb5760405163118cdaa760e01b815233600482015260240161054a565b60025f540361145c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161054a565b60025f55565b5f828152600d6020526040902080546001600160a01b03166114b35760405162461bcd60e51b815260206004820152600a602482015269139bdd081cdd185ad95960b21b604482015260640161054a565b5f600482015460ff1660038111156114cd576114cd61265e565b146115445760048101545f906114e59060ff16612402565b82600501546114f491906128f1565b9050804210156115425760405162461bcd60e51b815260206004820152601960248201527810dd5c9c995b9d081b1bd8dac81b9bdd08199a5b9a5cda1959603a1b604482015260640161054a565b505b61154d836115ce565b5060048101805483919060ff1916600183600381111561156f5761156f61265e565b02179055504260058201819055600382015580546040516001600160a01b03909116907f60f10efe42a59033e0f0d69d2e985d0dda173e5b56058f8aab1db6a4a8d974f3906115c19086908690612982565b60405180910390a2505050565b5f818152600d60205260408120600381015442908082116115f357505f949350505050565b5f6115fe828461295b565b90505f8080600487015460ff16600381111561161c5761161c61265e565b146116465760048601546116329060ff16612402565b866005015461164191906128f1565b611648565b5f5b90505f600487015460ff1660038111156116645761166461265e565b146117f95780841015611793575f81861061167f5781611681565b855b90505f858211611691575f61169b565b61169b868361295b565b90505f600454826116ac91906128d2565b60048a01549091505f906116c29060ff1661246d565b90505f6064826005546116d591906128bb565b6116df91906128d2565b5f8e8152600c60205260408120549192508190036116fb575060645b5f606461170883856128bb565b61171291906128d2565b61171c90866128bb565b9050611728818a6128f1565b9850878c1115611787575f61173d898e61295b565b90505f6004548261174e91906128d2565b90505f60648560055461176191906128bb565b61176b91906128d2565b905061177781836128bb565b611781908d6128f1565b9b505050505b5050505050505061185b565b5f600454846117a291906128d2565b5f8a8152600c60205260408120549192508190036117be575060645b5f6064826005546117cf91906128bb565b6117d991906128d2565b90506117e581846128bb565b6117ef90866128f1565b945050505061185b565b5f6004548461180891906128d2565b5f8a8152600c6020526040812054919250819003611824575060645b5f60648260055461183591906128bb565b61183f91906128d2565b905061184b81846128bb565b61185590866128f1565b94505050505b6003860185905581156119ef576003546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa1580156118ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118d29190612890565b9050828110156119305760405162461bcd60e51b8152602060048201526024808201527f4e6f7420656e6f7567682072657761726420746f6b656e7320696e20636f6e746044820152631c9858dd60e21b606482015260840161054a565b600354875460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810186905291169063a9059cbb906044016020604051808303815f875af1158015611981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119a5919061293c565b508654604080518b8152602081018690526001600160a01b03909216917ff01da32686223933d8a18a391060918c7f11a3648639edd87ae013e2e2731743910160405180910390a2505b509695505050505050565b6002546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611a2e90339030908790600401612918565b5f604051808303815f87803b158015611a45575f80fd5b505af1158015611a57573d5f803e3d5ffd5b5050505f838152600d6020526040902080546001600160a01b03191633178155600180820185905542600283018190556003808401919091556004830180549394508593909260ff19909116918490811115611ab557611ab561265e565b02179055505f826003811115611acd57611acd61265e565b14611ad85742611ada565b5f5b6005820155611b2683600e80545f838152600f60205260408120829055600182018355919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0155565b335f8181526010602081815260408084208054898652601184528286208190559383526001840181558452922001859055517f8acf475137e0cd74ca7f611d16b1e6383ec9a9c71a8e5b85967781b9c7214d11906115c19086908690612982565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f8080600484015460ff166003811115611bf457611bf461265e565b03611c0457506064925f92509050565b60048301545f90611c179060ff16612402565b90505f818560050154611c2a91906128f1565b6004860154909150428211905f90611c449060ff1661246d565b9791965090945050505050565b5f828152600d6020526040812090600482015460ff166003811115611c7857611c7861265e565b03611cc55760405162461bcd60e51b815260206004820152601860248201527f4e4654206e6f742063757272656e746c79206c6f636b65640000000000000000604482015260640161054a565b60048101545f90611cd89060ff16612402565b8260050154611ce791906128f1565b905080421015611d355760405162461bcd60e51b815260206004820152601960248201527810dd5c9c995b9d081b1bd8dac81b9bdd08199a5b9a5cda1959603a1b604482015260640161054a565b611d3e846115ce565b5060048201805484919060ff19166001836003811115611d6057611d6061265e565b02179055504260058301819055600383015581546040516001600160a01b03909116907f60f10efe42a59033e0f0d69d2e985d0dda173e5b56058f8aab1db6a4a8d974f390611db29087908790612982565b60405180910390a250505050565b5f818152600f6020526040812054600e54909190611de09060019061295b565b9050808214611e3b575f600e8281548110611dfd57611dfd61283a565b905f5260205f200154905080600e8481548110611e1c57611e1c61283a565b5f918252602080832090910192909255918252600f9052604090208290555b600e805480611e4c57611e4c61296e565b5f828152602080822083015f19908101839055909201909255938152600f90935250506040812055565b5f818152601160209081526040808320546001600160a01b03861684526010909252822054909190611eaa9060019061295b565b9050808214611f3b576001600160a01b0384165f908152601060205260408120805483908110611edc57611edc61283a565b905f5260205f20015490508060105f876001600160a01b03166001600160a01b031681526020019081526020015f208481548110611f1c57611f1c61283a565b5f91825260208083209091019290925591825260119052604090208290555b6001600160a01b0384165f908152601060205260409020805480611f6157611f6161296e565b5f828152602080822083015f1990810183905590920190925593815260119093525050604081205550565b5f818152600d6020526040812090600482015460ff166003811115611fb357611fb361265e565b146120405760048101545f90611fcb9060ff16612402565b8260050154611fda91906128f1565b90508042101561203e5760405162461bcd60e51b815260206004820152602960248201527f4c6f636b20706572696f64206e6f74206f7665722e2043616e6e6f7420756e736044820152683a30b5b2903cb2ba1760b91b606482015260840161054a565b505b612049826115ce565b5060025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92612082923092909116908790600401612918565b5f604051808303815f87803b158015612099575f80fd5b505af11580156120ab573d5f803e3d5ffd5b505050506120b882611dc0565b80546120cd906001600160a01b031683611e76565b5f828152600d6020908152604080832080546001600160a01b031916815560018101849055600281018490556003810184905560048101805460ff1916905560050192909255825491518481526001600160a01b03909216917f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75910160405180910390a25050565b5f818152600d6020526040812080546001600160a01b031661217957505f92915050565b6003810154429080821161219157505f949350505050565b5f61219c828461295b565b90505f8080600487015460ff1660038111156121ba576121ba61265e565b146121e45760048601546121d09060ff16612402565b86600501546121df91906128f1565b6121e6565b5f5b90505f600487015460ff1660038111156122025761220261265e565b146123975780841015612331575f81861061221d578161221f565b855b90505f85821161222f575f612239565b612239868361295b565b90505f6004548261224a91906128d2565b60048a01549091505f906122609060ff1661246d565b90505f60648260055461227391906128bb565b61227d91906128d2565b5f8e8152600c6020526040812054919250819003612299575060645b5f60646122a683856128bb565b6122b091906128d2565b6122ba90866128bb565b90506122c6818a6128f1565b9850878c1115612325575f6122db898e61295b565b90505f600454826122ec91906128d2565b90505f6064856005546122ff91906128bb565b61230991906128d2565b905061231581836128bb565b61231f908d6128f1565b9b505050505b505050505050506119ef565b5f6004548461234091906128d2565b5f8a8152600c602052604081205491925081900361235c575060645b5f60648260055461236d91906128bb565b61237791906128d2565b905061238381846128bb565b61238d90866128f1565b94505050506119ef565b5f600454846123a691906128d2565b5f8a8152600c60205260408120549192508190036123c2575060645b5f6064826005546123d391906128bb565b6123dd91906128d2565b90506123e981846128bb565b6123f390866128f1565b9b9a5050505050505050505050565b5f60018260038111156124175761241761265e565b0361242457505060065490565b60028260038111156124385761243861265e565b0361244557505060085490565b60038260038111156124595761245961265e565b03612466575050600a5490565b505f919050565b5f60018260038111156124825761248261265e565b0361248f57505060075490565b60028260038111156124a3576124a361265e565b036124b057505060095490565b60038260038111156124c4576124c461265e565b036124d1575050600b5490565b506064919050565b6040518060c001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f60038111156125175761251761265e565b81526020015f81525090565b5f60208284031215612533575f80fd5b5035919050565b5f8083601f84011261254a575f80fd5b50813567ffffffffffffffff811115612561575f80fd5b6020830191508360208260051b850101111561257b575f80fd5b9250929050565b5f805f8060408587031215612595575f80fd5b843567ffffffffffffffff808211156125ac575f80fd5b6125b88883890161253a565b909650945060208701359150808211156125d0575f80fd5b506125dd8782880161253a565b95989497509550505050565b6001600160a01b0381168114610bf5575f80fd5b5f6020828403121561260d575f80fd5b8135612618816125e9565b9392505050565b5f8060208385031215612630575f80fd5b823567ffffffffffffffff811115612646575f80fd5b6126528582860161253a565b90969095509350505050565b634e487b7160e01b5f52602160045260245ffd5b6004811061268e57634e487b7160e01b5f52602160045260245ffd5b9052565b602080825282518282018190525f919060409081850190868401855b8281101561270f57815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080808201516126f182880182612672565b505060a0908101519085015260c090930192908501906001016126ae565b5091979650505050505050565b5f806040838503121561272d575f80fd5b8235612738816125e9565b946020939093013593505050565b6001600160a01b038716815260208101869052604081018590526060810184905260c081016127786080830185612672565b8260a0830152979650505050505050565b5f805f805f8060c0878903121561279e575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b602080825282518282018190525f9190848201906040850190845b818110156127ff578351835292840192918401916001016127e3565b50909695505050505050565b602080825260159082015274082e4e4c2f240d8cadccee8d040dad2e6dac2e8c6d605b1b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b6020808252600a90820152692737ba1039ba30b5b2b960b11b604082015260600190565b5f60208284031215612882575f80fd5b813560048110612618575f80fd5b5f602082840312156128a0575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761129d5761129d6128a7565b5f826128ec57634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561129d5761129d6128a7565b634e487b7160e01b5f52604160045260245ffd5b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f6020828403121561294c575f80fd5b81518015158114612618575f80fd5b8181038181111561129d5761129d6128a7565b634e487b7160e01b5f52603160045260245ffd5b82815260408101612618602083018461267256fea2646970667358221220d6512025beb4d0383dcc5a6a0d4bae55bc44f6a8ca78f3af309df7f9a9bf123b64736f6c634300081800330000000000000000000000003303c4350259c2b8f3c560b2ec70ad3ed87a5e72

Deployed Bytecode

0x608060405234801561000f575f80fd5b5060043610610229575f3560e01c80638da5cb5b1161012a578063dbb7a621116100b4578063f7c618c111610079578063f7c618c1146104c9578063f7e455d7146104dc578063fae40fa0146104fc578063fb64455b14610505578063ffd2d8291461050d575f80fd5b8063dbb7a62114610475578063dd49756e1461047d578063e64a21f314610490578063efdd78e1146104a3578063f2fde38b146104b6575f80fd5b8063b2040612116100fa578063b2040612146103cf578063b865749d146103d8578063bf4bac391461043c578063d3abfe121461044f578063d56d229d14610462575f80fd5b80638da5cb5b1461038f57806399ba918d146103b45780639ce98f0e146103bd578063ae63586c146103c6575f80fd5b806370becf5d116101b6578063817b1cd21161017b578063817b1cd21461032e578063888ce4af1461033657806388c0771b146103565780638aee8127146103695780638cd4426d1461037c575f80fd5b806370becf5d146102d8578063715018a6146102e1578063760edace146102e95780637dc3db8f146102fc5780637f4ca1d71461030f575f80fd5b8063454aa669116101fc578063454aa6691461028457806352f5ad7714610297578063646e6f8b146102aa57806366e4664a146102bd5780636f9fb98a146102d0575f80fd5b80630dfa1e961461022d578063224eb12914610249578063398612b81461025e5780633af7a79514610271575b5f80fd5b61023660085481565b6040519081526020015b60405180910390f35b61025c610257366004612523565b610516565b005b61025c61026c366004612582565b610523565b61025c61027f366004612582565b6105fd565b61025c610292366004612523565b610684565b61025c6102a53660046125fd565b61070a565b61025c6102b836600461261f565b610734565b61025c6102cb366004612582565b6107ba565b61023661083b565b610236600a5481565b61025c6108aa565b6102366102f73660046125fd565b6108bd565b61025c61030a366004612523565b610a0e565b61023661031d366004612523565b600c6020525f908152604090205481565b600e54610236565b6103496103443660046125fd565b610a1b565b6040516102409190612692565b61025c610364366004612523565b610b6c565b61025c6103773660046125fd565b610bf8565b61025c61038a36600461271c565b610c22565b6001546001600160a01b03165b6040516001600160a01b039091168152602001610240565b61023660055481565b61023660065481565b61023660045481565b610236600b5481565b61042a6103e6366004612523565b600d6020525f90815260409020805460018201546002830154600384015460048501546005909501546001600160a01b039094169492939192909160ff9091169086565b60405161024096959493929190612746565b61025c61044a366004612582565b610c9d565b61025c61045d36600461261f565b610d5e565b60025461039c906001600160a01b031681565b61025c610e87565b61025c61048b366004612523565b610fe5565b61025c61049e36600461261f565b611127565b61025c6104b1366004612789565b6111a2565b61025c6104c43660046125fd565b6111c7565b60035461039c906001600160a01b031681565b6104ef6104ea36600461261f565b611201565b60405161024091906127c8565b61023660095481565b6103496112a3565b61023660075481565b61051e6113de565b600455565b61052b61140b565b8281146105535760405162461bcd60e51b815260040161054a9061280b565b60405180910390fd5b5f5b838110156105ed575f8585838181106105705761057061283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b031633146105b45760405162461bcd60e51b815260040161054a9061284e565b6105e4818585858181106105ca576105ca61283a565b90506020020160208101906105df9190612872565b611462565b50600101610555565b506105f760015f55565b50505050565b6106056113de565b8281146106245760405162461bcd60e51b815260040161054a9061280b565b5f5b8381101561067d578282828181106106405761064061283a565b90506020020135600c5f87878581811061065c5761065c61283a565b602090810292909201358352508101919091526040015f2055600101610626565b5050505050565b61068c6113de565b804710156106dc5760405162461bcd60e51b815260206004820152601960248201527f4e6f7420656e6f756768206e61746976652062616c616e636500000000000000604482015260640161054a565b604051339082156108fc029083905f818181858888f19350505050158015610706573d5f803e3d5ffd5b5050565b6107126113de565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b61073c61140b565b5f5b818110156107b0575f8383838181106107595761075961283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b0316331461079d5760405162461bcd60e51b815260040161054a9061284e565b6107a6816115ce565b505060010161073e565b5061070660015f55565b6107c261140b565b8281146107e15760405162461bcd60e51b815260040161054a9061280b565b5f5b838110156105ed576108338585838181106108005761080061283a565b905060200201358484848181106108195761081961283a565b905060200201602081019061082e9190612872565b6119fa565b6001016107e3565b6003546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015610881573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a59190612890565b905090565b6108b26113de565b6108bb5f611b87565b565b6001600160a01b0381165f90815260106020908152604080832080548251818502810185019093528083528493849392919083018282801561091c57602002820191905f5260205f20905b815481526020019060010190808311610908575b505050505090505f5b8151811015610a05575f8282815181106109415761094161283a565b6020908102919091018101515f818152600d90925260409091208054919250906001600160a01b0388811691161461097a5750506109fd565b5f8061098583611bd8565b915091505f81156109b1576064836005546109a091906128bb565b6109aa91906128d2565b90506109b6565b506005545b5f858152600c6020526040812054908190036109d0575060645b5f60646109dd83856128bb565b6109e791906128d2565b90506109f3818b6128f1565b9950505050505050505b600101610925565b50909392505050565b610a166113de565b600555565b6001600160a01b0381165f90815260106020526040812080546060928167ffffffffffffffff811115610a5057610a50612904565b604051908082528060200260200182016040528015610a8957816020015b610a766124d9565b815260200190600190039081610a6e5790505b5090505f5b82811015610b63575f848281548110610aa957610aa961283a565b5f918252602080832090910154808352600d8252604092839020835160c08101855281546001600160a01b0316815260018201549381019390935260028101549383019390935260038084015460608401526004840154919450919291608084019160ff1690811115610b1e57610b1e61265e565b6003811115610b2f57610b2f61265e565b8152602001600582015481525050838381518110610b4f57610b4f61283a565b602090810291909101015250600101610a8e565b50949350505050565b610b746113de565b610b7c61140b565b6002546001600160a01b03166323b872dd30610ba06001546001600160a01b031690565b846040518463ffffffff1660e01b8152600401610bbf93929190612918565b5f604051808303815f87803b158015610bd6575f80fd5b505af1158015610be8573d5f803e3d5ffd5b50505050610bf560015f55565b50565b610c006113de565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b610c2a6113de565b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303815f875af1158015610c74573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c98919061293c565b505050565b610ca561140b565b828114610cc45760405162461bcd60e51b815260040161054a9061280b565b5f5b838110156105ed575f858583818110610ce157610ce161283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b03163314610d255760405162461bcd60e51b815260040161054a9061284e565b610d5581858585818110610d3b57610d3b61283a565b9050602002016020810190610d509190612872565b611c51565b50600101610cc6565b610d666113de565b610d6e61140b565b5f5b818110156107b0575f838383818110610d8b57610d8b61283a565b602090810292909201355f818152600d90935260409092208054929350916001600160a01b0316159050610e7d5760025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92610df1923092909116908790600401612918565b5f604051808303815f87803b158015610e08575f80fd5b505af1158015610e1a573d5f803e3d5ffd5b50505050610e2782611dc0565b8054610e3c906001600160a01b031683611e76565b5f828152600d6020526040812080546001600160a01b031916815560018101829055600281018290556003810182905560048101805460ff19169055600501555b5050600101610d70565b610e8f6113de565b610e9761140b565b600e5415610fdc57600e545f90610eb09060019061295b565b90505f600e8281548110610ec657610ec661283a565b5f918252602080832090910154808352600d90915260409091208054919250906001600160a01b031615610fb05760025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92610f2c923092909116908790600401612918565b5f604051808303815f87803b158015610f43575f80fd5b505af1158015610f55573d5f803e3d5ffd5b50508254610f6f92506001600160a01b0316905083611e76565b5f828152600d6020526040812080546001600160a01b031916815560018101829055600281018290556003810182905560048101805460ff19169055600501555b600e805480610fc157610fc161296e565b600190038181905f5260205f20015f90559055505050610e97565b6108bb60015f55565b610fed61140b565b5f811161102f5760405162461bcd60e51b815260206004820152601060248201526f043616e6e6f74206465706f73697420360841b604482015260640161054a565b6003546040516323b872dd60e01b81525f916001600160a01b0316906323b872dd9061106390339030908790600401612918565b6020604051808303815f875af115801561107f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a3919061293c565b9050806110e85760405162461bcd60e51b81526020600482015260136024820152721d1c985b9cd9995c919c9bdb4819985a5b1959606a1b604482015260640161054a565b60405182815233907f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e9060200160405180910390a250610bf560015f55565b61112f61140b565b5f5b818110156107b0575f83838381811061114c5761114c61283a565b602090810292909201355f818152600d909352604090922054919250506001600160a01b031633146111905760405162461bcd60e51b815260040161054a9061284e565b61119981611f8c565b50600101611131565b6111aa6113de565b600695909555600793909355600891909155600955600a55600b55565b6111cf6113de565b6001600160a01b0381166111f857604051631e4fbdf760e01b81525f600482015260240161054a565b610bf581611b87565b60605f8267ffffffffffffffff81111561121d5761121d612904565b604051908082528060200260200182016040528015611246578160200160208202803683370190505b5090505f5b83811015611299576112748585838181106112685761126861283a565b90506020020135612155565b8282815181106112865761128661283a565b602090810291909101015260010161124b565b5090505b92915050565b600e546060905f8167ffffffffffffffff8111156112c3576112c3612904565b6040519080825280602002602001820160405280156112fc57816020015b6112e96124d9565b8152602001906001900390816112e15790505b5090505f5b828110156113d7575f600e828154811061131d5761131d61283a565b5f918252602080832090910154808352600d8252604092839020835160c08101855281546001600160a01b0316815260018201549381019390935260028101549383019390935260038084015460608401526004840154919450919291608084019160ff16908111156113925761139261265e565b60038111156113a3576113a361265e565b81526020016005820154815250508383815181106113c3576113c361283a565b602090810291909101015250600101611301565b5092915050565b6001546001600160a01b031633146108bb5760405163118cdaa760e01b815233600482015260240161054a565b60025f540361145c5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161054a565b60025f55565b5f828152600d6020526040902080546001600160a01b03166114b35760405162461bcd60e51b815260206004820152600a602482015269139bdd081cdd185ad95960b21b604482015260640161054a565b5f600482015460ff1660038111156114cd576114cd61265e565b146115445760048101545f906114e59060ff16612402565b82600501546114f491906128f1565b9050804210156115425760405162461bcd60e51b815260206004820152601960248201527810dd5c9c995b9d081b1bd8dac81b9bdd08199a5b9a5cda1959603a1b604482015260640161054a565b505b61154d836115ce565b5060048101805483919060ff1916600183600381111561156f5761156f61265e565b02179055504260058201819055600382015580546040516001600160a01b03909116907f60f10efe42a59033e0f0d69d2e985d0dda173e5b56058f8aab1db6a4a8d974f3906115c19086908690612982565b60405180910390a2505050565b5f818152600d60205260408120600381015442908082116115f357505f949350505050565b5f6115fe828461295b565b90505f8080600487015460ff16600381111561161c5761161c61265e565b146116465760048601546116329060ff16612402565b866005015461164191906128f1565b611648565b5f5b90505f600487015460ff1660038111156116645761166461265e565b146117f95780841015611793575f81861061167f5781611681565b855b90505f858211611691575f61169b565b61169b868361295b565b90505f600454826116ac91906128d2565b60048a01549091505f906116c29060ff1661246d565b90505f6064826005546116d591906128bb565b6116df91906128d2565b5f8e8152600c60205260408120549192508190036116fb575060645b5f606461170883856128bb565b61171291906128d2565b61171c90866128bb565b9050611728818a6128f1565b9850878c1115611787575f61173d898e61295b565b90505f6004548261174e91906128d2565b90505f60648560055461176191906128bb565b61176b91906128d2565b905061177781836128bb565b611781908d6128f1565b9b505050505b5050505050505061185b565b5f600454846117a291906128d2565b5f8a8152600c60205260408120549192508190036117be575060645b5f6064826005546117cf91906128bb565b6117d991906128d2565b90506117e581846128bb565b6117ef90866128f1565b945050505061185b565b5f6004548461180891906128d2565b5f8a8152600c6020526040812054919250819003611824575060645b5f60648260055461183591906128bb565b61183f91906128d2565b905061184b81846128bb565b61185590866128f1565b94505050505b6003860185905581156119ef576003546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa1580156118ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118d29190612890565b9050828110156119305760405162461bcd60e51b8152602060048201526024808201527f4e6f7420656e6f7567682072657761726420746f6b656e7320696e20636f6e746044820152631c9858dd60e21b606482015260840161054a565b600354875460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810186905291169063a9059cbb906044016020604051808303815f875af1158015611981573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119a5919061293c565b508654604080518b8152602081018690526001600160a01b03909216917ff01da32686223933d8a18a391060918c7f11a3648639edd87ae013e2e2731743910160405180910390a2505b509695505050505050565b6002546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90611a2e90339030908790600401612918565b5f604051808303815f87803b158015611a45575f80fd5b505af1158015611a57573d5f803e3d5ffd5b5050505f838152600d6020526040902080546001600160a01b03191633178155600180820185905542600283018190556003808401919091556004830180549394508593909260ff19909116918490811115611ab557611ab561265e565b02179055505f826003811115611acd57611acd61265e565b14611ad85742611ada565b5f5b6005820155611b2683600e80545f838152600f60205260408120829055600182018355919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0155565b335f8181526010602081815260408084208054898652601184528286208190559383526001840181558452922001859055517f8acf475137e0cd74ca7f611d16b1e6383ec9a9c71a8e5b85967781b9c7214d11906115c19086908690612982565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f8080600484015460ff166003811115611bf457611bf461265e565b03611c0457506064925f92509050565b60048301545f90611c179060ff16612402565b90505f818560050154611c2a91906128f1565b6004860154909150428211905f90611c449060ff1661246d565b9791965090945050505050565b5f828152600d6020526040812090600482015460ff166003811115611c7857611c7861265e565b03611cc55760405162461bcd60e51b815260206004820152601860248201527f4e4654206e6f742063757272656e746c79206c6f636b65640000000000000000604482015260640161054a565b60048101545f90611cd89060ff16612402565b8260050154611ce791906128f1565b905080421015611d355760405162461bcd60e51b815260206004820152601960248201527810dd5c9c995b9d081b1bd8dac81b9bdd08199a5b9a5cda1959603a1b604482015260640161054a565b611d3e846115ce565b5060048201805484919060ff19166001836003811115611d6057611d6061265e565b02179055504260058301819055600383015581546040516001600160a01b03909116907f60f10efe42a59033e0f0d69d2e985d0dda173e5b56058f8aab1db6a4a8d974f390611db29087908790612982565b60405180910390a250505050565b5f818152600f6020526040812054600e54909190611de09060019061295b565b9050808214611e3b575f600e8281548110611dfd57611dfd61283a565b905f5260205f200154905080600e8481548110611e1c57611e1c61283a565b5f918252602080832090910192909255918252600f9052604090208290555b600e805480611e4c57611e4c61296e565b5f828152602080822083015f19908101839055909201909255938152600f90935250506040812055565b5f818152601160209081526040808320546001600160a01b03861684526010909252822054909190611eaa9060019061295b565b9050808214611f3b576001600160a01b0384165f908152601060205260408120805483908110611edc57611edc61283a565b905f5260205f20015490508060105f876001600160a01b03166001600160a01b031681526020019081526020015f208481548110611f1c57611f1c61283a565b5f91825260208083209091019290925591825260119052604090208290555b6001600160a01b0384165f908152601060205260409020805480611f6157611f6161296e565b5f828152602080822083015f1990810183905590920190925593815260119093525050604081205550565b5f818152600d6020526040812090600482015460ff166003811115611fb357611fb361265e565b146120405760048101545f90611fcb9060ff16612402565b8260050154611fda91906128f1565b90508042101561203e5760405162461bcd60e51b815260206004820152602960248201527f4c6f636b20706572696f64206e6f74206f7665722e2043616e6e6f7420756e736044820152683a30b5b2903cb2ba1760b91b606482015260840161054a565b505b612049826115ce565b5060025481546040516323b872dd60e01b81526001600160a01b03928316926323b872dd92612082923092909116908790600401612918565b5f604051808303815f87803b158015612099575f80fd5b505af11580156120ab573d5f803e3d5ffd5b505050506120b882611dc0565b80546120cd906001600160a01b031683611e76565b5f828152600d6020908152604080832080546001600160a01b031916815560018101849055600281018490556003810184905560048101805460ff1916905560050192909255825491518481526001600160a01b03909216917f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75910160405180910390a25050565b5f818152600d6020526040812080546001600160a01b031661217957505f92915050565b6003810154429080821161219157505f949350505050565b5f61219c828461295b565b90505f8080600487015460ff1660038111156121ba576121ba61265e565b146121e45760048601546121d09060ff16612402565b86600501546121df91906128f1565b6121e6565b5f5b90505f600487015460ff1660038111156122025761220261265e565b146123975780841015612331575f81861061221d578161221f565b855b90505f85821161222f575f612239565b612239868361295b565b90505f6004548261224a91906128d2565b60048a01549091505f906122609060ff1661246d565b90505f60648260055461227391906128bb565b61227d91906128d2565b5f8e8152600c6020526040812054919250819003612299575060645b5f60646122a683856128bb565b6122b091906128d2565b6122ba90866128bb565b90506122c6818a6128f1565b9850878c1115612325575f6122db898e61295b565b90505f600454826122ec91906128d2565b90505f6064856005546122ff91906128bb565b61230991906128d2565b905061231581836128bb565b61231f908d6128f1565b9b505050505b505050505050506119ef565b5f6004548461234091906128d2565b5f8a8152600c602052604081205491925081900361235c575060645b5f60648260055461236d91906128bb565b61237791906128d2565b905061238381846128bb565b61238d90866128f1565b94505050506119ef565b5f600454846123a691906128d2565b5f8a8152600c60205260408120549192508190036123c2575060645b5f6064826005546123d391906128bb565b6123dd91906128d2565b90506123e981846128bb565b6123f390866128f1565b9b9a5050505050505050505050565b5f60018260038111156124175761241761265e565b0361242457505060065490565b60028260038111156124385761243861265e565b0361244557505060085490565b60038260038111156124595761245961265e565b03612466575050600a5490565b505f919050565b5f60018260038111156124825761248261265e565b0361248f57505060075490565b60028260038111156124a3576124a361265e565b036124b057505060095490565b60038260038111156124c4576124c461265e565b036124d1575050600b5490565b506064919050565b6040518060c001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f60038111156125175761251761265e565b81526020015f81525090565b5f60208284031215612533575f80fd5b5035919050565b5f8083601f84011261254a575f80fd5b50813567ffffffffffffffff811115612561575f80fd5b6020830191508360208260051b850101111561257b575f80fd5b9250929050565b5f805f8060408587031215612595575f80fd5b843567ffffffffffffffff808211156125ac575f80fd5b6125b88883890161253a565b909650945060208701359150808211156125d0575f80fd5b506125dd8782880161253a565b95989497509550505050565b6001600160a01b0381168114610bf5575f80fd5b5f6020828403121561260d575f80fd5b8135612618816125e9565b9392505050565b5f8060208385031215612630575f80fd5b823567ffffffffffffffff811115612646575f80fd5b6126528582860161253a565b90969095509350505050565b634e487b7160e01b5f52602160045260245ffd5b6004811061268e57634e487b7160e01b5f52602160045260245ffd5b9052565b602080825282518282018190525f919060409081850190868401855b8281101561270f57815180516001600160a01b0316855286810151878601528581015186860152606080820151908601526080808201516126f182880182612672565b505060a0908101519085015260c090930192908501906001016126ae565b5091979650505050505050565b5f806040838503121561272d575f80fd5b8235612738816125e9565b946020939093013593505050565b6001600160a01b038716815260208101869052604081018590526060810184905260c081016127786080830185612672565b8260a0830152979650505050505050565b5f805f805f8060c0878903121561279e575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b602080825282518282018190525f9190848201906040850190845b818110156127ff578351835292840192918401916001016127e3565b50909695505050505050565b602080825260159082015274082e4e4c2f240d8cadccee8d040dad2e6dac2e8c6d605b1b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b6020808252600a90820152692737ba1039ba30b5b2b960b11b604082015260600190565b5f60208284031215612882575f80fd5b813560048110612618575f80fd5b5f602082840312156128a0575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761129d5761129d6128a7565b5f826128ec57634e487b7160e01b5f52601260045260245ffd5b500490565b8082018082111561129d5761129d6128a7565b634e487b7160e01b5f52604160045260245ffd5b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f6020828403121561294c575f80fd5b81518015158114612618575f80fd5b8181038181111561129d5761129d6128a7565b634e487b7160e01b5f52603160045260245ffd5b82815260408101612618602083018461267256fea2646970667358221220d6512025beb4d0383dcc5a6a0d4bae55bc44f6a8ca78f3af309df7f9a9bf123b64736f6c63430008180033

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

0000000000000000000000003303c4350259c2b8f3c560b2ec70ad3ed87a5e72

-----Decoded View---------------
Arg [0] : _initialOwner (address): 0x3303C4350259C2B8F3C560B2ec70aD3ed87A5E72

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000003303c4350259c2b8f3c560b2ec70ad3ed87a5e72


Deployed Bytecode Sourcemap

16470:28667:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17549:39;;;;;;;;;160:25:1;;;148:2;133:18;17549:39:0;;;;;;;;20265:104;;;;;;:::i;:::-;;:::i;:::-;;24617:488;;;;;;:::i;:::-;;:::i;21438:334::-;;;;;;:::i;:::-;;:::i;21893:195::-;;;;;;:::i;:::-;;:::i;20030:110::-;;;;;;:::i;:::-;;:::i;24019:315::-;;;;;;:::i;:::-;;:::i;23159:329::-;;;;;;:::i;:::-;;:::i;22685:124::-;;;:::i;17649:39::-;;;;;;15344:103;;;:::i;26564:1203::-;;;;;;:::i;:::-;;:::i;20377:110::-;;;;;;:::i;:::-;;:::i;17882:48::-;;;;;;:::i;:::-;;;;;;;;;;;;;;38381:105;38454:17;:24;38381:105;;38877:436;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;44975:157::-;;;;;;:::i;:::-;;:::i;20148:109::-;;;;;;:::i;:::-;;:::i;22096:136::-;;;;;;:::i;:::-;;:::i;14669:87::-;14742:6;;-1:-1:-1;;;;;14742:6:0;14669:87;;;-1:-1:-1;;;;;5771:32:1;;;5753:51;;5741:2;5726:18;14669:87:0;5607:203:1;17238:41:0;;;;;;17449:39;;;;;;17057:36;;;;;;17695:37;;;;;;18662:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18662:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;25305:457::-;;;;;;:::i;:::-;;:::i;42824:834::-;;;;;;:::i;:::-;;:::i;16716:80::-;;;;;-1:-1:-1;;;;;16716:80:0;;;43861:871;;;:::i;22372:305::-;;;;;;:::i;:::-;;:::i;23623:313::-;;;;;;:::i;:::-;;:::i;20669:541::-;;;;;;:::i;:::-;;:::i;15602:220::-;;;;;;:::i;:::-;;:::i;16897:78::-;;;;;-1:-1:-1;;;;;16897:78:0;;;26034:336;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;17595:37::-;;;;;;38494:375;;;:::i;17495:37::-;;;;;;20265:104;14555:13;:11;:13::i;:::-;20338:12:::1;:23:::0;20265:104::o;24617:488::-;11195:21;:19;:21::i;:::-;24778:39;;::::1;24770:73;;;;-1:-1:-1::0;;;24770:73:0::1;;;;;;;:::i;:::-;;;;;;;;;24859:9;24854:244;24874:20:::0;;::::1;24854:244;;;24916:15;24934:9;;24944:1;24934:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;24969:19;::::0;;;:10:::1;:19:::0;;;;;;;:25;24934:12;;-1:-1:-1;;;;;;;24969:25:0::1;24998:10;24969:39;24961:62;;;;-1:-1:-1::0;;;24961:62:0::1;;;;;;;:::i;:::-;25038:48;25061:7;25070:12;;25083:1;25070:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;25038:22;:48::i;:::-;-1:-1:-1::0;24896:3:0::1;;24854:244;;;;11239:20:::0;10633:1;11759:7;:22;11576:213;11239:20;24617:488;;;;:::o;21438:334::-;14555:13;:11;:13::i;:::-;21570:39;;::::1;21562:73;;;;-1:-1:-1::0;;;21562:73:0::1;;;;;;;:::i;:::-;21651:9;21646:119;21666:20:::0;;::::1;21646:119;;;21738:12;;21751:1;21738:15;;;;;;;:::i;:::-;;;;;;;21708:13;:27;21722:9;;21732:1;21722:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;21708:27:::0;;-1:-1:-1;21708:27:0;::::1;::::0;;;;;;-1:-1:-1;21708:27:0;:45;21688:3:::1;;21646:119;;;;21438:334:::0;;;;:::o;21893:195::-;14555:13;:11;:13::i;:::-;21995:7:::1;21970:21;:32;;21962:70;;;::::0;-1:-1:-1;;;21962:70:0;;9321:2:1;21962:70:0::1;::::0;::::1;9303:21:1::0;9360:2;9340:18;;;9333:30;9399:27;9379:18;;;9372:55;9444:18;;21962:70:0::1;9119:349:1::0;21962:70:0::1;22043:37;::::0;22051:10:::1;::::0;22043:37;::::1;;;::::0;22072:7;;22043:37:::1;::::0;;;22072:7;22051:10;22043:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;21893:195:::0;:::o;20030:110::-;14555:13;:11;:13::i;:::-;20106:11:::1;:26:::0;;-1:-1:-1;;;;;;20106:26:0::1;-1:-1:-1::0;;;;;20106:26:0;;;::::1;::::0;;;::::1;::::0;;20030:110::o;24019:315::-;11195:21;:19;:21::i;:::-;24114:9:::1;24109:218;24129:20:::0;;::::1;24109:218;;;24171:15;24189:9;;24199:1;24189:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;24224:19;::::0;;;:10:::1;:19:::0;;;;;;;:25;24189:12;;-1:-1:-1;;;;;;;24224:25:0::1;24253:10;24224:39;24216:62;;;;-1:-1:-1::0;;;24216:62:0::1;;;;;;;:::i;:::-;24293:22;24307:7;24293:13;:22::i;:::-;-1:-1:-1::0;;24151:3:0::1;;24109:218;;;;11239:20:::0;10633:1;11759:7;:22;11576:213;23159:329;11195:21;:19;:21::i;:::-;23286:39;;::::1;23278:73;;;;-1:-1:-1::0;;;23278:73:0::1;;;;;;;:::i;:::-;23367:9;23362:119;23382:20:::0;;::::1;23362:119;;;23424:45;23439:9;;23449:1;23439:12;;;;;;;:::i;:::-;;;;;;;23453;;23466:1;23453:15;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;23424:14;:45::i;:::-;23404:3;;23362:119;;22685:124:::0;22765:11;;:36;;-1:-1:-1;;;22765:36:0;;22795:4;22765:36;;;5753:51:1;22738:7:0;;-1:-1:-1;;;;;22765:11:0;;:21;;5726:18:1;;22765:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22758:43;;22685:124;:::o;15344:103::-;14555:13;:11;:13::i;:::-;15409:30:::1;15436:1;15409:18;:30::i;:::-;15344:103::o:0;26564:1203::-;-1:-1:-1;;;;;26713:23:0;;26628:7;26713:23;;;:16;:23;;;;;;;;26685:51;;;;;;;;;;;;;;;;;26628:7;;;;26685:51;26713:23;26685:51;;;26713:23;26685:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26754:9;26749:977;26773:8;:15;26769:1;:19;26749:977;;;26810:15;26828:8;26837:1;26828:11;;;;;;;;:::i;:::-;;;;;;;;;;;;26854:22;26879:19;;;:10;:19;;;;;;;26948:10;;26828:11;;-1:-1:-1;26879:19:0;-1:-1:-1;;;;;26948:19:0;;;:10;;:19;26944:33;;26969:8;;;;26944:33;27046:22;27070:11;27085:33;27113:4;27085:27;:33::i;:::-;27045:73;;;;27133:17;27171:6;27167:293;;;27312:3;27294:14;27275:16;;:33;;;;:::i;:::-;27274:41;;;;:::i;:::-;27262:53;;27167:293;;;-1:-1:-1;27428:16:0;;27167:293;27522:15;27540:22;;;:13;:22;;;;;;;27581:12;;;27577:31;;-1:-1:-1;27605:3:0;27577:31;27625:17;27669:3;27646:19;27658:7;27646:9;:19;:::i;:::-;27645:27;;;;:::i;:::-;27625:47;-1:-1:-1;27687:27:0;27625:47;27687:27;;:::i;:::-;;;26795:931;;;;;;;26749:977;26790:3;;26749:977;;;-1:-1:-1;27745:14:0;;26564:1203;-1:-1:-1;;;26564:1203:0:o;20377:110::-;14555:13;:11;:13::i;:::-;20453:16:::1;:26:::0;20377:110::o;38877:436::-;-1:-1:-1;;;;;39002:25:0;;38973:26;39002:25;;;:16;:25;;;;;39055:15;;38942:18;;39055:15;39109:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;39081:51;;39148:9;39143:139;39167:6;39163:1;:10;39143:139;;;39195:15;39213:8;39222:1;39213:11;;;;;;;;:::i;:::-;;;;;;;;;;;;;39251:19;;;:10;:19;;;;;;;39239:31;;;;;;;;;-1:-1:-1;;;;;39239:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39213:11;;-1:-1:-1;39239:31:0;;39251:19;39239:31;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:6;39246:1;39239:9;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;39175:3:0;;39143:139;;;-1:-1:-1;39299:6:0;38877:436;-1:-1:-1;;;;38877:436:0:o;44975:157::-;14555:13;:11;:13::i;:::-;11195:21:::1;:19;:21::i;:::-;45066:11:::2;::::0;-1:-1:-1;;;;;45066:11:0::2;:24;45099:4;45106:7;14742:6:::0;;-1:-1:-1;;;;;14742:6:0;;14669:87;45106:7:::2;45115:8;45066:58;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;11239:20:::1;10633:1:::0;11759:7;:22;11576:213;11239:20:::1;44975:157:::0;:::o;20148:109::-;14555:13;:11;:13::i;:::-;20223:11:::1;:26:::0;;-1:-1:-1;;;;;;20223:26:0::1;-1:-1:-1::0;;;;;20223:26:0;;;::::1;::::0;;;::::1;::::0;;20148:109::o;22096:136::-;14555:13;:11;:13::i;:::-;22180:44:::1;::::0;-1:-1:-1;;;22180:44:0;;22204:10:::1;22180:44;::::0;::::1;11005:51:1::0;11072:18;;;11065:34;;;-1:-1:-1;;;;;22180:23:0;::::1;::::0;::::1;::::0;10978:18:1;;22180:44:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;22096:136:::0;;:::o;25305:457::-;11195:21;:19;:21::i;:::-;25436:42;;::::1;25428:76;;;;-1:-1:-1::0;;;25428:76:0::1;;;;;;;:::i;:::-;25520:9;25515:240;25535:20:::0;;::::1;25515:240;;;25577:15;25595:9;;25605:1;25595:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;25630:19;::::0;;;:10:::1;:19:::0;;;;;;;:25;25595:12;;-1:-1:-1;;;;;;;25630:25:0::1;25659:10;25630:39;25622:62;;;;-1:-1:-1::0;;;25622:62:0::1;;;;;;;:::i;:::-;25699:44;25715:7;25724:15;;25740:1;25724:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;25699:15;:44::i;:::-;-1:-1:-1::0;25557:3:0::1;;25515:240;;42824:834:::0;14555:13;:11;:13::i;:::-;11195:21:::1;:19;:21::i;:::-;42932:9:::2;42927:724;42947:20:::0;;::::2;42927:724;;;42989:15;43007:9;;43017:1;43007:12;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;::::2;;43034:22;43059:19:::0;;;:10:::2;:19:::0;;;;;;;43161:10;;43007:12;;-1:-1:-1;43059:19:0;-1:-1:-1;;;;;43161:10:0::2;:24:::0;;-1:-1:-1;43157:483:0::2;;43254:11;::::0;43294:10;;43254:60:::2;::::0;-1:-1:-1;;;43254:60:0;;-1:-1:-1;;;;;43254:11:0;;::::2;::::0;:24:::2;::::0;:60:::2;::::0;43287:4:::2;::::0;43294:10;;::::2;::::0;43306:7;;43254:60:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;43380:37;43409:7;43380:28;:37::i;:::-;43507:10:::0;;43479:48:::2;::::0;-1:-1:-1;;;;;43507:10:0::2;43519:7:::0;43479:27:::2;:48::i;:::-;43605:19;::::0;;;:10:::2;:19;::::0;;;;43598:26;;-1:-1:-1;;;;;;43598:26:0::2;::::0;;;;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;;-1:-1:-1;;43598:26:0::2;::::0;;::::2;;::::0;43157:483:::2;-1:-1:-1::0;;42969:3:0::2;;42927:724;;43861:871:::0;14555:13;:11;:13::i;:::-;11195:21:::1;:19;:21::i;:::-;44019:17:::2;:24:::0;:28;44012:713:::2;;44084:17;:24:::0;44064:17:::2;::::0;44084:28:::2;::::0;44111:1:::2;::::0;44084:28:::2;:::i;:::-;44064:48;;44127:15;44145:17;44163:9;44145:28;;;;;;;;:::i;:::-;;::::0;;;::::2;::::0;;;;;::::2;::::0;44213:19;;;:10:::2;:19:::0;;;;;;;44253:10;;44145:28;;-1:-1:-1;44213:19:0;-1:-1:-1;;;;;44253:10:0::2;:24:::0;44249:369:::2;;44346:11;::::0;44386:10;;44346:60:::2;::::0;-1:-1:-1;;;44346:60:0;;-1:-1:-1;;;;;44346:11:0;;::::2;::::0;:24:::2;::::0;:60:::2;::::0;44379:4:::2;::::0;44386:10;;::::2;::::0;44398:7;;44346:60:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;44498:10:0;;44470:48:::2;::::0;-1:-1:-1;;;;;;44498:10:0::2;::::0;-1:-1:-1;44510:7:0;44470:27:::2;:48::i;:::-;44583:19;::::0;;;:10:::2;:19;::::0;;;;44576:26;;-1:-1:-1;;;;;;44576:26:0::2;::::0;;;;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;;;::::2;::::0;::::2;::::0;;-1:-1:-1;;44576:26:0::2;::::0;;::::2;;::::0;44249:369:::2;44690:17;:23;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;44049:676;;;44012:713;;;11239:20:::1;10633:1:::0;11759:7;:22;11576:213;22372:305;11195:21;:19;:21::i;:::-;22461:1:::1;22452:6;:10;22444:39;;;::::0;-1:-1:-1;;;22444:39:0;;11859:2:1;22444:39:0::1;::::0;::::1;11841:21:1::0;11898:2;11878:18;;;11871:30;-1:-1:-1;;;11917:18:1;;;11910:46;11973:18;;22444:39:0::1;11657:340:1::0;22444:39:0::1;22509:11;::::0;:59:::1;::::0;-1:-1:-1;;;22509:59:0;;22494:12:::1;::::0;-1:-1:-1;;;;;22509:11:0::1;::::0;:24:::1;::::0;:59:::1;::::0;22534:10:::1;::::0;22554:4:::1;::::0;22561:6;;22509:59:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;22494:74;;22587:7;22579:39;;;::::0;-1:-1:-1;;;22579:39:0;;12204:2:1;22579:39:0::1;::::0;::::1;12186:21:1::0;12243:2;12223:18;;;12216:30;-1:-1:-1;;;12262:18:1;;;12255:49;12321:18;;22579:39:0::1;12002:343:1::0;22579:39:0::1;22634:35;::::0;160:25:1;;;22650:10:0::1;::::0;22634:35:::1;::::0;148:2:1;133:18;22634:35:0::1;;;;;;;22433:244;11239:20:::0;10633:1;11759:7;:22;11576:213;23623:313;11195:21;:19;:21::i;:::-;23713:9:::1;23708:221;23728:20:::0;;::::1;23708:221;;;23770:15;23788:9;;23798:1;23788:12;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;23823:19;::::0;;;:10:::1;:19:::0;;;;;;;:25;23788:12;;-1:-1:-1;;;;;;;23823:25:0::1;23852:10;23823:39;23815:62;;;;-1:-1:-1::0;;;23815:62:0::1;;;;;;;:::i;:::-;23892:25;23909:7;23892:16;:25::i;:::-;-1:-1:-1::0;23750:3:0::1;;23708:221;;20669:541:::0;14555:13;:11;:13::i;:::-;20939:14:::1;:32:::0;;;;20982:16:::1;:36:::0;;;;21031:14:::1;:32:::0;;;;21074:16:::1;:36:::0;21123:14:::1;:32:::0;21166:16:::1;:36:::0;20669:541::o;15602:220::-;14555:13;:11;:13::i;:::-;-1:-1:-1;;;;;15687:22:0;::::1;15683:93;;15733:31;::::0;-1:-1:-1;;;15733:31:0;;15761:1:::1;15733:31;::::0;::::1;5753:51:1::0;5726:18;;15733:31:0::1;5607:203:1::0;15683:93:0::1;15786:28;15805:8;15786:18;:28::i;26034:336::-:0;26118:16;26147:24;26188:9;26174:31;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26174:31:0;;26147:58;;26221:9;26216:122;26236:20;;;26216:122;;;26291:35;26313:9;;26323:1;26313:12;;;;;;;:::i;:::-;;;;;;;26291:21;:35::i;:::-;26278:7;26286:1;26278:10;;;;;;;;:::i;:::-;;;;;;;;;;:48;26258:3;;26216:122;;;-1:-1:-1;26355:7:0;-1:-1:-1;26034:336:0;;;;;:::o;38494:375::-;38593:17;:24;38545:18;;38576:14;38593:24;38656:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;38628:51;;38695:9;38690:148;38714:6;38710:1;:10;38690:148;;;38742:15;38760:17;38778:1;38760:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;38807:19;;;:10;:19;;;;;;;38795:31;;;;;;;;;-1:-1:-1;;;;;38795:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38760:20;;-1:-1:-1;38795:31:0;;38807:19;38795:31;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:6;38802:1;38795:9;;;;;;;;:::i;:::-;;;;;;;;;;:31;-1:-1:-1;38722:3:0;;38690:148;;;-1:-1:-1;38855:6:0;38494:375;-1:-1:-1;;38494:375:0:o;14834:166::-;14742:6;;-1:-1:-1;;;;;14742:6:0;12865:10;14894:23;14890:103;;14941:40;;-1:-1:-1;;;14941:40:0;;12865:10;14941:40;;;5753:51:1;5726:18;;14941:40:0;5607:203:1;11275:293:0;10677:1;11409:7;;:19;11401:63;;;;-1:-1:-1;;;11401:63:0;;12552:2:1;11401:63:0;;;12534:21:1;12591:2;12571:18;;;12564:30;12630:33;12610:18;;;12603:61;12681:18;;11401:63:0;12350:355:1;11401:63:0;10677:1;11542:7;:18;11275:293::o;29864:902::-;29961:22;29986:20;;;:10;:20;;;;;30054:10;;-1:-1:-1;;;;;30054:10:0;30046:47;;;;-1:-1:-1;;;30046:47:0;;12912:2:1;30046:47:0;;;12894:21:1;12951:2;12931:18;;;12924:30;-1:-1:-1;;;12970:18:1;;;12963:40;13020:18;;30046:47:0;12710:334:1;30046:47:0;30191:15;30172;;;;;;:34;;;;;;;;:::i;:::-;;30168:218;;30279:15;;;;30223;;30262:33;;30279:15;;30262:16;:33::i;:::-;30241:4;:18;;;:54;;;;:::i;:::-;30223:72;;30337:7;30318:15;:26;;30310:64;;;;-1:-1:-1;;;30310:64:0;;13251:2:1;30310:64:0;;;13233:21:1;13290:2;13270:18;;;13263:30;-1:-1:-1;;;13309:18:1;;;13302:55;13374:18;;30310:64:0;13049:349:1;30310:64:0;30208:178;30168:218;30477:23;30491:8;30477:13;:23::i;:::-;-1:-1:-1;30538:15:0;;;:32;;30556:14;;30538:15;-1:-1:-1;;30538:32:0;;30556:14;30538:32;;;;;;;;:::i;:::-;;;;;-1:-1:-1;30602:15:0;30581:18;;;:36;;;30628:18;;;:36;30721:10;;30703:55;;-1:-1:-1;;;;;30721:10:0;;;;30703:55;;;;30733:8;;30743:14;;30703:55;:::i;:::-;;;;;;;;29950:816;29864:902;;:::o;32008:3599::-;32067:7;32112:20;;;:10;:20;;;;;32215:18;;;;32167:15;;32291:26;;;32287:67;;-1:-1:-1;32341:1:0;;32008:3599;-1:-1:-1;;;;32008:3599:0:o;32287:67::-;32366:16;32385:25;32399:11;32385;:25;:::i;:::-;32366:44;-1:-1:-1;32421:19:0;;;32508:15;;;;;;:34;;;;;;;;:::i;:::-;;32507:125;;32615:15;;;;32598:33;;32615:15;;32598:16;:33::i;:::-;32577:4;:18;;;:54;;;;:::i;:::-;32507:125;;;32559:1;32507:125;32489:143;-1:-1:-1;32739:15:0;32720;;;;;;:34;;;;;;;;:::i;:::-;;32716:2394;;32822:7;32808:11;:21;32804:1962;;;32886:24;32928:7;32914:11;:21;32913:47;;32953:7;32913:47;;;32939:11;32913:47;32886:74;;32979:18;33020:11;33001:16;:30;33000:111;;33110:1;33000:111;;;33056:30;33075:11;33056:16;:30;:::i;:::-;32979:132;;33132:18;33166:12;;33153:10;:25;;;;:::i;:::-;33237:15;;;;33132:46;;-1:-1:-1;33197:18:0;;33218:35;;33237:15;;33218:18;:35::i;:::-;33197:56;;33410:23;33470:3;33456:10;33437:16;;:29;;;;:::i;:::-;33436:37;;;;:::i;:::-;33538:15;33556:23;;;:13;:23;;;;;;33410:63;;-1:-1:-1;33602:12:0;;;33598:31;;-1:-1:-1;33626:3:0;33598:31;33738:20;33805:3;33776:25;33794:7;33776:15;:25;:::i;:::-;33775:33;;;;:::i;:::-;33761:48;;:10;:48;:::i;:::-;33738:71;-1:-1:-1;33828:27:0;33738:71;33828:27;;:::i;:::-;;;33960:7;33946:11;:21;33942:421;;;33992:20;34015:21;34029:7;34015:11;:21;:::i;:::-;33992:44;;34059:20;34097:12;;34082;:27;;;;:::i;:::-;34059:50;;34211:25;34270:3;34259:7;34240:16;;:26;;;;:::i;:::-;34239:34;;;;:::i;:::-;34211:62;-1:-1:-1;34311:32:0;34211:62;34311:12;:32;:::i;:::-;34296:47;;;;:::i;:::-;;;33969:394;;;33942:421;32831:1547;;;;;;;32716:2394;;32804:1962;34459:17;34490:12;;34479:8;:23;;;;:::i;:::-;34521:15;34539:23;;;:13;:23;;;;;;34459:43;;-1:-1:-1;34585:12:0;;;34581:31;;-1:-1:-1;34609:3:0;34581:31;34633:21;34688:3;34677:7;34658:16;;:26;;;;:::i;:::-;34657:34;;;;:::i;:::-;34633:58;-1:-1:-1;34725:25:0;34633:58;34725:9;:25;:::i;:::-;34710:40;;;;:::i;:::-;;;34384:382;;;32716:2394;;;34839:17;34870:12;;34859:8;:23;;;;:::i;:::-;34897:15;34915:23;;;:13;:23;;;;;;34839:43;;-1:-1:-1;34957:12:0;;;34953:31;;-1:-1:-1;34981:3:0;34953:31;35001:13;35048:3;35037:7;35018:16;;:26;;;;:::i;:::-;35017:34;;;;:::i;:::-;35001:50;-1:-1:-1;35081:17:0;35001:50;35081:9;:17;:::i;:::-;35066:32;;;;:::i;:::-;;;34783:327;;;32716:2394;35153:18;;;:32;;;35247:15;;35243:326;;35301:11;;:36;;-1:-1:-1;;;35301:36:0;;35331:4;35301:36;;;5753:51:1;35279:19:0;;-1:-1:-1;;;;;35301:11:0;;:21;;5726:18:1;;35301:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;35279:58;;35375:11;35360;:26;;35352:75;;;;-1:-1:-1;;;35352:75:0;;13890:2:1;35352:75:0;;;13872:21:1;13929:2;13909:18;;;13902:30;13968:34;13948:18;;;13941:62;-1:-1:-1;;;14019:18:1;;;14012:34;14063:19;;35352:75:0;13688:400:1;35352:75:0;35442:11;;35463:10;;35442:45;;-1:-1:-1;;;35442:45:0;;-1:-1:-1;;;;;35463:10:0;;;35442:45;;;11005:51:1;11072:18;;;11065:34;;;35442:11:0;;;:20;;10978:18:1;;35442:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;35523:10:0;;35509:48;;;14267:25:1;;;14323:2;14308:18;;14301:34;;;-1:-1:-1;;;;;35523:10:0;;;;35509:48;;14240:18:1;35509:48:0;;;;;;;35264:305;35243:326;-1:-1:-1;35588:11:0;32008:3599;-1:-1:-1;;;;;;32008:3599:0:o;27958:784::-;28096:11;;:61;;-1:-1:-1;;;28096:61:0;;-1:-1:-1;;;;;28096:11:0;;;;:24;;:61;;28121:10;;28141:4;;28148:8;;28096:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;28202:22:0;28227:20;;;:10;:20;;;;;28258:23;;-1:-1:-1;;;;;;28258:23:0;28271:10;28258:23;;;;28292:12;;;:23;;;28342:15;28326:13;;;:31;;;28368:18;;;;:36;;;;28415:15;;;:29;;28227:20;;-1:-1:-1;28433:11:0;;28415:15;;-1:-1:-1;;28415:29:0;;;;28433:11;;28415:29;;;;;;;:::i;:::-;;;;;-1:-1:-1;28492:15:0;28477:11;:30;;;;;;;;:::i;:::-;;28476:54;;28515:15;28476:54;;;28511:1;28476:54;28455:18;;;:75;28587:33;28611:8;39549:17;:24;;39517:29;;;;:19;:29;;;;;:56;;;39584:32;;;;;;;;;;;;39446:178;28587:33;28654:10;40239:23;;;;:16;:23;;;;;;;;:30;;40205:31;;;:21;:31;;;;;:64;;;40280:23;;;:38;;;;;;;;;;;;;28693:41;;;;;40205:31;;28722:11;;28693:41;:::i;15982:191::-;16075:6;;;-1:-1:-1;;;;;16092:17:0;;;-1:-1:-1;;;;;;16092:17:0;;;;;;;16125:40;;16075:6;;;16092:17;16075:6;;16125:40;;16056:16;;16125:40;16045:128;15982:191;:::o;42008:570::-;42138:24;;;42203:15;;;;;;:34;;;;;;;;:::i;:::-;;42199:86;;-1:-1:-1;42262:3:0;;42267:5;;-1:-1:-1;42008:570:0;-1:-1:-1;42008:570:0:o;42199:86::-;42331:15;;;;42295:16;;42314:33;;42331:15;;42314:16;:33::i;:::-;42295:52;;42358:15;42397:8;42376:4;:18;;;:29;;;;:::i;:::-;42512:15;;;;42358:47;;-1:-1:-1;42437:15:0;:25;-1:-1:-1;42437:25:0;42416:17;;42493:35;;42512:15;;42493:18;:35::i;:::-;42474:54;42557:12;;-1:-1:-1;42008:570:0;;-1:-1:-1;;;;;42008:570:0:o;30960:801::-;31050:22;31075:20;;;:10;:20;;;;;;31168:15;;;;;;:34;;;;;;;;:::i;:::-;;31160:71;;;;-1:-1:-1;;;31160:71:0;;14548:2:1;31160:71:0;;;14530:21:1;14587:2;14567:18;;;14560:30;14626:26;14606:18;;;14599:54;14670:18;;31160:71:0;14346:348:1;31160:71:0;31334:15;;;;31278;;31317:33;;31334:15;;31317:16;:33::i;:::-;31296:4;:18;;;:54;;;;:::i;:::-;31278:72;;31388:7;31369:15;:26;;31361:64;;;;-1:-1:-1;;;31361:64:0;;13251:2:1;31361:64:0;;;13233:21:1;13290:2;13270:18;;;13263:30;-1:-1:-1;;;13309:18:1;;;13302:55;13374:18;;31361:64:0;13049:349:1;31361:64:0;31478:23;31492:8;31478:13;:23::i;:::-;-1:-1:-1;31554:15:0;;;:32;;31572:14;;31554:15;-1:-1:-1;;31554:32:0;;31572:14;31554:32;;;;;;;;:::i;:::-;;;;;-1:-1:-1;31618:15:0;31597:18;;;:36;;;31644:18;;;:36;31716:10;;31698:55;;-1:-1:-1;;;;;31716:10:0;;;;31698:55;;;;31728:8;;31738:14;;31698:55;:::i;:::-;;;;;;;;31039:722;;30960:801;;:::o;39632:480::-;39708:11;39722:29;;;:19;:29;;;;;;39782:17;:24;39722:29;;39708:11;39782:28;;39809:1;;39782:28;:::i;:::-;39762:48;;39832:9;39825:3;:16;39821:203;;39858:19;39880:17;39898:9;39880:28;;;;;;;;:::i;:::-;;;;;;;;;39858:50;;39948:11;39923:17;39941:3;39923:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;39974:32;;;:19;:32;;;;;:38;;;39821:203;40034:17;:23;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;40034:23:0;;;;;;;;;;;;40075:29;;;:19;:29;;;-1:-1:-1;;40075:29:0;;;40068:36;39632:480::o;40334:526::-;40424:11;40438:31;;;:21;:31;;;;;;;;;-1:-1:-1;;;;;40500:23:0;;;;:16;:23;;;;;:30;40438:31;;40424:11;40500:34;;40533:1;;40500:34;:::i;:::-;40480:54;;40558:9;40551:3;:16;40547:217;;-1:-1:-1;;;;;40606:23:0;;40584:19;40606:23;;;:16;:23;;;;;:34;;40630:9;;40606:34;;;;;;:::i;:::-;;;;;;;;;40584:56;;40686:11;40655:16;:23;40672:5;-1:-1:-1;;;;;40655:23:0;-1:-1:-1;;;;;40655:23:0;;;;;;;;;;;;40679:3;40655:28;;;;;;;;:::i;:::-;;;;;;;;;;;;:42;;;;40712:34;;;:21;:34;;;;;:40;;;40547:217;-1:-1:-1;;;;;40774:23:0;;;;;;:16;:23;;;;;:29;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;40774:29:0;;;;;;;;;;;;40821:31;;;:21;:31;;;-1:-1:-1;;40821:31:0;;;40814:38;-1:-1:-1;40334:526:0:o;28750:808::-;28814:22;28839:20;;;:10;:20;;;;;;28924:15;;;;;;:34;;;;;;;;:::i;:::-;;28920:234;;29031:15;;;;28975;;29014:33;;29031:15;;29014:16;:33::i;:::-;28993:4;:18;;;:54;;;;:::i;:::-;28975:72;;29089:7;29070:15;:26;;29062:80;;;;-1:-1:-1;;;29062:80:0;;14901:2:1;29062:80:0;;;14883:21:1;14940:2;14920:18;;;14913:30;14979:34;14959:18;;;14952:62;-1:-1:-1;;;15030:18:1;;;15023:39;15079:19;;29062:80:0;14699:405:1;29062:80:0;28960:194;28920:234;29206:23;29220:8;29206:13;:23::i;:::-;-1:-1:-1;29272:11:0;;29312:10;;29272:61;;-1:-1:-1;;;29272:61:0;;-1:-1:-1;;;;;29272:11:0;;;;:24;;:61;;29305:4;;29312:10;;;;29324:8;;29272:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29366:38;29395:8;29366:28;:38::i;:::-;29443:10;;29415:49;;-1:-1:-1;;;;;29443:10:0;29455:8;29415:27;:49::i;:::-;29482:20;;;;:10;:20;;;;;;;;29475:27;;-1:-1:-1;;;;;;29475:27:0;;;-1:-1:-1;29475:27:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;29475:27:0;;;;;;;;;29529:10;;29520:30;;160:25:1;;;-1:-1:-1;;;;;29529:10:0;;;;29520:30;;133:18:1;29520:30:0;;;;;;;28803:755;28750:808;:::o;35702:2528::-;35774:7;35819:20;;;:10;:20;;;;;35854:10;;-1:-1:-1;;;;;35854:10:0;35850:38;;-1:-1:-1;35887:1:0;;35702:2528;-1:-1:-1;;35702:2528:0:o;35850:38::-;35985:18;;;;35937:15;;36018:26;;;36014:40;;-1:-1:-1;36053:1:0;;35702:2528;-1:-1:-1;;;;35702:2528:0:o;36014:40::-;36067:16;36086:25;36100:11;36086;:25;:::i;:::-;36067:44;-1:-1:-1;36122:19:0;;;36177:15;;;;;;:34;;;;;;;;:::i;:::-;;36176:125;;36284:15;;;;36267:33;;36284:15;;36267:16;:33::i;:::-;36246:4;:18;;;:54;;;;:::i;:::-;36176:125;;;36228:1;36176:125;36158:143;-1:-1:-1;36337:15:0;36318;;;;;;:34;;;;;;;;:::i;:::-;;36314:1878;;36387:7;36373:11;:21;36369:1496;;;36415:24;36457:7;36443:11;:21;36442:47;;36482:7;36442:47;;;36468:11;36442:47;36415:74;;36508:18;36549:11;36530:16;:30;36529:111;;36639:1;36529:111;;;36585:30;36604:11;36585:16;:30;:::i;:::-;36508:132;;36661:18;36695:12;;36682:10;:25;;;;:::i;:::-;36766:15;;;;36661:46;;-1:-1:-1;36726:18:0;;36747:35;;36766:15;;36747:18;:35::i;:::-;36726:56;;36803:23;36863:3;36849:10;36830:16;;:29;;;;:::i;:::-;36829:37;;;;:::i;:::-;36887:15;36905:23;;;:13;:23;;;;;;36803:63;;-1:-1:-1;36951:12:0;;;36947:31;;-1:-1:-1;36975:3:0;36947:31;36999:20;37066:3;37037:25;37055:7;37037:15;:25;:::i;:::-;37036:33;;;;:::i;:::-;37022:48;;:10;:48;:::i;:::-;36999:71;-1:-1:-1;37089:27:0;36999:71;37089:27;;:::i;:::-;;;37155:7;37141:11;:21;37137:334;;;37187:20;37210:21;37224:7;37210:11;:21;:::i;:::-;37187:44;;37254:20;37292:12;;37277;:27;;;;:::i;:::-;37254:50;;37327:21;37382:3;37371:7;37352:16;;:26;;;;:::i;:::-;37351:34;;;;:::i;:::-;37327:58;-1:-1:-1;37423:28:0;37327:58;37423:12;:28;:::i;:::-;37408:43;;;;:::i;:::-;;;37164:307;;;37137:334;36396:1090;;;;;;;36314:1878;;36369:1496;37558:17;37589:12;;37578:8;:23;;;;:::i;:::-;37620:15;37638:23;;;:13;:23;;;;;;37558:43;;-1:-1:-1;37684:12:0;;;37680:31;;-1:-1:-1;37708:3:0;37680:31;37732:21;37787:3;37776:7;37757:16;;:26;;;;:::i;:::-;37756:34;;;;:::i;:::-;37732:58;-1:-1:-1;37824:25:0;37732:58;37824:9;:25;:::i;:::-;37809:40;;;;:::i;:::-;;;37492:373;;;36314:1878;;;37921:17;37952:12;;37941:8;:23;;;;:::i;:::-;37979:15;37997:23;;;:13;:23;;;;;;37921:43;;-1:-1:-1;38039:12:0;;;38035:31;;-1:-1:-1;38063:3:0;38035:31;38083:13;38130:3;38119:7;38100:16;;:26;;;;:::i;:::-;38099:34;;;;:::i;:::-;38083:50;-1:-1:-1;38163:17:0;38083:50;38163:9;:17;:::i;:::-;38148:32;;;;:::i;:::-;;38211:11;-1:-1:-1;;;;;;;;;;;35702:2528:0:o;40972:369::-;41040:7;41074:17;41064:6;:27;;;;;;;;:::i;:::-;;41060:255;;-1:-1:-1;;41115:14:0;;;40972:369::o;41060:255::-;41161:17;41151:6;:27;;;;;;;;:::i;:::-;;41147:168;;-1:-1:-1;;41202:14:0;;;40972:369::o;41147:168::-;41248:17;41238:6;:27;;;;;;;;:::i;:::-;;41234:81;;-1:-1:-1;;41289:14:0;;;40972:369::o;41234:81::-;-1:-1:-1;41332:1:0;;40972:369;-1:-1:-1;40972:369:0:o;41456:397::-;41526:7;41560:17;41550:6;:27;;;;;;;;:::i;:::-;;41546:261;;-1:-1:-1;;41601:16:0;;;41456:397::o;41546:261::-;41649:17;41639:6;:27;;;;;;;;:::i;:::-;;41635:172;;-1:-1:-1;;41690:16:0;;;41456:397::o;41635:172::-;41738:17;41728:6;:27;;;;;;;;:::i;:::-;;41724:83;;-1:-1:-1;;41779:16:0;;;41456:397::o;41724:83::-;-1:-1:-1;41824:3:0;;41456:397;-1:-1:-1;41456:397:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;381:367::-;444:8;454:6;508:3;501:4;493:6;489:17;485:27;475:55;;526:1;523;516:12;475:55;-1:-1:-1;549:20:1;;592:18;581:30;;578:50;;;624:1;621;614:12;578:50;661:4;653:6;649:17;637:29;;721:3;714:4;704:6;701:1;697:14;689:6;685:27;681:38;678:47;675:67;;;738:1;735;728:12;675:67;381:367;;;;;:::o;753:787::-;889:6;897;905;913;966:2;954:9;945:7;941:23;937:32;934:52;;;982:1;979;972:12;934:52;1022:9;1009:23;1051:18;1092:2;1084:6;1081:14;1078:34;;;1108:1;1105;1098:12;1078:34;1147:70;1209:7;1200:6;1189:9;1185:22;1147:70;:::i;:::-;1236:8;;-1:-1:-1;1121:96:1;-1:-1:-1;1324:2:1;1309:18;;1296:32;;-1:-1:-1;1340:16:1;;;1337:36;;;1369:1;1366;1359:12;1337:36;;1408:72;1472:7;1461:8;1450:9;1446:24;1408:72;:::i;:::-;753:787;;;;-1:-1:-1;1499:8:1;-1:-1:-1;;;;753:787:1:o;2323:140::-;-1:-1:-1;;;;;2407:31:1;;2397:42;;2387:70;;2453:1;2450;2443:12;2468:271;2542:6;2595:2;2583:9;2574:7;2570:23;2566:32;2563:52;;;2611:1;2608;2601:12;2563:52;2650:9;2637:23;2669:40;2703:5;2669:40;:::i;:::-;2728:5;2468:271;-1:-1:-1;;;2468:271:1:o;2744:437::-;2830:6;2838;2891:2;2879:9;2870:7;2866:23;2862:32;2859:52;;;2907:1;2904;2897:12;2859:52;2947:9;2934:23;2980:18;2972:6;2969:30;2966:50;;;3012:1;3009;3002:12;2966:50;3051:70;3113:7;3104:6;3093:9;3089:22;3051:70;:::i;:::-;3140:8;;3025:96;;-1:-1:-1;2744:437:1;-1:-1:-1;;;;2744:437:1:o;3447:127::-;3508:10;3503:3;3499:20;3496:1;3489:31;3539:4;3536:1;3529:15;3563:4;3560:1;3553:15;3579:238;3661:1;3654:5;3651:12;3641:143;;3706:10;3701:3;3697:20;3694:1;3687:31;3741:4;3738:1;3731:15;3769:4;3766:1;3759:15;3641:143;3793:18;;3579:238::o;3822:1176::-;4045:2;4097:21;;;4167:13;;4070:18;;;4189:22;;;4016:4;;4045:2;4230;;4248:18;;;;4289:15;;;4016:4;4332:640;4346:6;4343:1;4340:13;4332:640;;;4405:13;;4447:9;;-1:-1:-1;;;;;4443:35:1;4431:48;;4519:11;;;4513:18;4499:12;;;4492:40;4572:11;;;4566:18;4552:12;;;4545:40;4608:4;4652:11;;;4646:18;4632:12;;;4625:40;4688:4;4731:11;;;4725:18;4756:54;4797:12;;;4725:18;4756:54;:::i;:::-;-1:-1:-1;;4833:4:1;4877:11;;;4871:18;4857:12;;;4850:40;4919:4;4910:14;;;;4947:15;;;;4368:1;4361:9;4332:640;;;-1:-1:-1;4989:3:1;;3822:1176;-1:-1:-1;;;;;;;3822:1176:1:o;5278:324::-;5346:6;5354;5407:2;5395:9;5386:7;5382:23;5378:32;5375:52;;;5423:1;5420;5413:12;5375:52;5462:9;5449:23;5481:40;5515:5;5481:40;:::i;:::-;5540:5;5592:2;5577:18;;;;5564:32;;-1:-1:-1;;;5278:324:1:o;5815:593::-;-1:-1:-1;;;;;6132:32:1;;6114:51;;6196:2;6181:18;;6174:34;;;6239:2;6224:18;;6217:34;;;6282:2;6267:18;;6260:34;;;6101:3;6086:19;;6303:55;6353:3;6338:19;;6330:6;6303:55;:::i;:::-;6395:6;6389:3;6378:9;6374:19;6367:35;5815:593;;;;;;;;;:::o;6636:523::-;6740:6;6748;6756;6764;6772;6780;6833:3;6821:9;6812:7;6808:23;6804:33;6801:53;;;6850:1;6847;6840:12;6801:53;-1:-1:-1;;6873:23:1;;;6943:2;6928:18;;6915:32;;-1:-1:-1;6994:2:1;6979:18;;6966:32;;7045:2;7030:18;;7017:32;;-1:-1:-1;7096:3:1;7081:19;;7068:33;;-1:-1:-1;7148:3:1;7133:19;7120:33;;-1:-1:-1;6636:523:1;-1:-1:-1;6636:523:1:o;7386:632::-;7557:2;7609:21;;;7679:13;;7582:18;;;7701:22;;;7528:4;;7557:2;7780:15;;;;7754:2;7739:18;;;7528:4;7823:169;7837:6;7834:1;7831:13;7823:169;;;7898:13;;7886:26;;7967:15;;;;7932:12;;;;7859:1;7852:9;7823:169;;;-1:-1:-1;8009:3:1;;7386:632;-1:-1:-1;;;;;;7386:632:1:o;8023:345::-;8225:2;8207:21;;;8264:2;8244:18;;;8237:30;-1:-1:-1;;;8298:2:1;8283:18;;8276:51;8359:2;8344:18;;8023:345::o;8373:127::-;8434:10;8429:3;8425:20;8422:1;8415:31;8465:4;8462:1;8455:15;8489:4;8486:1;8479:15;8505:334;8707:2;8689:21;;;8746:2;8726:18;;;8719:30;-1:-1:-1;;;8780:2:1;8765:18;;8758:40;8830:2;8815:18;;8505:334::o;8844:270::-;8917:6;8970:2;8958:9;8949:7;8945:23;8941:32;8938:52;;;8986:1;8983;8976:12;8938:52;9025:9;9012:23;9064:1;9057:5;9054:12;9044:40;;9080:1;9077;9070:12;9473:184;9543:6;9596:2;9584:9;9575:7;9571:23;9567:32;9564:52;;;9612:1;9609;9602:12;9564:52;-1:-1:-1;9635:16:1;;9473:184;-1:-1:-1;9473:184:1:o;9662:127::-;9723:10;9718:3;9714:20;9711:1;9704:31;9754:4;9751:1;9744:15;9778:4;9775:1;9768:15;9794:168;9867:9;;;9898;;9915:15;;;9909:22;;9895:37;9885:71;;9936:18;;:::i;9967:217::-;10007:1;10033;10023:132;;10077:10;10072:3;10068:20;10065:1;10058:31;10112:4;10109:1;10102:15;10140:4;10137:1;10130:15;10023:132;-1:-1:-1;10169:9:1;;9967:217::o;10189:125::-;10254:9;;;10275:10;;;10272:36;;;10288:18;;:::i;10319:127::-;10380:10;10375:3;10371:20;10368:1;10361:31;10411:4;10408:1;10401:15;10435:4;10432:1;10425:15;10451:375;-1:-1:-1;;;;;10709:15:1;;;10691:34;;10761:15;;;;10756:2;10741:18;;10734:43;10808:2;10793:18;;10786:34;;;;10641:2;10626:18;;10451:375::o;11110:277::-;11177:6;11230:2;11218:9;11209:7;11205:23;11201:32;11198:52;;;11246:1;11243;11236:12;11198:52;11278:9;11272:16;11331:5;11324:13;11317:21;11310:5;11307:32;11297:60;;11353:1;11350;11343:12;11392:128;11459:9;;;11480:11;;;11477:37;;;11494:18;;:::i;11525:127::-;11586:10;11581:3;11577:20;11574:1;11567:31;11617:4;11614:1;11607:15;11641:4;11638:1;11631:15;13403:280;13589:25;;;13577:2;13562:18;;13623:54;13673:2;13658:18;;13650:6;13623:54;:::i

Swarm Source

ipfs://d6512025beb4d0383dcc5a6a0d4bae55bc44f6a8ca78f3af309df7f9a9bf123b

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

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