文件 1 的 17:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 17:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 3 的 17:ECDSA.sol
pragma solidity ^0.8.0;
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS,
InvalidSignatureV
}
function _throwError(RecoverError error) private pure {
if (error == RecoverError.NoError) {
return;
} else if (error == RecoverError.InvalidSignature) {
revert("ECDSA: invalid signature");
} else if (error == RecoverError.InvalidSignatureLength) {
revert("ECDSA: invalid signature length");
} else if (error == RecoverError.InvalidSignatureS) {
revert("ECDSA: invalid signature 's' value");
} else if (error == RecoverError.InvalidSignatureV) {
revert("ECDSA: invalid signature 'v' value");
}
}
function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else if (signature.length == 64) {
bytes32 r;
bytes32 vs;
assembly {
r := mload(add(signature, 0x20))
vs := mload(add(signature, 0x40))
}
return tryRecover(hash, r, vs);
} else {
return (address(0), RecoverError.InvalidSignatureLength);
}
}
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, signature);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address, RecoverError) {
bytes32 s;
uint8 v;
assembly {
s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
v := add(shr(255, vs), 27)
}
return tryRecover(hash, v, r, s);
}
function recover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, r, vs);
_throwError(error);
return recovered;
}
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address, RecoverError) {
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS);
}
if (v != 27 && v != 28) {
return (address(0), RecoverError.InvalidSignatureV);
}
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature);
}
return (signer, RecoverError.NoError);
}
function recover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
(address recovered, RecoverError error) = tryRecover(hash, v, r, s);
_throwError(error);
return recovered;
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
}
}
文件 4 的 17:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 5 的 17:ERC721.sol
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
string private _name;
string private _symbol;
mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;
mapping(uint256 => address) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}
文件 6 的 17:ERC721Enumerable.sol
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "./IERC721Enumerable.sol";
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
mapping(uint256 => uint256) private _ownedTokensIndex;
uint256[] private _allTokens;
mapping(uint256 => uint256) private _allTokensIndex;
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId;
_ownedTokensIndex[lastTokenId] = tokenIndex;
}
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId;
_allTokensIndex[lastTokenId] = tokenIndex;
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}
文件 7 的 17:HypeBears.sol
pragma solidity 0.8.4;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
contract HypeBears is ERC721("HypeBears", "HB"), ERC721Enumerable, Ownable {
using ECDSA for bytes32;
using SafeMath for uint256;
using Strings for uint256;
address public proxyRegistryAddress = 0xa5409ec958C83C3f309868babACA7c86DCB077c1;
string private baseURI = 'ipfs://bafybeidkik23lcp7my72udcgdbt5h6ytpnyph3a2lw3f7tnuo6zxzbehom/';
string private blindURI;
uint256 public mintLimit = 1;
uint256 private constant TOTAL_NFT = 10000;
uint256 public mintPrice = 0.4 ether;
bool public reveal;
bool public mintActive;
mapping (address => bool) public whitelist;
mapping (address => bool) public addressMinted;
address whitelistSigner;
uint256 public partnerMintAmount = 100;
mapping(address => uint256) public partnerMintAvailableBy;
constructor() {
partnerMintAvailableBy[0xBC3C2C6e7BaAeB7C7EA2ad4B2Fa8681a91d47Ccd] = 50;
partnerMintAvailableBy[0xBC3C2C6e7BaAeB7C7EA2ad4B2Fa8681a91d47Ccd] = 49;
partnerMintAvailableBy[0x6C63244f8efFE378abD24240EEea27c732f8fc6D] = 1;
}
function revealNow() external onlyOwner {
reveal = true;
}
function setMintActive(bool _isActive) external onlyOwner {
mintActive = _isActive;
}
function setURIs(string memory _blindURI, string memory _URI) external onlyOwner {
blindURI = _blindURI;
baseURI = _URI;
}
function setWhitelistSigner(address _address) external onlyOwner {
whitelistSigner = _address;
}
function addToWhitelist(address _newAddress) external onlyOwner {
whitelist[_newAddress] = true;
}
function removeFromWhitelist(address _address) external onlyOwner {
whitelist[_address] = false;
}
function addMultipleToWhitelist(address[] calldata _addresses) external onlyOwner {
require(_addresses.length <= 10000, "Provide less addresses in one function call");
for (uint256 i = 0; i < _addresses.length; i++) {
whitelist[_addresses[i]] = true;
}
}
function removeMultipleFromWhitelist(address[] calldata _addresses) external onlyOwner {
require(_addresses.length <= 10000, "Provide less addresses in one function call");
for (uint256 i = 0; i < _addresses.length; i++) {
whitelist[_addresses[i]] = false;
}
}
function canMint(address _address, bytes memory _signature) public view returns (bool, string memory) {
if (!whitelist[_address]) {
bytes32 hash = keccak256(abi.encodePacked(whitelistSigner, _address));
bytes32 messageHash = hash.toEthSignedMessageHash();
address signer = messageHash.recover(_signature);
if (signer != whitelistSigner) {
return (false, "Invalid signature");
}
}
if (addressMinted[_address]) {
return (false, "Already withdrawn");
}
return (true, "");
}
function withdraw() public onlyOwner {
uint256 balance = address(this).balance;
uint256 amount1 = balance * 70 / 100;
uint256 amount2 = balance - amount1;
payable(0xe0F7204f04b060715f858Ba8Ae357f57E5494d18).transfer(amount1);
payable(0x029c2D9EDC080A5A077f30F3bf6122e100F2aDc6).transfer(amount2);
}
function updateMintLimit(uint256 _newLimit) public onlyOwner {
mintLimit = _newLimit;
}
function updateMintPrice(uint256 _newPrice) public onlyOwner {
mintPrice = _newPrice;
}
function addPartnerMint(address account, uint256 amount) public onlyOwner {
partnerMintAmount += amount;
require(totalSupply().add(partnerMintAmount) <= TOTAL_NFT, "Can't add partner more than available");
partnerMintAvailableBy[account] += amount;
}
function mintNFT(uint256 _numOfTokens, bytes memory _signature) public payable {
require(mintActive, 'Not active');
require(_numOfTokens <= mintLimit, "Can't mint more than limit per tx");
require(mintPrice.mul(_numOfTokens) <= msg.value, "Insufficient payable value");
require(totalSupply().add(_numOfTokens).add(partnerMintAmount) <= TOTAL_NFT, "Can't mint more than 10000");
(bool success, string memory reason) = canMint(msg.sender, _signature);
require(success, reason);
for(uint i = 0; i < _numOfTokens; i++) {
_safeMint(msg.sender, totalSupply() + 1);
}
addressMinted[msg.sender] = true;
}
function partnersMintMultiple(address[] memory _to) public {
uint256 amount = _to.length;
require(partnerMintAmount >= amount, "Can't mint more than total available for partners");
require(partnerMintAvailableBy[msg.sender] >= amount, "Can't mint more than available for msg.sender");
for(uint256 i = 0; i < amount; i++){
_safeMint(_to[i],totalSupply() + 1);
}
partnerMintAmount -= amount;
partnerMintAvailableBy[msg.sender] -= amount;
}
function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");
if (!reveal) {
return string(abi.encodePacked(blindURI));
} else {
return string(abi.encodePacked(baseURI, _tokenId.toString()));
}
}
function supportsInterface(bytes4 _interfaceId) public view override (ERC721, ERC721Enumerable) returns (bool) {
return super.supportsInterface(_interfaceId);
}
function _beforeTokenTransfer(address _from, address _to, uint256 _tokenId) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(_from, _to, _tokenId);
}
function isApprovedForAll(address owner, address operator) override public view returns(bool) {
if (proxyRegistryAddress == operator) {
return true;
}
return super.isApprovedForAll(owner, operator);
}
function updateProxy(address _proxy) external onlyOwner {
proxyRegistryAddress = _proxy;
}
}
文件 8 的 17:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 9 的 17:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 10 的 17:IERC721Enumerable.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Enumerable is IERC721 {
function totalSupply() external view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
function tokenByIndex(uint256 index) external view returns (uint256);
}
文件 11 的 17:IERC721Metadata.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 12 的 17:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 13 的 17:IHypebItems.sol
pragma solidity ^0.8.4;
interface IHypebItems {
function create(uint256, string calldata) external returns(uint256);
function mintItem(uint256, address, uint256) external;
function setURI(string calldata, uint256) external;
}
文件 14 的 17:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_setOwner(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 15 的 17:SafeMath.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
文件 16 的 17:Staking.sol
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "./IHypebItems.sol";
import "./HypeBears.sol";
contract Hypeb {
address public operator;
uint256 public totalSupply;
bool public paused;
IERC721 public hypebearsWalking;
IERC721 public hypebears;
IHypebItems public itemsContract;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
mapping(address => Hypebear[]) internal stakers;
mapping(address => Hypebear[]) internal stakersWalking;
uint256[] public bonusLevels;
mapping(uint256 => uint256) public levelPercent;
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
uint256 public rewardAmount = 1;
uint256 public rewardPeriod = 1 days;
struct Hypebear {
uint256 stakedTimestamp;
uint256 tokenId;
}
struct Item {
uint256 totalSupply;
uint256 maxSupply;
uint256 price;
}
uint256 public totalItemIdAmount;
mapping(uint256 => Item) public items;
mapping(address => uint256) public lastClaim;
mapping(address => bool) public blackList;
function name() external pure returns (string memory) {
return "HYPEB";
}
function symbol() external pure returns (string memory) {
return "HYPEB";
}
function decimals() external pure returns (uint8) {
return 0;
}
constructor(address _hypebears, address _hypebearsWalking) {
operator = msg.sender;
hypebears = IERC721(_hypebears);
hypebearsWalking = IERC721(_hypebearsWalking);
_status = _NOT_ENTERED;
bonusLevels.push(3);
bonusLevels.push(5);
bonusLevels.push(10);
levelPercent[1] = 5;
levelPercent[2] = 10;
levelPercent[3] = 22;
}
function approve(address spender, uint256 value) external returns (bool) {
allowance[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
function transfer(address to, uint256 value) external whenNotPaused returns (bool) {
require(!blackList[msg.sender], "Address Blocked");
_transfer(msg.sender, to, value);
return true;
}
function transferFrom(
address from,
address to,
uint256 value
) external whenNotPaused returns (bool) {
require(!blackList[msg.sender], "Address Blocked");
if (allowance[from][msg.sender] != type(uint256).max) {
allowance[from][msg.sender] -= value;
}
_transfer(from, to, value);
return true;
}
function totalStakedBy(address _staker) public view returns(uint256) {
return (stakers[_staker].length + stakersWalking[_staker].length);
}
function hypebearsOfStaker(address _staker, bool _walking) public view returns (uint256[] memory) {
Hypebear[] memory st = _walking ? stakersWalking[_staker] : stakers[_staker];
uint256[] memory tokenIds = new uint256[](st.length);
for (uint256 i = 0; i < st.length; i++) {
tokenIds[i] = st[i].tokenId;
}
return tokenIds;
}
function stake(uint256[] memory _hypebears, bool _walking) public nonReentrant whenNotPaused {
if (totalStakedBy(msg.sender) > 0) {
withdrawTo(msg.sender);
}
IERC721 hb = _walking ? IERC721(hypebearsWalking) : IERC721(hypebears);
Hypebear[] storage st = _walking ? stakersWalking[msg.sender] : stakers[msg.sender];
for (uint256 i = 0; i < _hypebears.length; i++) {
require(hb.ownerOf(_hypebears[i]) == msg.sender, "Not owner");
hb.transferFrom(msg.sender, address(this), _hypebears[i]);
st.push(Hypebear(block.timestamp, _hypebears[i]));
}
}
function removeIdsFromStaker(Hypebear[] storage st, uint256[] memory _tokenIds) internal {
for (uint256 i = 0; i < _tokenIds.length; i++) {
for (uint256 j = 0; j < st.length; j++) {
if (_tokenIds[i] == st[j].tokenId) {
st[j] = st[st.length - 1];
st.pop();
}
}
}
}
function unstake(uint256[] calldata _tokenIds, bool _walking) external nonReentrant whenNotPaused {
require(!blackList[msg.sender], "Address Blocked");
IERC721 hb = _walking ? IERC721(hypebearsWalking) : IERC721(hypebears);
Hypebear[] storage st = _walking ? stakersWalking[msg.sender] : stakers[msg.sender];
for (uint256 i = 0; i < _tokenIds.length; i++) {
bool owned;
for (uint256 j = 0; j < st.length; j++) {
if (st[j].tokenId == _tokenIds[i]) {
owned = true;
}
}
require(owned, "NOT OWNED");
hb.transferFrom(address(this), msg.sender, _tokenIds[i]);
}
withdrawTo(msg.sender);
removeIdsFromStaker(st, _tokenIds);
}
function emergencyWithdrawNFT() external nonReentrant whenNotPaused {
require(!blackList[msg.sender], "Address Blocked");
IERC721 hbw = IERC721(hypebearsWalking);
Hypebear[] storage stw = stakersWalking[msg.sender];
for (uint256 j = 0; j < stw.length; j++) {
hbw.transferFrom(address(this), msg.sender, stw[j].tokenId);
}
delete stakersWalking[msg.sender];
IERC721 hb = IERC721(hypebears);
Hypebear[] storage st = stakers[msg.sender];
for (uint256 j = 0; j < st.length; j++) {
hb.transferFrom(address(this), msg.sender, st[j].tokenId);
}
delete stakers[msg.sender];
}
function claim() external nonReentrant whenNotPaused {
require(!blackList[msg.sender], "Address Blocked");
withdrawTo(msg.sender);
}
function withdrawTo(address to) internal {
uint256 reward = calculateRewards(to);
if (reward > 0) {
lastClaim[msg.sender] = block.timestamp;
_mint(to, reward);
}
}
function calculateRewards(address _staker) public view returns(uint256) {
uint256 HypebAmount;
HypebAmount += _calculateRewards(stakers[_staker], lastClaim[_staker]);
HypebAmount += _calculateRewards(stakersWalking[_staker], lastClaim[_staker]);
HypebAmount += HypebAmount * calculateBalanceBonus(totalStakedBy(_staker)) / 100;
return HypebAmount;
}
function _calculateRewards(Hypebear[] memory st, uint256 _lastClaim) internal view returns(uint256) {
uint256 result;
uint256 stakerBalance = st.length;
for (uint256 i = 0; i < stakerBalance; i++) {
result +=
calculateHypeb(
_lastClaim,
st[i].stakedTimestamp,
block.timestamp
);
}
return result;
}
function calculateBalanceBonus(uint256 balance) public view returns(uint256) {
for (uint256 i = 0; i < bonusLevels.length; i++) {
if (balance < bonusLevels[i]) return levelPercent[i];
}
return levelPercent[bonusLevels.length];
}
function getAllBonusesByTokenAmount() external view returns(uint256[] memory) {
uint256[] memory percents = new uint256[](bonusLevels[bonusLevels.length - 1]);
for (uint256 i = 0; i < percents.length; i++) {
percents[i] = calculateBalanceBonus(i+1);
}
return percents;
}
function calculateHypeb(
uint256 _lastClaimedTimestamp,
uint256 _stakedTimestamp,
uint256 _currentTimestamp
) internal view returns (uint256 hypeb) {
_lastClaimedTimestamp = _lastClaimedTimestamp < _stakedTimestamp ? _stakedTimestamp : _lastClaimedTimestamp;
uint256 unclaimedTime = _currentTimestamp - _lastClaimedTimestamp;
hypeb = unclaimedTime * rewardAmount/ rewardPeriod;
}
function createItem(uint256 maxSupply, string calldata uri, uint256 _price) external onlyOperator {
uint256 id = itemsContract.create(maxSupply, uri);
items[id].maxSupply = maxSupply;
items[id].price = _price;
totalItemIdAmount = id;
}
function updateItem(uint256 id, uint256 maxSupply, uint256 _price, string calldata uri) external onlyOperator {
items[id].maxSupply = maxSupply;
items[id].price = _price;
if (bytes(uri).length > 0) {
itemsContract.setURI(uri, id);
}
}
function mintItem(uint256 id, uint256 amount) external {
require(balanceOf[msg.sender] >= items[id].price * amount, "Insufficient balance");
_burn(msg.sender, items[id].price * amount);
itemsContract.mintItem(id, msg.sender, amount);
items[id].totalSupply += amount;
}
function allItemsAmounts() external view returns (Item[] memory) {
Item[] memory itemsList = new Item[](totalItemIdAmount);
for (uint256 i = 0; i < itemsList.length; i++) {
itemsList[i] = items[i + 1];
}
return itemsList;
}
function staker(address staker_) public view returns (Hypebear[] memory) {
return stakers[staker_];
}
function stakerWalking(address staker_) public view returns (Hypebear[] memory) {
return stakersWalking[staker_];
}
function updateItemsContract(address newAddress) external onlyOperator {
itemsContract = IHypebItems(newAddress);
}
function updateBonusLevels(uint256[] memory levels, uint256[] memory percents) external onlyOperator {
require(levels.length == percents.length,"Different lengths");
delete bonusLevels;
for (uint256 i = 0; i < levels.length; i++) {
bonusLevels.push(levels[i]);
levelPercent[i + 1] = percents[i];
}
}
function updateRewardPeriod(uint256 newPeriod) external onlyOperator {
rewardPeriod = newPeriod;
}
function updateRewardAmount(uint256 newAmount) external onlyOperator {
rewardAmount = newAmount;
}
function setOperator(address _newOperator) external onlyOperator {
operator = _newOperator;
}
function setPaused(bool _paused) external onlyOperator {
paused = _paused;
}
function setHypebearsAddress(address _newAddress) external onlyOperator {
hypebears = IERC721(_newAddress);
}
function setHypebearsWalkingAddress(address _newAddress) external onlyOperator {
hypebearsWalking = IERC721(_newAddress);
}
function multipleBlacklist(address[] calldata addresses_, bool[] calldata statuses_) external onlyOperator {
for (uint256 i = 0; i < addresses_.length; i++) {
blackList[addresses_[i]] = statuses_[i];
}
}
function _transfer(
address from,
address to,
uint256 value
) internal {
require(balanceOf[from] >= value, "ERC20: transfer amount exceeds balance");
balanceOf[from] -= value;
balanceOf[to] += value;
emit Transfer(from, to, value);
}
function _mint(address to, uint256 value) internal {
totalSupply += value;
balanceOf[to] += value;
emit Transfer(address(0), to, value);
}
function _burn(address from, uint256 value) internal {
balanceOf[from] -= value;
totalSupply -= value;
emit Transfer(from, address(0), value);
}
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
modifier onlyOperator() {
require(msg.sender == operator, "NOT ALLOWED");
_;
}
modifier whenNotPaused() {
require(!paused, "Pausable: paused");
_;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 17 的 17: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);
}
}
{
"compilationTarget": {
"contracts/Staking.sol": "Hypeb"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_hypebears","type":"address"},{"internalType":"address","name":"_hypebearsWalking","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"allItemsAmounts","outputs":[{"components":[{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"internalType":"struct Hypeb.Item[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"blackList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"bonusLevels","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"calculateBalanceBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"}],"name":"calculateRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"string","name":"uri","type":"string"},{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"createItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"emergencyWithdrawNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllBonusesByTokenAmount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hypebears","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"},{"internalType":"bool","name":"_walking","type":"bool"}],"name":"hypebearsOfStaker","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hypebearsWalking","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"items","outputs":[{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"itemsContract","outputs":[{"internalType":"contract IHypebItems","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"levelPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses_","type":"address[]"},{"internalType":"bool[]","name":"statuses_","type":"bool[]"}],"name":"multipleBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setHypebearsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setHypebearsWalkingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOperator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_hypebears","type":"uint256[]"},{"internalType":"bool","name":"_walking","type":"bool"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"staker_","type":"address"}],"name":"staker","outputs":[{"components":[{"internalType":"uint256","name":"stakedTimestamp","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct Hypeb.Hypebear[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker_","type":"address"}],"name":"stakerWalking","outputs":[{"components":[{"internalType":"uint256","name":"stakedTimestamp","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct Hypeb.Hypebear[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalItemIdAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_staker","type":"address"}],"name":"totalStakedBy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bool","name":"_walking","type":"bool"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"levels","type":"uint256[]"},{"internalType":"uint256[]","name":"percents","type":"uint256[]"}],"name":"updateBonusLevels","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"updateItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"updateItemsContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"updateRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPeriod","type":"uint256"}],"name":"updateRewardPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"}]