Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xf80229C6C6d64de561B03f7A79d537e636EC15a5
Balance 0 ETH
Nonce 1
Code Size 5313 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

5313 bytes
0x608060405234801561001057600080fd5b50600436106100ff5760003560e01c80634b075fe6116100975780638da5cb5b116100665780638da5cb5b14610278578063ac4afa3814610293578063e2bbb158146102d0578063f2fde38b146102e357600080fd5b80634b075fe6146102375780634dd5a57d1461024a5780635a4ec0ca1461025d578063715018a61461027057600080fd5b806334144b0f116100d357806334144b0f146101be5780633c93f7fb146101f1578063441a3e701461020457806349d69ae91461021757600080fd5b8062ae5faa1461010457806305117a441461012d578063150b7a0214610171578063213e1678146101a9575b600080fd5b6101176101123660046110b0565b6102f6565b60405161012491906110da565b60405180910390f35b61016361013b3660046110b0565b6001600160a01b03919091166000908152600260209081526040808320938352929052205490565b604051908152602001610124565b61019061017f366004611149565b630a85bd0160e11b95945050505050565b6040516001600160e01b03199091168152602001610124565b6101bc6101b73660046111fa565b61039d565b005b6101d16101cc3660046112c4565b6103ac565b604080519485526020850193909352918301526060820152608001610124565b6101636101ff3660046110b0565b610401565b6101bc6102123660046112f7565b610414565b61022a6102253660046112c4565b610433565b6040516101249190611319565b6101bc610245366004611344565b6104dd565b6101bc61025836600461138a565b6105db565b6101bc61026b3660046113a3565b610663565b6101bc610779565b6000546040516001600160a01b039091168152602001610124565b6102a66102a136600461138a565b6107af565b604080516001600160a01b0390951685526020850193909352918301526060820152608001610124565b6101bc6102de3660046112f7565b6107f3565b6101bc6102f13660046113dc565b6107fe565b6001600160a01b03821660009081526002602090815260408083208484528252808320805482518185028101850190935280835260609492939192909184015b82821015610390578382906000526020600020906004020160405180608001604052908160008201548152602001600182015481526020016002820154815260200160038201548152505081526020019060010190610336565b5050505090505b92915050565b6103a8338383610899565b5050565b600260205282600052604060002060205281600052604060002081815481106103d457600080fd5b60009182526020909120600490910201805460018201546002830154600390930154919550935090915084565b600061040d83836108e1565b9392505050565b6000610421338484610986565b905061042e338483610aab565b505050565b61045e6040518060800160405280600081526020016000815260200160008152602001600081525090565b6001600160a01b03841660009081526002602090815260408083208684529091529020805483908110610493576104936113f7565b906000526020600020906004020160405180608001604052908160008201548152602001600182015481526020016002820154815260200160038201548152505090509392505050565b6000546001600160a01b031633146105105760405162461bcd60e51b81526004016105079061140d565b60405180910390fd5b8360018681548110610524576105246113f7565b906000526020600020906004020160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550826001868154811061056d5761056d6113f7565b9060005260206000209060040201600101819055508160018681548110610596576105966113f7565b90600052602060002090600402016002018190555080600186815481106105bf576105bf6113f7565b9060005260206000209060040201600301819055505050505050565b60005b3360009081526002602090815260408083208584529091529020548110156103a857336000908152600260209081526040808320858452909152902080548290811061062c5761062c6113f7565b9060005260206000209060040201600301546000141561065157610651338383610aab565b8061065b81611458565b9150506105de565b6000546001600160a01b0316331461068d5760405162461bcd60e51b81526004016105079061140d565b604080516080810182526001600160a01b039586168152602081019485529081019283526060810191825260018054808201825560009190915290517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6600490920291820180546001600160a01b031916919096161790945591517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7840155517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8830155517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf990910155565b6000546001600160a01b031633146107a35760405162461bcd60e51b81526004016105079061140d565b6107ad6000610de8565b565b600181815481106107bf57600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919084565b6103a8338383610e38565b6000546001600160a01b031633146108285760405162461bcd60e51b81526004016105079061140d565b6001600160a01b03811661088d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610507565b61089681610de8565b50565b60005b81518110156108db576108c984848484815181106108bc576108bc6113f7565b6020026020010151610e38565b806108d381611458565b91505061089c565b50505050565b6000805b6001600160a01b038416600090815260026020908152604080832086845290915290205481101561097f576001600160a01b03841660009081526002602090815260408083208684529091529020805482908110610945576109456113f7565b9060005260206000209060040201600301546000141561096d578161096981611458565b9250505b8061097781611458565b9150506108e5565b5092915050565b6000805b6001600160a01b0385166000908152600260209081526040808320878452909152902054811015610a70576001600160a01b038516600090815260026020908152604080832087845290915290208054849190839081106109ed576109ed6113f7565b906000526020600020906004020160000154148015610a5257506001600160a01b03851660009081526002602090815260408083208784529091529020805482908110610a3c57610a3c6113f7565b9060005260206000209060040201600301546000145b15610a5e57905061040d565b80610a6881611458565b91505061098a565b5060405162461bcd60e51b815260206004820152600f60248201526e151bdad95b881b9bdd08199bdd5b99608a1b6044820152606401610507565b6001600160a01b03831660009081526002602090815260408083208584529091529020805442919083908110610ae357610ae36113f7565b6000918252602080832060026004909302018201546001600160a01b03881684529181526040808420878552909152909120805484908110610b2757610b276113f7565b906000526020600020906004020160010154610b439190611473565b10610b905760405162461bcd60e51b815260206004820152601d60248201527f536f7272792c20746f6f206561726c7920666f722077697468647261770000006044820152606401610507565b6001600160a01b03831660009081526002602090815260408083208584529091529020805482908110610bc557610bc56113f7565b906000526020600020906004020160030154600014610c195760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e481d5b9cdd185ad95960821b6044820152606401610507565b6001600160a01b03831660009081526002602090815260408083208584529091529020805442919083908110610c5157610c516113f7565b906000526020600020906004020160030181905550600060018381548110610c7b57610c7b6113f7565b600091825260208083206004909202909101546001600160a01b03878116845260028352604080852088865290935291909220805491909216925082916323b872dd913091889187908110610cd257610cd26113f7565b9060005260206000209060040201600001546040518463ffffffff1660e01b8152600401610d21939291906001600160a01b039384168152919092166020820152604081019190915260600190565b600060405180830381600087803b158015610d3b57600080fd5b505af1158015610d4f573d6000803e3d6000fd5b5050506001600160a01b038516600081815260026020908152604080832088845290915290208054600193508692917f42e4e5bc031685fe8ecea7d83faf3884712115e0cc7d4d77c34bb5fc9500b3329187908110610db057610db06113f7565b90600052602060002090600402016000015442604051610dda929190918252602082015260400190565b60405180910390a450505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b4260018381548110610e4c57610e4c6113f7565b90600052602060002090600402016002015410610ea15760405162461bcd60e51b8152602060048201526013602482015272141bdbdb081b9bdd081858dd1a5d99481e595d606a1b6044820152606401610507565b4260018381548110610eb557610eb56113f7565b90600052602060002090600402016003015411610f055760405162461bcd60e51b815260206004820152600e60248201526d141bdbdb081a5cc818db1bdcd95960921b6044820152606401610507565b60026000846001600160a01b03166001600160a01b031681526020019081526020016000206000838152602001908152602001600020604051806080016040528083815260200142815260200160018581548110610f6557610f656113f7565b600091825260208083206004928302016001908101548552938101839052855480850187559583528083208551969092029091019485558301518483015560408301516002850155606090920151600390930192909255815490919084908110610fd157610fd16113f7565b60009182526020909120600491820201546040516323b872dd60e01b81526001600160a01b0387811693820193909352306024820152604481018590529116915081906323b872dd90606401600060405180830381600087803b15801561103757600080fd5b505af115801561104b573d6000803e3d6000fd5b505060408051858152426020820152600093508692506001600160a01b038816917f42e4e5bc031685fe8ecea7d83faf3884712115e0cc7d4d77c34bb5fc9500b3329101610dda565b80356001600160a01b03811681146110ab57600080fd5b919050565b600080604083850312156110c357600080fd5b6110cc83611094565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561113d5761112a838551805182526020810151602083015260408101516040830152606081015160608301525050565b92840192608092909201916001016110f6565b50909695505050505050565b60008060008060006080868803121561116157600080fd5b61116a86611094565b945061117860208701611094565b935060408601359250606086013567ffffffffffffffff8082111561119c57600080fd5b818801915088601f8301126111b057600080fd5b8135818111156111bf57600080fd5b8960208285010111156111d157600080fd5b9699959850939650602001949392505050565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561120d57600080fd5b8235915060208084013567ffffffffffffffff8082111561122d57600080fd5b818601915086601f83011261124157600080fd5b813581811115611253576112536111e4565b8060051b604051601f19603f83011681018181108582111715611278576112786111e4565b60405291825284820192508381018501918983111561129657600080fd5b938501935b828510156112b45784358452938501939285019261129b565b8096505050505050509250929050565b6000806000606084860312156112d957600080fd5b6112e284611094565b95602085013595506040909401359392505050565b6000806040838503121561130a57600080fd5b50508035926020909101359150565b8151815260208083015190820152604080830151908201526060808301519082015260808101610397565b600080600080600060a0868803121561135c57600080fd5b8535945061136c60208701611094565b94979496505050506040830135926060810135926080909101359150565b60006020828403121561139c57600080fd5b5035919050565b600080600080608085870312156113b957600080fd5b6113c285611094565b966020860135965060408601359560600135945092505050565b6000602082840312156113ee57600080fd5b61040d82611094565b634e487b7160e01b600052603260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600060001982141561146c5761146c611442565b5060010190565b6000821982111561148657611486611442565b50019056fea2646970667358221220b65143e88d98098bdd1749a883320e5e8cb08cf6d68eea2ac837221e378d0a4664736f6c634300080b0033

