文件 1 的 5:ERC20.sol
pragma solidity >=0.8.0;
abstract contract ERC20 {
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
string public name;
string public symbol;
uint8 public immutable decimals;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}
文件 2 的 5:ERC721.sol
pragma solidity >=0.8.0;
abstract contract ERC721 {
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed spender, uint256 indexed id);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
string public name;
string public symbol;
mapping(uint256 => address) internal _ownerOf;
mapping(address => uint256) internal _balanceOf;
function ownerOf(uint256 id) public view virtual returns (address owner) {
require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
}
function balanceOf(address owner) public view virtual returns (uint256) {
require(owner != address(0), "ZERO_ADDRESS");
return _balanceOf[owner];
}
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
}
function approve(address spender, uint256 id) public virtual {
address owner = _ownerOf[id];
require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");
getApproved[id] = spender;
emit Approval(owner, spender, id);
}
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function transferFrom(
address from,
address to,
uint256 id
) public virtual {
require(from == _ownerOf[id], "WRONG_FROM");
require(to != address(0), "INVALID_RECIPIENT");
require(
msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
"NOT_AUTHORIZED"
);
unchecked {
_balanceOf[from]--;
_balanceOf[to]++;
}
_ownerOf[id] = to;
delete getApproved[id];
emit Transfer(from, to, id);
}
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == 0x80ac58cd ||
interfaceId == 0x5b5e139f;
}
function _mint(address to, uint256 id) internal virtual {
require(to != address(0), "INVALID_RECIPIENT");
require(_ownerOf[id] == address(0), "ALREADY_MINTED");
unchecked {
_balanceOf[to]++;
}
_ownerOf[id] = to;
emit Transfer(address(0), to, id);
}
function _burn(uint256 id) internal virtual {
address owner = _ownerOf[id];
require(owner != address(0), "NOT_MINTED");
unchecked {
_balanceOf[owner]--;
}
delete _ownerOf[id];
delete getApproved[id];
emit Transfer(owner, address(0), id);
}
function _safeMint(address to, uint256 id) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _safeMint(
address to,
uint256 id,
bytes memory data
) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
}
abstract contract ERC721TokenReceiver {
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external virtual returns (bytes4) {
return ERC721TokenReceiver.onERC721Received.selector;
}
}
文件 3 的 5:NFTVault.sol
pragma solidity >=0.8.0;
import "./tokens/ERC721.sol";
import "./tokens/ERC20.sol";
import "./utils/owner.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract RapPearsNft is ERC721, Owner {
using Strings for *;
struct Rewards {
uint256 weight;
uint256 tracker;
}
struct MetaData {
string name;
address vaultAddress;
uint256 withdrawable;
uint256 id;
uint256 vaultType;
}
mapping(uint256 => Rewards) public deposits;
uint256 public yeildPerDeposit;
uint256 public totalWeight;
uint256 constant SCALAR = 1e10;
mapping(uint256 => uint256) locked;
uint256 internal lockTimeSeconds;
mapping(uint256 => mapping(address => bool)) public privateMintClaimed;
mapping(uint256 => mapping(uint256 => uint256)) public qtyPricing;
uint256 public defaultPricePerUnit = 1e17;
uint256 public pricingVersionCount = 1;
uint256 public maxWhitelistMintPerTx;
bool internal publicMint;
uint256 internal supplyCap;
mapping(address => uint256[]) public tokensByAddress;
mapping(uint256 => uint256) internal indexById;
ERC20 public weth;
uint256 internal devFeeBP;
uint256 public devBalance;
uint256 public currentId;
constructor(
address _weth,
uint256 _devFeeBP,
uint256 _lockTime,
uint256 _initalSupplyCap,
uint256 _initialMintAmount,
string memory _name,
string memory _symbol
) ERC721(_name, _symbol) {
weth = ERC20(_weth);
devFeeBP = _devFeeBP;
lockTimeSeconds = _lockTime;
supplyCap = _initalSupplyCap;
setMaxWhiteList(5);
ipfsLink = "ipfs://QmWYt6XezHy7PBwCYEHpWZYfSemjGwWMpHSxRmXVfSFEvQ/";
maxWhitelistMintPerTx = 5;
for (uint256 i; i < _initialMintAmount; ) {
_mintNewNFT();
unchecked {
++i;
}
}
}
function adminMint(uint256 amount)
external
onlyOwner
returns (uint256[] memory)
{
_takeFees();
uint256[] memory ret = new uint256[](amount);
for (uint256 i; i < amount; ) {
ret[i] = _mintNewNFT();
unchecked {
++i;
}
}
return ret;
}
function mintNewNft(uint256 amount)
external
payable
returns (uint256[] memory)
{
require(price(amount) <= msg.value, "underpaid");
require(publicMint, "not live");
_takeFees();
uint256[] memory ret = new uint256[](amount);
for (uint256 i; i < amount; ) {
ret[i] = _mintNewNFT();
unchecked {
++i;
}
}
return ret;
}
function lockUp(uint256 id) external {
require(msg.sender == ownerOf(id), "Not Owner");
locked[id] = block.timestamp;
deposits[id].weight = 100;
deposits[id].tracker += 100 * yeildPerDeposit;
totalWeight += 100;
}
event A(uint256);
function withdrawFromId(uint256 id, uint256 amount) public {
require(
block.timestamp - locked[id] >= lockTimeSeconds && locked[id] != 0,
"here"
);
locked[id] = 0;
_withdrawFromId(amount, id);
}
function bundleWithdraw() external {
uint256 length = tokensByAddress[msg.sender].length;
for (uint256 i; i < length; ) {
uint256 id = tokensByAddress[msg.sender][i];
if (
block.timestamp - locked[id] >= lockTimeSeconds &&
locked[id] != 0
) {
withdrawFromId(id, withdrawableById(id));
}
unchecked {
++i;
}
}
}
function withdrawableById(uint256 id)
public
view
returns (uint256 claimId)
{
return yieldPerId(id);
}
function claimDevFeeBPs() external onlyOwner {
weth.transfer(owner, devBalance);
}
function _mintNewNFT() internal returns (uint256) {
uint256 id = ++currentId;
require(currentId <= supplyCap);
_mint(msg.sender, id);
_addId(msg.sender, id);
return id;
}
function _withdrawFromId(uint256 amount, uint256 id) internal {
require(msg.sender == ownerOf(id) && amount <= withdrawableById(id));
deposits[id].weight = 0;
deposits[id].tracker = 0;
totalWeight -= 100;
weth.transfer(msg.sender, amount);
}
function _takeFees() internal {
(bool success, ) = payable(address(weth)).call{value: msg.value}("");
require(success);
uint256 toDev = (msg.value * devFeeBP) / 10000;
devBalance += toDev;
if (totalWeight > 0) {
distributeYeild(msg.value - toDev);
} else {
devBalance += (msg.value - toDev);
}
}
function _addId(address who, uint256 id) internal {
tokensByAddress[who].push(id);
indexById[id] = tokensByAddress[who].length - 1;
}
function _removeId(address who, uint256 id) internal {
uint256 index = indexById[id];
uint256 lastVal = tokensByAddress[who][tokensByAddress[who].length - 1];
tokensByAddress[who][index] = lastVal;
tokensByAddress[who].pop();
}
function distributeYeild(uint256 amount) public virtual {
yeildPerDeposit += ((amount * SCALAR) / totalWeight);
}
function yieldPerId(uint256 id) public view returns (uint256) {
uint256 pre = (deposits[id].weight * yeildPerDeposit) / SCALAR;
return pre - (deposits[id].tracker / SCALAR);
}
function price(uint256 _count) public view returns (uint256) {
uint256 pricePerUnit = qtyPricing[pricingVersionCount][_count];
if (_count > maxWhitelistMintPerTx) {
pricePerUnit = qtyPricing[pricingVersionCount][
maxWhitelistMintPerTx
];
}
if (pricePerUnit == 0) {
pricePerUnit = defaultPricePerUnit;
}
return pricePerUnit * _count;
}
function whitelistMint(
uint256 amount,
uint256 whitelistNonce,
bytes32 msgHash,
uint8 _v,
bytes32 _r,
bytes32 _s
) public payable returns (uint256[] memory) {
require(msg.value >= price(amount), "Value below price");
require(
!privateMintClaimed[whitelistNonce][msg.sender],
"Already claimed!"
);
bytes32 calculatedMsgHash = keccak256(
abi.encodePacked(msg.sender, whitelistNonce)
);
address signer = ecrecover(
keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", msgHash)
),
_v,
_r,
_s
);
require(calculatedMsgHash == msgHash, "Invalid hash");
require(owner == signer, "Access denied");
privateMintClaimed[whitelistNonce][msg.sender] = true;
_takeFees();
uint256[] memory ret = new uint256[](amount);
for (uint256 i; i < amount; ) {
ret[i] = _mintNewNFT();
unchecked {
++i;
}
}
return ret;
}
function setLockTime(uint256 _lockTime) external onlyOwner {
lockTimeSeconds = _lockTime;
}
function setMaxWhiteList(uint256 amount) public onlyOwner {
maxWhitelistMintPerTx = amount;
}
function setMintPrices(
uint256 _defaultPricePerUnit,
uint256[] memory qty,
uint256[] memory prices
) public onlyOwner {
require(
qty.length == prices.length,
"Qty input vs price length mismatch"
);
defaultPricePerUnit = _defaultPricePerUnit;
++pricingVersionCount;
bool containsMaxWhitelistMintPerTx = false;
for (uint256 i = 0; i < qty.length; i++) {
if (qty[i] == maxWhitelistMintPerTx) {
containsMaxWhitelistMintPerTx = true;
}
qtyPricing[pricingVersionCount][qty[i]] = prices[i];
}
require(
containsMaxWhitelistMintPerTx,
"prices do not include the max mint price"
);
}
function setSupplyCap(uint256 total) external onlyOwner {
supplyCap = total;
}
function setPublicMint(bool open) external onlyOwner {
publicMint = open;
}
string public ipfsLink;
function tokenURI(uint256 tokenId)
public
view
virtual
returns (string memory)
{
return string(abi.encodePacked(ipfsLink, tokenId.toString(), ".json"));
}
function setTokenUri(string memory baseURI) public onlyOwner {
ipfsLink = baseURI;
}
function totalSupply() public view returns (uint256) {
return supplyCap;
}
function transferFrom(
address from,
address to,
uint256 id
) public override {
require(
locked[id] == 0 || locked[id] - block.timestamp >= lockTimeSeconds
);
locked[id] = 0;
_removeId(from, id);
_addId(to, id);
super.transferFrom(from, to, id);
}
}
文件 4 的 5:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
文件 5 的 5:owner.sol
pragma solidity >=0.8.0;
abstract contract Owner {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
address public owner;
modifier onlyOwner() {
require (msg.sender == owner, "NOT_OWNER");
_;
}
constructor() {
_transferOwnership(msg.sender);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
address oldOwner = owner;
owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
{
"compilationTarget": {
"contracts/NFTVault.sol": "RapPearsNft"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_weth","type":"address"},{"internalType":"uint256","name":"_devFeeBP","type":"uint256"},{"internalType":"uint256","name":"_lockTime","type":"uint256"},{"internalType":"uint256","name":"_initalSupplyCap","type":"uint256"},{"internalType":"uint256","name":"_initialMintAmount","type":"uint256"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"A","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"adminMint","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bundleWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimDevFeeBPs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultPricePerUnit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"weight","type":"uint256"},{"internalType":"uint256","name":"tracker","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"distributeYeild","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ipfsLink","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"lockUp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxWhitelistMintPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintNewNft","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pricingVersionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"privateMintClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"qtyPricing","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockTime","type":"uint256"}],"name":"setLockTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_defaultPricePerUnit","type":"uint256"},{"internalType":"uint256[]","name":"qty","type":"uint256[]"},{"internalType":"uint256[]","name":"prices","type":"uint256[]"}],"name":"setMintPrices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"open","type":"bool"}],"name":"setPublicMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"name":"setSupplyCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setTokenUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokensByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"whitelistNonce","type":"uint256"},{"internalType":"bytes32","name":"msgHash","type":"bytes32"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"whitelistMint","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFromId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"withdrawableById","outputs":[{"internalType":"uint256","name":"claimId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yeildPerDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"yieldPerId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]