编译器
0.8.19+commit.7dd6d404
文件 1 的 14:DefaultOperatorFilterer.sol
pragma solidity ^0.8.13;
import {OperatorFilterer} from "./OperatorFilterer.sol";
abstract contract DefaultOperatorFilterer is OperatorFilterer {
address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);
constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}
文件 2 的 14: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;
}
}
文件 3 的 14:ERC2981.sol
pragma solidity ^0.8.0;
import "../../interfaces/IERC2981.sol";
import "../../utils/introspection/ERC165.sol";
abstract contract ERC2981 is IERC2981, ERC165 {
struct RoyaltyInfo {
address receiver;
uint96 royaltyFraction;
}
RoyaltyInfo private _defaultRoyaltyInfo;
mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
}
function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) {
RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];
if (royalty.receiver == address(0)) {
royalty = _defaultRoyaltyInfo;
}
uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator();
return (royalty.receiver, royaltyAmount);
}
function _feeDenominator() internal pure virtual returns (uint96) {
return 10000;
}
function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: invalid receiver");
_defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
}
function _deleteDefaultRoyalty() internal virtual {
delete _defaultRoyaltyInfo;
}
function _setTokenRoyalty(
uint256 tokenId,
address receiver,
uint96 feeNumerator
) internal virtual {
require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice");
require(receiver != address(0), "ERC2981: Invalid parameters");
_tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
}
function _resetTokenRoyalty(uint256 tokenId) internal virtual {
delete _tokenRoyaltyInfo[tokenId];
}
}
文件 4 的 14:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 5 的 14:IERC2981.sol
pragma solidity ^0.8.0;
import "../utils/introspection/IERC165.sol";
interface IERC2981 is IERC165 {
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
returns (address receiver, uint256 royaltyAmount);
}
文件 6 的 14:IOperatorFilterRegistry.sol
pragma solidity ^0.8.13;
interface IOperatorFilterRegistry {
function isOperatorAllowed(address registrant, address operator) external view returns (bool);
function register(address registrant) external;
function registerAndSubscribe(address registrant, address subscription) external;
function registerAndCopyEntries(address registrant, address registrantToCopy) external;
function unregister(address addr) external;
function updateOperator(address registrant, address operator, bool filtered) external;
function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
function subscribe(address registrant, address registrantToSubscribe) external;
function unsubscribe(address registrant, bool copyExistingEntries) external;
function subscriptionOf(address addr) external returns (address registrant);
function subscribers(address registrant) external returns (address[] memory);
function subscriberAt(address registrant, uint256 index) external returns (address);
function copyEntriesOf(address registrant, address registrantToCopy) external;
function isOperatorFiltered(address registrant, address operator) external returns (bool);
function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
function filteredOperators(address addr) external returns (address[] memory);
function filteredCodeHashes(address addr) external returns (bytes32[] memory);
function filteredOperatorAt(address registrant, uint256 index) external returns (address);
function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
function isRegistered(address addr) external returns (bool);
function codeHashOf(address addr) external returns (bytes32);
}
文件 7 的 14:KillaCubs.sol
pragma solidity ^0.8.19;
import "./KillaCubs/KillaCubsRestrictor.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
interface IURIManager {
function getTokenURI(
uint256 id,
Token memory token
) external view returns (string memory);
}
contract KillaCubs is KillaCubsRestrictor, IURIManager {
using Strings for uint256;
using Strings for uint16;
IURIManager public uriManager;
string public baseURI;
string public baseURIFinalized;
uint256 public finalizedGeneration;
constructor(
address bitsAddress,
address gearAddress,
address superOwner
) KillaCubsRestrictor(bitsAddress, gearAddress, superOwner) {
uriManager = IURIManager(this);
}
function mint(
address owner,
uint256[] calldata ids,
bool staked
) public onlyAuthority {
_mint(owner, ids, staked);
}
function mint(address owner, uint16 n, bool staked) external onlyAuthority {
_mint(owner, n, staked);
if (counters.batched > 5555) revert Overflow();
}
function mintRedeemed(
address owner,
uint16 n,
bool staked
) external onlyAuthority {
_mint(owner, n, staked);
counters.redeems += n;
wallets[owner].redeems += n;
if (counters.batched > 5555) revert Overflow();
}
function useAllowance(
address sender,
address main,
uint256 n,
bool holders,
uint256 allowance
) external onlyAuthority {
wallets[sender].allowlistMints += uint16(n);
Wallet storage w = wallets[main];
if (holders) {
w.holderMints += uint16(n);
if (w.holderMints > allowance) revert Overflow();
} else {
w.privateMints += uint16(n);
if (w.privateMints > allowance) revert Overflow();
}
}
function tokenURI(uint256 id) external view returns (string memory) {
Token memory token = resolveToken(id);
return uriManager.getTokenURI(id, token);
}
function getTokenURI(
uint256 id,
Token memory token
) public view returns (string memory) {
bool staked = token.stakeTimestamp > 0;
uint256 phase = _getIncubationPhase(token);
uint256 gen = token.generation;
if (laterGenerations[id] != 0) gen = laterGenerations[id];
if (staked) {
return
string(
abi.encodePacked(
baseURI,
gen == 0 ? "initial-" : "remix-",
id.toString(),
"-",
phase.toString(),
"-",
token.bit.toString()
)
);
}
string storage base = gen < finalizedGeneration
? baseURI
: baseURIFinalized;
return
string(
abi.encodePacked(
base,
gen == 0 ? "cubryo-" : "cub-",
id.toString(),
"-",
phase.toString()
)
);
}
function configureRoyalties(
address royaltyReceiver,
uint96 royaltyAmount
) external onlyOwner {
_setDefaultRoyalty(royaltyReceiver, royaltyAmount);
}
function toggleRestricted(bool restricted_) external onlyOwner {
restricted = restricted_;
}
function configureStakingWindows(
uint256 initialLength,
uint256 remixLength
) external onlyOwner {
initialIncubationLength = initialLength;
remixIncubationLength = remixLength;
}
function setIncubator(address addr) external onlyOwner {
incubator = IIncubator(addr);
}
function startNexGeneration() external onlyOwner {
activeGeneration++;
}
function finalizeGeneration(
uint256 gen,
string calldata uri
) external onlyOwner {
finalizedGeneration = gen;
baseURIFinalized = uri;
}
function setURIManager(address addr) external onlyOwner {
uriManager = IURIManager(addr);
}
function setBaseUri(string calldata uri) external onlyOwner {
baseURI = uri;
}
function withdraw(address to) external onlyOwner {
if (to == address(0)) revert NotAllowed();
payable(to).transfer(address(this).balance);
}
}
文件 8 的 14:KillaCubsERC721.sol
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/token/common/ERC2981.sol";
struct Token {
address owner;
uint16 linkedNext;
uint16 linkedPrev;
uint32 stakeTimestamp;
uint8 generation;
uint8 incubationPhase;
uint16 bit;
}
struct Wallet {
uint16 balance;
uint16 stakes;
uint16 linkedMints;
uint16 batchedMints;
uint16 allowlistMints;
uint16 privateMints;
uint16 holderMints;
uint16 redeems;
}
struct MintCounters {
uint16 linked;
uint16 batched;
uint16 redeems;
uint16 stakes;
}
interface IIncubator {
function add(address owner, uint256[] calldata tokenIds) external;
function add(address owner, uint256 start, uint256 count) external;
function remove(address owner, uint256[] calldata tokenIds) external;
function remove(address owner, uint256 start, uint256 count) external;
}
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
abstract contract KillaCubsERC721 is ERC2981 {
string public name;
string public symbol;
IIncubator public incubator;
MintCounters public counters;
mapping(address => Wallet) public wallets;
mapping(uint256 => Token) public tokens;
mapping(uint256 => address) private tokenApprovals;
mapping(address => mapping(address => bool)) private operatorApprovals;
error TransferToNonERC721ReceiverImplementer();
error NonExistentToken();
error NotAllowed();
error Overflow();
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
);
constructor() {
name = "KillaCubs";
symbol = "KillaCubs";
_setDefaultRoyalty(msg.sender, 500);
}
function _mint(address to, uint256 n, bool staked) internal {
uint256 tokenId = 3334 + counters.batched;
uint256 end = tokenId + n - 1;
if (end > 8888) revert NotAllowed();
Token storage token = tokens[tokenId];
token.owner = to;
counters.batched += uint16(n);
wallets[to].batchedMints += uint16(n);
if (staked) {
incubator.add(to, tokenId, n);
token.stakeTimestamp = uint32(block.timestamp);
counters.stakes += uint16(n);
wallets[to].stakes += uint16(n);
while (tokenId <= end) {
emit Transfer(address(0), to, tokenId);
emit Transfer(to, address(this), tokenId);
tokenId++;
}
} else {
wallets[to].balance += uint16(n);
while (tokenId <= end) {
emit Transfer(address(0), to, tokenId);
tokenId++;
}
}
}
function _mint(
address to,
uint256[] calldata tokenIds,
bool staked
) internal {
for (uint256 i = 0; i < tokenIds.length; i++) {
uint256 id = tokenIds[i];
Token storage token = tokens[id];
if (id == 0) revert NotAllowed();
if (token.owner != address(0)) revert NotAllowed();
if (token.linkedPrev != 0) revert NotAllowed();
token.owner = to;
emit Transfer(address(0), to, id);
if (staked) {
emit Transfer(to, address(this), id);
token.stakeTimestamp = uint32(block.timestamp);
}
if (i == 0) {
token.owner = to;
} else {
token.linkedPrev = uint16(tokenIds[i - 1]);
tokens[tokenIds[i - 1]].linkedNext = uint16(id);
}
}
counters.linked += uint16(tokenIds.length);
if (staked) {
counters.stakes += uint16(tokenIds.length);
wallets[to].stakes += uint16(tokenIds.length);
incubator.add(to, tokenIds);
} else {
wallets[to].balance += uint16(tokenIds.length);
}
wallets[to].linkedMints += uint16(tokenIds.length);
}
function totalSupply() public view virtual returns (uint256) {
return counters.linked + counters.batched;
}
function balanceOf(
address owner
) external view virtual returns (uint256 balance) {
if (owner == address(this)) return counters.stakes;
return wallets[owner].balance;
}
function ownerOf(uint256 id) public view virtual returns (address) {
Token memory token = resolveToken(id);
if (token.stakeTimestamp != 0) return address(this);
return token.owner;
}
function rightfulOwnerOf(
uint256 tokenId
) public view virtual returns (address) {
return resolveToken(tokenId).owner;
}
function resolveToken(uint256 id) public view returns (Token memory) {
Token memory token = tokens[id];
if (token.owner == address(0)) {
Token memory temp = token;
if (token.linkedPrev != 0) {
do token = tokens[token.linkedPrev]; while (
token.owner == address(0)
);
} else if (id > 3333 && id <= 3333 + counters.batched) {
do token = tokens[--id]; while (token.owner == address(0));
} else {
revert NonExistentToken();
}
token.bit = temp.bit;
token.linkedNext = temp.linkedNext;
token.linkedPrev = temp.linkedPrev;
}
return token;
}
function resolveTokens(
uint256[] calldata ids
) public view returns (Token[] memory) {
Token[] memory ret = new Token[](ids.length);
bool skip = false;
Token memory token;
for (uint256 i = 0; i < ids.length; i++) {
uint256 id = ids[i];
if (skip) skip = false;
else token = resolveToken(id);
ret[i] = token;
uint256 nextId;
if (token.linkedNext != 0) {
nextId = token.linkedNext;
} else if (id > 3333 && id < 3333 + counters.batched) {
nextId = id + 1;
} else {
continue;
}
if (tokens[nextId].owner != address(0)) continue;
if (i + 1 < ids.length && ids[i + 1] == nextId) {
skip = true;
token.bit = tokens[nextId].bit;
token.linkedNext = tokens[nextId].linkedNext;
token.linkedPrev = tokens[nextId].linkedPrev;
continue;
}
}
return ret;
}
function safeTransferFrom(
address from,
address to,
uint256 id,
bytes memory data
) public virtual {
transferFrom(from, to, id);
if (!_checkOnERC721Received(from, to, id, data))
revert TransferToNonERC721ReceiverImplementer();
}
function safeTransferFrom(
address from,
address to,
uint256 id
) public virtual {
safeTransferFrom(from, to, id, "");
}
function transferFrom(address from, address to, uint256 id) public virtual {
if (to == from) revert NotAllowed();
if (to == address(0)) revert NotAllowed();
Token memory token = resolveToken(id);
if (token.stakeTimestamp > 0 || token.owner != from)
revert NotAllowed();
if (msg.sender != token.owner) {
if (
!operatorApprovals[token.owner][msg.sender] &&
tokenApprovals[id] != msg.sender
) revert NotAllowed();
}
if (tokenApprovals[id] != address(0)) {
delete tokenApprovals[id];
emit Approval(from, address(0), id);
}
emit Transfer(token.owner, to, id);
_bakeNextToken(token, id);
token.owner = to;
wallets[from].balance--;
wallets[to].balance++;
tokens[id] = token;
}
function _bakeNextToken(Token memory current, uint256 id) internal {
uint256 nextId;
if (current.linkedNext != 0) {
nextId = current.linkedNext;
} else if (id > 3333) {
nextId = id + 1;
if (nextId > 3333 + counters.batched) return;
} else {
return;
}
Token memory temp = tokens[nextId];
if (temp.owner != address(0)) return;
tokens[nextId] = current;
tokens[nextId].linkedNext = temp.linkedNext;
tokens[nextId].linkedPrev = temp.linkedPrev;
tokens[nextId].bit = temp.bit;
}
function approve(address to, uint256 id) public virtual {
tokenApprovals[id] = to;
emit Approval(msg.sender, to, id);
}
function setApprovalForAll(address operator, bool approved) public virtual {
operatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function getApproved(
uint256 id
) external view virtual returns (address operator) {
return tokenApprovals[id];
}
function isApprovedForAll(
address owner,
address operator
) external view virtual returns (bool) {
return operatorApprovals[owner][operator];
}
function supportsInterface(
bytes4 interfaceId
) public view virtual override returns (bool) {
return
interfaceId == 0x01ffc9a7 ||
interfaceId == 0x80ac58cd ||
interfaceId == 0x5b5e139f ||
interfaceId == 0x4e2312e0 ||
interfaceId == 0x2a55205a;
}
function _checkOnERC721Received(
address from,
address to,
uint256 id,
bytes memory data
) private returns (bool) {
try
IERC721Receiver(to).onERC721Received(msg.sender, from, id, 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))
}
}
}
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) external pure returns (bytes4) {
return
bytes4(
keccak256(
"onERC1155Received(address,address,uint256,uint256,bytes)"
)
);
}
}
文件 9 的 14:KillaCubsRestrictor.sol
pragma solidity ^0.8.19;
import "./KillaCubsStaking.sol";
import "operator-filter-registry/src/DefaultOperatorFilterer.sol";
contract KillaCubsRestrictor is KillaCubsStaking, DefaultOperatorFilterer {
constructor(
address bitsAddress,
address gearAddress,
address superOwner
) KillaCubsStaking(bitsAddress, gearAddress, superOwner) {}
bool public restricted = true;
function setApprovalForAll(
address operator,
bool approved
) public override {
if (restricted) {
setApprovalForAllRestricted(operator, approved);
} else {
super.setApprovalForAll(operator, approved);
}
}
function approve(address operator, uint256 tokenId) public override {
if (restricted) {
approveRestricted(operator, tokenId);
} else {
super.approve(operator, tokenId);
}
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public override {
if (restricted) {
transferFromRestricted(from, to, tokenId);
} else {
super.transferFrom(from, to, tokenId);
}
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public override {
if (restricted) {
safeTransferFromRestricted(from, to, tokenId);
} else {
super.safeTransferFrom(from, to, tokenId);
}
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public override {
if (restricted) {
safeTransferFromRestricted(from, to, tokenId);
} else {
super.safeTransferFrom(from, to, tokenId, data);
}
}
function setApprovalForAllRestricted(
address operator,
bool approved
) public onlyAllowedOperatorApproval(operator) {
super.setApprovalForAll(operator, approved);
}
function approveRestricted(
address operator,
uint256 tokenId
) public onlyAllowedOperatorApproval(operator) {
super.approve(operator, tokenId);
}
function transferFromRestricted(
address from,
address to,
uint256 tokenId
) public onlyAllowedOperator(from) {
super.transferFrom(from, to, tokenId);
}
function safeTransferFromRestricted(
address from,
address to,
uint256 tokenId
) public onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, tokenId);
}
function safeTransferFromRestricted(
address from,
address to,
uint256 tokenId,
bytes memory data
) public onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, tokenId, data);
}
}
文件 10 的 14:KillaCubsStaking.sol
pragma solidity ^0.8.19;
import "./KillaCubsERC721.sol";
import "../SuperOwnable.sol";
interface IKILLABITS {
function detachUpgrade(uint256 token) external;
function tokenUpgrade(uint256 token) external view returns (uint64);
function transferFrom(address from, address to, uint256 tokenId) external;
}
interface IKILLAGEAR {
function detokenize(
address addr,
uint256[] calldata types,
uint256[] calldata amounts
) external;
}
abstract contract KillaCubsStaking is KillaCubsERC721, SuperOwnable {
IKILLABITS public immutable bitsContract;
IKILLAGEAR public immutable gearContract;
event BitsAdded(uint256[] indexed tokens, uint16[] indexed bits);
event BitRemoved(uint256 indexed token, uint16 indexed bit);
event FastForwarded(uint256[] indexed tokens, uint256 indexed numberOfDays);
mapping(uint256 => bool) public bitsUsed;
uint256 public activeGeneration = 1;
uint256 public initialIncubationLength = 8;
uint256 public remixIncubationLength = 4;
mapping(uint256 => uint256) public laterGenerations;
constructor(
address bitsAddress,
address gearAddress,
address superOwner
) KillaCubsERC721() SuperOwnable(superOwner) {
bitsContract = IKILLABITS(bitsAddress);
gearContract = IKILLAGEAR(gearAddress);
}
function stake(uint256[] calldata tokenIds) external {
if (tokenIds.length == 0) return;
Token memory token;
bool skip;
for (uint256 i = 0; i < tokenIds.length; i++) {
uint256 tokenId = tokenIds[i];
if (!skip) {
token = resolveToken(tokenId);
if (token.owner != msg.sender) revert NotAllowed();
if (token.stakeTimestamp > 0) revert NotAllowed();
tokens[tokenId] = token;
tokens[tokenId].stakeTimestamp = uint32(block.timestamp);
}
emit Transfer(msg.sender, address(this), tokenId);
skip = _lookAhead(tokenIds, i, token, true);
}
wallets[msg.sender].stakes += uint16(tokenIds.length);
wallets[msg.sender].balance -= uint16(tokenIds.length);
counters.stakes += uint16(tokenIds.length);
incubator.add(msg.sender, tokenIds);
}
function unstake(uint256[] calldata tokenIds, bool finalized) external {
if (tokenIds.length == 0) return;
Token memory token;
bool skip;
bool setLaterGeneration;
for (uint256 i = 0; i < tokenIds.length; i++) {
uint256 tokenId = tokenIds[i];
if (tokens[tokenId].bit > 0) {
bitsContract.transferFrom(
address(this),
msg.sender,
tokens[tokenId].bit
);
if (finalized) bitsUsed[tokens[tokenId].bit] = true;
emit BitRemoved(tokenId, tokens[tokenId].bit);
tokens[tokenId].bit = 0;
}
if (!skip) {
token = resolveToken(tokenId);
setLaterGeneration = false;
if (token.owner != msg.sender) revert NotAllowed();
if (token.stakeTimestamp == 0) revert NotAllowed();
uint256 phase = _getIncubationPhase(token);
tokens[tokenId] = token;
tokens[tokenId].stakeTimestamp = 0;
uint256 max = token.generation == 0
? initialIncubationLength
: remixIncubationLength;
if (phase >= max) {
if (!finalized) revert NotAllowed();
tokens[tokenId].incubationPhase = 0;
if (activeGeneration > 255) {
tokens[tokenId].generation = 255;
setLaterGeneration = true;
} else {
tokens[tokenId].generation = uint8(activeGeneration);
}
} else {
if (finalized) revert NotAllowed();
tokens[tokenId].incubationPhase = uint8(phase);
}
}
if (setLaterGeneration) {
laterGenerations[tokenId] = activeGeneration;
}
emit Transfer(address(this), msg.sender, tokenId);
skip = _lookAhead(tokenIds, i, token, true);
}
wallets[msg.sender].stakes -= uint16(tokenIds.length);
wallets[msg.sender].balance += uint16(tokenIds.length);
counters.stakes -= uint16(tokenIds.length);
incubator.remove(msg.sender, tokenIds);
}
function addBits(
uint256[] calldata tokenIds,
uint16[] calldata bits
) external {
if (tokenIds.length == 0) return;
Token memory token;
bool skip;
bool modified;
for (uint256 i = 0; i < tokenIds.length; i++) {
uint256 tokenId = tokenIds[i];
if (tokens[tokenId].bit > 0) revert NotAllowed();
if (bitsUsed[bits[i]]) revert NotAllowed();
tokens[tokenId].bit = bits[i];
bitsContract.transferFrom(msg.sender, address(this), bits[i]);
if (!skip) {
modified = false;
token = resolveToken(tokenId);
if (token.generation > 0) revert NotAllowed();
if (token.owner != msg.sender) revert NotAllowed();
if (token.stakeTimestamp == 0) revert NotAllowed();
uint256 phase = _getIncubationPhase(token);
if (phase >= initialIncubationLength) revert NotAllowed();
if (phase > 1) {
tokens[tokenId] = token;
tokens[tokenId].stakeTimestamp = 0;
tokens[tokenId].incubationPhase = 0;
modified = true;
}
}
skip = _lookAhead(tokenIds, i, token, modified);
}
emit BitsAdded(tokenIds, bits);
}
function removeBits(uint256[] calldata tokenIds) external {
uint16 n = uint16(tokenIds.length);
for (uint256 i = 0; i < n; i++) {
uint256 tokenId = tokenIds[i];
if (rightfulOwnerOf(tokenId) != msg.sender) revert NotAllowed();
bitsContract.transferFrom(
address(this),
msg.sender,
tokens[tokenId].bit
);
emit BitRemoved(tokenId, tokens[tokenId].bit);
tokens[tokenId].bit = 0;
}
}
function extractGear(uint256[] calldata cubs) external {
if (cubs.length == 0) revert NotAllowed();
uint256[] memory weapons = new uint256[](1);
uint256[] memory amounts = new uint256[](1);
amounts[0] = 1;
for (uint256 i = 0; i < cubs.length; i++) {
uint256 id = cubs[i];
Token memory token = resolveToken(id);
if (token.owner != msg.sender) revert NotAllowed();
if (token.bit == 0) revert NotAllowed();
uint256 phase = _getIncubationPhase(token);
if (phase != 8) revert NotAllowed();
uint256 weapon = bitsContract.tokenUpgrade(token.bit);
bitsContract.detachUpgrade(token.bit);
weapons[0] = weapon;
gearContract.detokenize(address(this), weapons, amounts);
}
}
function fastForward(
address owner,
uint256[] calldata tokenIds,
uint256 numberOfDays
) external onlyAuthority {
if (tokenIds.length == 0) return;
if (numberOfDays == 0) return;
Token memory token;
bool skip;
bool modified;
for (uint256 i = 0; i < tokenIds.length; i++) {
uint256 tokenId = tokenIds[i];
if (!skip) {
token = resolveToken(tokenId);
if (token.owner != owner) revert NotAllowed();
if (token.stakeTimestamp == 0) revert NotAllowed();
uint256 phase = _getIncubationPhase(token);
uint256 max = token.generation == 0
? initialIncubationLength
: remixIncubationLength;
if (phase >= max) revert NotAllowed();
tokens[tokenId] = token;
tokens[tokenId].stakeTimestamp -= uint32(
numberOfDays * 24 * 3600
);
modified = true;
}
skip = _lookAhead(tokenIds, i, token, modified);
}
emit FastForwarded(tokenIds, numberOfDays);
}
function _lookAhead(
uint256[] calldata tokenIds,
uint256 index,
Token memory current,
bool modified
) internal returns (bool sequential) {
uint256 id = tokenIds[index];
uint256 nextId;
if (current.linkedNext != 0) {
nextId = current.linkedNext;
} else if (id > 3333 && id < 3333 + counters.batched) {
nextId = id + 1;
} else {
return false;
}
if (tokens[nextId].owner != address(0)) return false;
if (index + 1 < tokenIds.length && tokenIds[index + 1] == nextId)
return true;
if (modified) {
Token memory temp = tokens[nextId];
tokens[nextId] = current;
tokens[nextId].bit = temp.bit;
tokens[nextId].linkedNext = temp.linkedNext;
tokens[nextId].linkedPrev = temp.linkedPrev;
}
return false;
}
function _getIncubationPhase(
Token memory token
) internal view returns (uint256) {
uint256 phase = token.incubationPhase;
if (token.stakeTimestamp != 0) {
phase += (block.timestamp - token.stakeTimestamp) / 1 weeks;
}
uint256 max = token.generation == 0
? initialIncubationLength
: remixIncubationLength;
if (phase > max) return max;
return phase;
}
function getIncubationPhase(uint256 id) public view returns (uint256) {
Token memory token = resolveToken(id);
return _getIncubationPhase(token);
}
function getGeneration(uint256 id) public view returns (uint256) {
if (laterGenerations[id] != 0) return laterGenerations[id];
Token memory token = resolveToken(id);
return token.generation;
}
}
文件 11 的 14:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1);
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(
uint256 x,
uint256 y,
uint256 denominator,
Rounding rounding
) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10**64) {
value /= 10**64;
result += 64;
}
if (value >= 10**32) {
value /= 10**32;
result += 32;
}
if (value >= 10**16) {
value /= 10**16;
result += 16;
}
if (value >= 10**8) {
value /= 10**8;
result += 8;
}
if (value >= 10**4) {
value /= 10**4;
result += 4;
}
if (value >= 10**2) {
value /= 10**2;
result += 2;
}
if (value >= 10**1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}
文件 12 的 14:OperatorFilterer.sol
pragma solidity ^0.8.13;
import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol";
abstract contract OperatorFilterer {
error OperatorNotAllowed(address operator);
IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);
constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
if (subscribe) {
OPERATOR_FILTER_REGISTRY.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
} else {
if (subscriptionOrRegistrantToCopy != address(0)) {
OPERATOR_FILTER_REGISTRY.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
} else {
OPERATOR_FILTER_REGISTRY.register(address(this));
}
}
}
}
modifier onlyAllowedOperator(address from) virtual {
if (from != msg.sender) {
_checkFilterOperator(msg.sender);
}
_;
}
modifier onlyAllowedOperatorApproval(address operator) virtual {
_checkFilterOperator(operator);
_;
}
function _checkFilterOperator(address operator) internal view virtual {
if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
revert OperatorNotAllowed(operator);
}
}
}
}
文件 13 的 14:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
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] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
文件 14 的 14:SuperOwnable.sol
pragma solidity ^0.8.19;
abstract contract SuperOwnable {
address public owner;
address public superOwner;
mapping(address => bool) authorities;
error Denied();
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor(address superOwner_) {
_transferOwnership(msg.sender);
superOwner = superOwner_;
}
modifier onlyOwner() {
if (msg.sender != owner && msg.sender != superOwner) revert Denied();
_;
}
modifier onlySuperOwner() {
if (msg.sender != superOwner) revert Denied();
_;
}
modifier onlyAuthority() {
if (!authorities[msg.sender] && msg.sender != owner) revert Denied();
_;
}
function transferOwnership(address addr) public virtual onlyOwner {
_transferOwnership(addr);
}
function _transferOwnership(address addr) internal virtual {
address oldOwner = owner;
owner = addr;
emit OwnershipTransferred(oldOwner, addr);
}
function setSuperOwner(address addr) public onlySuperOwner {
if (addr == address(0)) revert Denied();
superOwner = addr;
}
function toggleAuthority(address addr, bool enabled) public onlyOwner {
authorities[addr] = enabled;
}
}
{
"compilationTarget": {
"contracts/KillaCubs.sol": "KillaCubs"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"bitsAddress","type":"address"},{"internalType":"address","name":"gearAddress","type":"address"},{"internalType":"address","name":"superOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Denied","type":"error"},{"inputs":[],"name":"NonExistentToken","type":"error"},{"inputs":[],"name":"NotAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"Overflow","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","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":"uint256","name":"token","type":"uint256"},{"indexed":true,"internalType":"uint16","name":"bit","type":"uint16"}],"name":"BitRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256[]","name":"tokens","type":"uint256[]"},{"indexed":true,"internalType":"uint16[]","name":"bits","type":"uint16[]"}],"name":"BitsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256[]","name":"tokens","type":"uint256[]"},{"indexed":true,"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"FastForwarded","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":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activeGeneration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint16[]","name":"bits","type":"uint16[]"}],"name":"addBits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approveRestricted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURIFinalized","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bitsContract","outputs":[{"internalType":"contract IKILLABITS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"bitsUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"royaltyReceiver","type":"address"},{"internalType":"uint96","name":"royaltyAmount","type":"uint96"}],"name":"configureRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"initialLength","type":"uint256"},{"internalType":"uint256","name":"remixLength","type":"uint256"}],"name":"configureStakingWindows","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"counters","outputs":[{"internalType":"uint16","name":"linked","type":"uint16"},{"internalType":"uint16","name":"batched","type":"uint16"},{"internalType":"uint16","name":"redeems","type":"uint16"},{"internalType":"uint16","name":"stakes","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"cubs","type":"uint256[]"}],"name":"extractGear","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"fastForward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"gen","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"finalizeGeneration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalizedGeneration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gearContract","outputs":[{"internalType":"contract IKILLAGEAR","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getGeneration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getIncubationPhase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint16","name":"linkedNext","type":"uint16"},{"internalType":"uint16","name":"linkedPrev","type":"uint16"},{"internalType":"uint32","name":"stakeTimestamp","type":"uint32"},{"internalType":"uint8","name":"generation","type":"uint8"},{"internalType":"uint8","name":"incubationPhase","type":"uint8"},{"internalType":"uint16","name":"bit","type":"uint16"}],"internalType":"struct Token","name":"token","type":"tuple"}],"name":"getTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incubator","outputs":[{"internalType":"contract IIncubator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialIncubationLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"laterGenerations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint16","name":"n","type":"uint16"},{"internalType":"bool","name":"staked","type":"bool"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"bool","name":"staked","type":"bool"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint16","name":"n","type":"uint16"},{"internalType":"bool","name":"staked","type":"bool"}],"name":"mintRedeemed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","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":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"remixIncubationLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"removeBits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"resolveToken","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint16","name":"linkedNext","type":"uint16"},{"internalType":"uint16","name":"linkedPrev","type":"uint16"},{"internalType":"uint32","name":"stakeTimestamp","type":"uint32"},{"internalType":"uint8","name":"generation","type":"uint8"},{"internalType":"uint8","name":"incubationPhase","type":"uint8"},{"internalType":"uint16","name":"bit","type":"uint16"}],"internalType":"struct Token","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"resolveTokens","outputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint16","name":"linkedNext","type":"uint16"},{"internalType":"uint16","name":"linkedPrev","type":"uint16"},{"internalType":"uint32","name":"stakeTimestamp","type":"uint32"},{"internalType":"uint8","name":"generation","type":"uint8"},{"internalType":"uint8","name":"incubationPhase","type":"uint8"},{"internalType":"uint16","name":"bit","type":"uint16"}],"internalType":"struct Token[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"restricted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"rightfulOwnerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFromRestricted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFromRestricted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAllRestricted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setIncubator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setSuperOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setURIManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startNexGeneration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"superOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"address","name":"addr","type":"address"},{"internalType":"bool","name":"enabled","type":"bool"}],"name":"toggleAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"restricted_","type":"bool"}],"name":"toggleRestricted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokens","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint16","name":"linkedNext","type":"uint16"},{"internalType":"uint16","name":"linkedPrev","type":"uint16"},{"internalType":"uint32","name":"stakeTimestamp","type":"uint32"},{"internalType":"uint8","name":"generation","type":"uint8"},{"internalType":"uint8","name":"incubationPhase","type":"uint8"},{"internalType":"uint16","name":"bit","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","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":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFromRestricted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"bool","name":"finalized","type":"bool"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriManager","outputs":[{"internalType":"contract IURIManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"main","type":"address"},{"internalType":"uint256","name":"n","type":"uint256"},{"internalType":"bool","name":"holders","type":"bool"},{"internalType":"uint256","name":"allowance","type":"uint256"}],"name":"useAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wallets","outputs":[{"internalType":"uint16","name":"balance","type":"uint16"},{"internalType":"uint16","name":"stakes","type":"uint16"},{"internalType":"uint16","name":"linkedMints","type":"uint16"},{"internalType":"uint16","name":"batchedMints","type":"uint16"},{"internalType":"uint16","name":"allowlistMints","type":"uint16"},{"internalType":"uint16","name":"privateMints","type":"uint16"},{"internalType":"uint16","name":"holderMints","type":"uint16"},{"internalType":"uint16","name":"redeems","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]