Verified Source Code Partial Match

Compiler: v0.8.11+commit.d7f03943 EVM: istanbul Optimization: Yes (200 runs)
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

pragma solidity ^0.8.0;

import "IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

import "Context.sol";

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

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

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

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

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

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
IERC721Receiver.sol 27 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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



contract Sidus721Staking is Ownable, IERC721Receiver {
    //using ECDSA for bytes32;
    // pool struct
    struct PoolInfo {
        address contractAddress;  // erc721 contract address
        uint256 period;           // stake period.cant claim during stake!
        uint256 activeAfter;      // date of start staking
        uint256 closedAfter;      // date of end staking
    }

    // user struct
    struct UserInfo {
        uint256 tokenId;         // subj
        uint256 stakedAt;        // moment of stake
        uint256 period;          // period in seconds
        uint256 unStaked;        // date of unstaked 
    }

    PoolInfo[] public  pools;
    
    // maping from user  to poolId to tokenId
    mapping(address => mapping(uint256 => UserInfo[])) public userStakes;

    /// Emit in case of any changes: stake or unstake for now
    /// 0 - Staked
    /// 1 - Unstaked 
    event StakeChanged(
        address indexed user, 
        uint256 indexed poolId, 
        uint8   indexed changeType,
        uint256 tokenId, 
        uint256 timestamp
    );


    function deposit(uint256 poolId, uint256 tokenId) external {
        _deposit(msg.sender, poolId, tokenId);
    }

    function depositBatch(uint256 poolId, uint256[] memory tokenIds) external {
         _depositBatch(msg.sender, poolId, tokenIds);
    }

    function withdraw(uint256 _poolId, uint256 _tokenId) external {
        // lets get tokenId index
        uint256 _tokenIndex = _getTokenIndexByTokenId(msg.sender, _poolId, _tokenId);
        _withdraw(msg.sender, _poolId, _tokenIndex); 
    }

    function withdrawBatch(uint256 _poolId) external {
        for (uint256 i = 0; i < userStakes[msg.sender][_poolId].length; i ++) {
            if (userStakes[msg.sender][_poolId][i].unStaked == 0) {
                _withdraw(msg.sender, _poolId, i);        
            }
        }
    }

    
    function getUserStakeInfo(address _user, uint256 _poolId) public view returns(UserInfo[] memory) {
        return userStakes[_user][_poolId];
    }

    function getUserStakeByIndex(address _user, uint256 _poolId, uint256 _index) public view returns(UserInfo memory) {
        return userStakes[_user][_poolId][_index];
    }

    function getUserStakeCount(address _user, uint256 _poolId) public view returns(uint256) {
        return userStakes[_user][_poolId].length;
    }

    function getUserActiveStakesCount(address _user, uint256 _poolId) public view returns(uint256) {
        return _getUserActiveStakesCount(_user, _poolId);
    } 

    ////////////////////////////////////////////////////////////
    /////////// Admin only           ////////////////////////////
    ////////////////////////////////////////////////////////////
    function addPool(
        address _contract, 
        uint256 _period, 
        uint256 _activeAfter, 
        uint256 _closedAfter
    ) public onlyOwner {
        pools.push(
            PoolInfo({
              contractAddress: _contract,  // erc721 contract address
              period: _period,             // stake period.cant claim during stake!
              activeAfter: _activeAfter,   // date of start staking
              closedAfter: _closedAfter    // date of end staking
            })
        );
    }

    function editPool(
        uint256 _poolId, 
        address _contract, 
        uint256 _period, 
        uint256 _activeAfter, 
        uint256 _closedAfter
    ) public onlyOwner {
        pools[_poolId].contractAddress = _contract;    // erc721 contract address
        pools[_poolId].period = _period;               // stake period.cant claim during stake!
        pools[_poolId].activeAfter = _activeAfter;     // date of start staking
        pools[_poolId].closedAfter = _closedAfter;     // date of end staking
    }


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


     ////////////////////////////////////////////////////////////
    /////////// internal           /////////////////////////////
    ////////////////////////////////////////////////////////////

    function _depositBatch(address _user, uint256 _poolId, uint256[] memory _tokenId) internal {
        for(uint256 i = 0; i < _tokenId.length; i ++) {
            _deposit(_user, _poolId, _tokenId[i]);
        }
    }

    function _deposit(address _user, uint256 _poolId, uint256 _tokenId) internal {
        require(pools[_poolId].activeAfter < block.timestamp, "Pool not active yet");
        require(pools[_poolId].closedAfter > block.timestamp, "Pool is closed");
        //TokenInfo[] storage theS =  userStakes[_user][_poolId];
        userStakes[_user][_poolId].push(
            UserInfo({
               tokenId: _tokenId,
               stakedAt:block.timestamp,      // moment of stake
               period: pools[_poolId].period, // period in seconds
               unStaked: 0                    // date of unstaked(close stake flag) 
        }));
        IERC721 nft = IERC721(pools[_poolId].contractAddress);
        nft.transferFrom(address(_user), address(this), _tokenId);
        emit StakeChanged(_user, _poolId, 0, _tokenId, block.timestamp);
    }

    function _withdraw(address _user, uint256 _poolId, uint256 _tokenIndex) internal {
        require(
            userStakes[_user][_poolId][_tokenIndex].stakedAt 
            + userStakes[_user][_poolId][_tokenIndex].period < block.timestamp,
            "Sorry, too early for withdraw"
        );
        require(
            userStakes[_user][_poolId][_tokenIndex].unStaked == 0,
            "Already unstaked"
        );

        userStakes[_user][_poolId][_tokenIndex].unStaked = block.timestamp;
        IERC721 nft = IERC721(pools[_poolId].contractAddress);
        nft.transferFrom(address(this), _user, userStakes[_user][_poolId][_tokenIndex].tokenId);
        emit StakeChanged(_user, _poolId, 1, userStakes[_user][_poolId][_tokenIndex].tokenId, block.timestamp);
    }

    function _getUserActiveStakesCount(address _user, uint256 _poolId) 
        internal 
        view 
        returns (uint256 count) 
    {
        for (uint256 i = 0; i < userStakes[_user][_poolId].length; i ++) {
            if (userStakes[_user][_poolId][i].unStaked == 0) {
                count ++;
            }
        }
    }

    function _getTokenIndexByTokenId(address _user, uint256 _poolId, uint256 _tokenId) 
        internal 
        view 
        returns (uint256) 
    {
        for (uint256 i = 0; i < userStakes[_user][_poolId].length; i ++ ) {
            if (userStakes[_user][_poolId][i].tokenId == _tokenId &&
                userStakes[_user][_poolId][i].unStaked == 0 //only active stakes
                ) 
            {
                return i;
            }
        }
        revert("Token not found");
    }
}

Read Contract

getUserActiveStakesCount 0x3c93f7fb → uint256
getUserStakeByIndex 0x49d69ae9 → tuple
getUserStakeCount 0x05117a44 → uint256
getUserStakeInfo 0x00ae5faa → tuple[]
owner 0x8da5cb5b → address
pools 0xac4afa38 → address, uint256, uint256, uint256
userStakes 0x34144b0f → uint256, uint256, uint256, uint256

Write Contract 9 functions

These functions modify contract state and require a wallet transaction to execute.

addPool 0x5a4ec0ca
address _contract
uint256 _period
uint256 _activeAfter
uint256 _closedAfter
deposit 0xe2bbb158
uint256 poolId
uint256 tokenId
depositBatch 0x213e1678
uint256 poolId
uint256[] tokenIds
editPool 0x4b075fe6
uint256 _poolId
address _contract
uint256 _period
uint256 _activeAfter
uint256 _closedAfter
onERC721Received 0x150b7a02
address operator
address from
uint256 tokenId
bytes data
returns: bytes4
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner
withdraw 0x441a3e70
uint256 _poolId
uint256 _tokenId
withdrawBatch 0x4dd5a57d
uint256 _poolId

Recent Transactions

No transactions found for this address