Blockchain / Global / Address
Contract
0x1d1c62F8AaAFb751B14b3487ECe8483bB8b39f37
- Balance
- 0 SOMI
- Transactions sent
- 1
- Type
- Contract · 6,077 bytes of code
CapybarasNFTStakingV2 Verified
- Compiler
- solc 0.8.30+commit.73712a01
- Language
- Solidity
- Optimization
- Yes, 200 runs
- EVM version
- paris
- License
- —
- Verified
- 2026-10-12
contracts/CapybarasNFTStakingV2.sol
and 6 more files
Solidity
// SPDX-License-Identifier: MIT
pragma solidity >= 0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
interface ICapybarasNFTStaking {
struct Stake {
uint256 tokenId;
uint8 tier; // 1 for T1, 2 for T2, 3 for T3
uint256 multiplier; // 1e18 for 1x, 1.5e18 for 1.5x, 3e18 for 3x
uint256 stakeTime; // Timestamp when staked
}
function getUserStakes(address user) external view returns (Stake[] memory);
function stake(uint256 tokenId) external;
function unstake(uint256 tokenId) external;
function emergencyWithdrawNFT(uint256 tokenId) external;
function transferOwnership(address newOwner) external;
}
contract CapybarasNFTStakingV2 is Ownable, ReentrancyGuard {
ICapybarasNFTStaking public immutable stakeV1;
IERC20 public tokenContract;
IERC721 public immutable nftContract;
uint256 public constant RATE = 1_000;
uint256 public constant HOURS = 1 hours;
uint256 public basicRewards = 88;
bool public canArchived = false;
bool public stakeEnabled = false;
mapping(uint256 => StakeV2) public nftStakes;
mapping(uint256 => uint8) public nftTiers;
mapping(uint256 => uint256) public tierMultipliers;
mapping(address => uint256) public userAvailableRewards;
// Staking structure
struct StakeV2 {
address userAddress;
uint256 tokenId;
uint8 tier; // 1 for T1, 2 for T2, 3 for T3
uint256 multiplier; // 1e18 for 1x, 1.5e18 for 1.5x, 3e18 for 3x
uint256 stakeTime; // Timestamp when staked
}
// Events
event Staked(address indexed user, uint256 indexed tokenId, uint8 tier, uint256 multiplier);
event Unstaked(address indexed user, uint256 indexed tokenId, uint256 indexed nftRewards);
// Constructor
constructor(address _nftContract, address v1) Ownable(msg.sender) {
nftContract = IERC721(_nftContract);
stakeV1 = ICapybarasNFTStaking(v1);
// Set multipliers
tierMultipliers[1] = 1000; // T1: 1x
tierMultipliers[2] = 1500; // T2: 1.5x
tierMultipliers[3] = 3000; // T3: 3x
}
function upgradeToV2() public {
address _self = address(this);
ICapybarasNFTStaking.Stake[] memory stakes = stakeV1.getUserStakes(msg.sender);
for (uint8 i = 0; i < stakes.length; i++) {
ICapybarasNFTStaking.Stake memory _stake = stakes[i];
uint256 tokenId = _stake.tokenId;
nftStakes[tokenId] = StakeV2(msg.sender, tokenId, _stake.tier, _stake.multiplier, _stake.stakeTime);
stakeV1.emergencyWithdrawNFT(tokenId);
nftContract.transferFrom(_self, msg.sender, tokenId);
}
}
function claim() public {
require(address(tokenContract) != address(0), "Not enabled");
uint256 amount = userAvailableRewards[msg.sender];
uint256 hexAmount = amount * 10**18;
tokenContract.approve(address(this), hexAmount);
tokenContract.transferFrom(address(this), msg.sender, hexAmount);
userAvailableRewards[msg.sender] = 0;
}
function getUserStakes(uint256[] calldata tokenIds) public view returns (StakeV2[] memory) {
StakeV2[] memory stakes = new StakeV2[](tokenIds.length);
for (uint8 i = 0; i < tokenIds.length; i++) {
StakeV2 memory _stake = nftStakes[tokenIds[i]];
if (_stake.tokenId > 0)
stakes[i] = _stake;
}
return stakes;
}
function getPendingRewards(uint256[] calldata tokenIds) public view returns (uint256) {
StakeV2[] memory stakes = getUserStakes(tokenIds);
if (stakes.length == 0) return 0;
uint256 userRewards = 0;
for (uint i = 0; i < stakes.length; i++) {
StakeV2 memory _stake = stakes[i];
if (_stake.tokenId > 0) {
uint256 time = block.timestamp - _stake.stakeTime;
if (time > 1) {
uint256 hour = (time * RATE) / HOURS;
userRewards += ((hour * basicRewards * _stake.multiplier) / RATE / RATE);
}
}
}
return userRewards;
}
function stake(uint256 tokenId) nonReentrant public {
require(stakeEnabled, "Staking disabled");
require(nftContract.ownerOf(tokenId) == msg.sender, "Not owner");
// Assume a function to get tier from NFT metadata or external call
// In practice, integrate with NFT contract's getTier(tokenId) or use metadata
uint8 tier = _getNFTTier(tokenId); // Placeholder: implement based on NFT logic
uint256 multiplier = tierMultipliers[tier];
nftStakes[tokenId] = StakeV2(msg.sender, tokenId, tier, multiplier, block.timestamp);
emit Staked(msg.sender, tokenId, tier, multiplier);
}
function unstake(uint256 tokenId) nonReentrant public {
require(nftContract.ownerOf(tokenId) == msg.sender, "Not owner");
StakeV2 storage _stake = nftStakes[tokenId];
if (_stake.userAddress == address(0) || _stake.tokenId == 0) {
revert("Not staking yet");
}
// Rewards are cleared: no claim, just remove stake
uint256 userRewards = 0;
if (canArchived) {
uint256 time = block.timestamp - _stake.stakeTime;
if (time > 1) {
uint256 hour = (time * RATE) / HOURS;
userRewards = (hour * basicRewards * _stake.multiplier) / RATE / RATE;
userAvailableRewards[msg.sender] = userAvailableRewards[msg.sender] + userRewards;
}
}
// reset from stakes
_stake.userAddress = address(0);
_stake.tokenId = 0;
_stake.tier = 0;
_stake.stakeTime = 0;
nftStakes[tokenId] = _stake;
emit Unstaked(msg.sender, tokenId, userRewards);
}
function _getNFTTier(uint256 tokenId) internal view returns (uint8) {
uint8 tier = nftTiers[tokenId];
if (tier > 0) return tier;
return 1;
}
function setBasicRewards(uint256 _rewards) public onlyOwner {
basicRewards = _rewards;
}
function setTier(uint256[] memory ids, uint8[] memory tiers) public onlyOwner {
for (uint8 i = 0; i < ids.length && i < tiers.length; i++) {
uint256 id = ids[i];
nftTiers[id] = tiers[i];
}
}
function setTierMultipliers(uint8 _tier, uint256 _multipliers) public onlyOwner {
tierMultipliers[_tier] = _multipliers;
}
function setArchived(uint8 _archive) public onlyOwner {
canArchived = _archive == 1;
}
function setStakeEnabled(uint8 _enabled) public onlyOwner {
stakeEnabled = _enabled == 1;
}
function setTokenContract(address _token) public onlyOwner {
tokenContract = IERC20(_token);
}
function transferOwnershipV1(address newOwner) public onlyOwner {
stakeV1.transferOwnership(newOwner);
}
}
Other files
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }@openzeppelin/contracts/utils/ReentrancyGuard.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @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 EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * 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; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); 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 if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // 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; } }@openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol) pragma solidity >=0.4.16; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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); }@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/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. * * 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); } }@openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol) pragma solidity >=0.4.16; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ 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); }@openzeppelin/contracts/token/ERC721/IERC721.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.4.0) (token/ERC721/IERC721.sol) pragma solidity >=0.6.2; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC-721 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 ERC-721 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 ERC-721 * 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); }
ABI · 35 entries
json
[
{
"type": "constructor",
"inputs": [
{
"name": "_nftContract",
"type": "address",
"internalType": "address"
},
{
"name": "v1",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "OwnableInvalidOwner",
"type": "error",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "OwnableUnauthorizedAccount",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "Staked",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "tier",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "multiplier",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Unstaked",
"type": "event",
"inputs": [
{
"name": "user",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
},
{
"name": "nftRewards",
"type": "uint256",
"indexed": true,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "HOURS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "RATE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "basicRewards",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "canArchived",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "claim",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "getPendingRewards",
"type": "function",
"inputs": [
{
"name": "tokenIds",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "getUserStakes",
"type": "function",
"inputs": [
{
"name": "tokenIds",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"outputs": [
{
"name": "",
"type": "tuple[]",
"components": [
{
"name": "userAddress",
"type": "address",
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "tier",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "multiplier",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "stakeTime",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct CapybarasNFTStakingV2.StakeV2[]"
}
],
"stateMutability": "view"
},
{
"name": "nftContract",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IERC721"
}
],
"stateMutability": "view"
},
{
"name": "nftStakes",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "userAddress",
"type": "address",
"internalType": "address"
},
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "tier",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "multiplier",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "stakeTime",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "nftTiers",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setArchived",
"type": "function",
"inputs": [
{
"name": "_archive",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setBasicRewards",
"type": "function",
"inputs": [
{
"name": "_rewards",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setStakeEnabled",
"type": "function",
"inputs": [
{
"name": "_enabled",
"type": "uint8",
"internalType": "uint8"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setTier",
"type": "function",
"inputs": [
{
"name": "ids",
"type": "uint256[]",
"internalType": "uint256[]"
},
{
"name": "tiers",
"type": "uint8[]",
"internalType": "uint8[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setTierMultipliers",
"type": "function",
"inputs": [
{
"name": "_tier",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "_multipliers",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setTokenContract",
"type": "function",
"inputs": [
{
"name": "_token",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "stake",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "stakeEnabled",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "stakeV1",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract ICapybarasNFTStaking"
}
],
"stateMutability": "view"
},
{
"name": "tierMultipliers",
"type": "function",
"inputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "tokenContract",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "contract IERC20"
}
],
"stateMutability": "view"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "transferOwnershipV1",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "unstake",
"type": "function",
"inputs": [
{
"name": "tokenId",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "upgradeToV2",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "userAvailableRewards",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
}
]