编译器
0.8.20+commit.a1b79de6
文件 1 的 17:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 2 的 17:DoubleEndedQueue.sol
pragma solidity ^0.8.20;
library DoubleEndedQueue {
error QueueEmpty();
error QueueFull();
error QueueOutOfBounds();
struct Uint256Deque {
uint128 _begin;
uint128 _end;
mapping(uint128 index => uint256) _data;
}
function pushBack(Uint256Deque storage deque, uint256 value) internal {
unchecked {
uint128 backIndex = deque._end;
if (backIndex + 1 == deque._begin) revert QueueFull();
deque._data[backIndex] = value;
deque._end = backIndex + 1;
}
}
function popBack(
Uint256Deque storage deque
) internal returns (uint256 value) {
unchecked {
uint128 backIndex = deque._end;
if (backIndex == deque._begin) revert QueueEmpty();
--backIndex;
value = deque._data[backIndex];
delete deque._data[backIndex];
deque._end = backIndex;
}
}
function pushFront(Uint256Deque storage deque, uint256 value) internal {
unchecked {
uint128 frontIndex = deque._begin - 1;
if (frontIndex == deque._end) revert QueueFull();
deque._data[frontIndex] = value;
deque._begin = frontIndex;
}
}
function popFront(
Uint256Deque storage deque
) internal returns (uint256 value) {
unchecked {
uint128 frontIndex = deque._begin;
if (frontIndex == deque._end) revert QueueEmpty();
value = deque._data[frontIndex];
delete deque._data[frontIndex];
deque._begin = frontIndex + 1;
}
}
function front(
Uint256Deque storage deque
) internal view returns (uint256 value) {
if (empty(deque)) revert QueueEmpty();
return deque._data[deque._begin];
}
function back(
Uint256Deque storage deque
) internal view returns (uint256 value) {
if (empty(deque)) revert QueueEmpty();
unchecked {
return deque._data[deque._end - 1];
}
}
function at(
Uint256Deque storage deque,
uint256 index
) internal view returns (uint256 value) {
if (index >= length(deque)) revert QueueOutOfBounds();
unchecked {
return deque._data[deque._begin + uint128(index)];
}
}
function clear(Uint256Deque storage deque) internal {
deque._begin = 0;
deque._end = 0;
}
function length(Uint256Deque storage deque) internal view returns (uint256) {
unchecked {
return uint256(deque._end - deque._begin);
}
}
function empty(Uint256Deque storage deque) internal view returns (bool) {
return deque._end == deque._begin;
}
}
文件 3 的 17:ERC20Events.sol
pragma solidity ^0.8.20;
library ERC20Events {
event Approval(address indexed owner, address indexed spender, uint256 value);
event Transfer(address indexed from, address indexed to, uint256 amount);
}
文件 4 的 17:ERC404.sol
pragma solidity ^0.8.20;
import {IERC721Receiver} from "@openzeppelin/contracts/interfaces/IERC721Receiver.sol";
import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol";
import {IERC404} from "./interfaces/IERC404.sol";
import {DoubleEndedQueue} from "erc404/lib/DoubleEndedQueue.sol";
import {ERC721Events} from "erc404/lib/ERC721Events.sol";
import {ERC20Events} from "erc404/lib/ERC20Events.sol";
import "./types/LinkedListInventory.sol";
abstract contract ERC404 is IERC404 {
using DoubleEndedQueue for DoubleEndedQueue.Uint256Deque;
using LinkedListInventory for LinkedListStorage;
DoubleEndedQueue.Uint256Deque internal _storedERC721Ids;
string public name;
string public symbol;
uint8 public immutable decimals;
uint256 public immutable units;
uint256 public totalSupply;
uint256 public minted;
uint256 internal immutable _INITIAL_CHAIN_ID;
bytes32 internal immutable _INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
mapping(uint256 => uint256) internal _ownedData;
LinkedListStorage internal _owned;
mapping(address => bool) internal _erc721TransferExempt;
mapping(address => uint256) public nonces;
uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
uint256 private constant _BITMASK_OWNED_INDEX = ((1 << 96) - 1) << 160;
uint256 public constant ID_ENCODING_PREFIX = 1 << 255;
constructor(string memory name_, string memory symbol_, uint8 decimals_) {
name = name_;
symbol = symbol_;
if (decimals_ < 18) {
revert DecimalsTooLow();
}
decimals = decimals_;
units = 10 ** decimals;
_INITIAL_CHAIN_ID = block.chainid;
_INITIAL_DOMAIN_SEPARATOR = _computeDomainSeparator();
}
function ownerOf(
uint256 id_
) public view virtual returns (address erc721Owner) {
erc721Owner = _getOwnerOf(id_);
if (!_isValidTokenId(id_)) {
revert InvalidTokenId();
}
if (erc721Owner == address(0)) {
revert NotFound();
}
}
function owned(
address owner_
) public view virtual returns (uint16[] memory) {
return _owned.tidsOrdered(owner_);
}
function erc721BalanceOf(
address owner_
) public view virtual returns (uint256) {
return _owned.length(owner_);
}
function erc20BalanceOf(
address owner_
) public view virtual returns (uint256) {
return balanceOf[owner_];
}
function erc20TotalSupply() public view virtual returns (uint256) {
return totalSupply;
}
function erc721TotalSupply() public view virtual returns (uint256) {
return minted;
}
function getERC721QueueLength() public view virtual returns (uint256) {
return _storedERC721Ids.length();
}
function getERC721TokensInQueue(
uint256 start_,
uint256 count_
) public view virtual returns (uint256[] memory) {
uint256[] memory tokensInQueue = new uint256[](count_);
for (uint256 i = start_; i < start_ + count_; ) {
tokensInQueue[i - start_] = _storedERC721Ids.at(i);
unchecked {
++i;
}
}
return tokensInQueue;
}
function tokenURI(uint256 id_) public view virtual returns (string memory);
function reorderOwned(uint16[] calldata newList, uint16 newHead) public {
_owned.commitLinkedList(newList, newHead);
}
function approve(
address spender_,
uint256 valueOrId_
) public virtual returns (bool) {
if (_isValidTokenId(valueOrId_)) {
erc721Approve(spender_, valueOrId_);
} else {
return erc20Approve(spender_, valueOrId_);
}
return true;
}
function erc721Approve(address spender_, uint256 id_) public virtual {
address erc721Owner = _getOwnerOf(id_);
if (
msg.sender != erc721Owner && !isApprovedForAll[erc721Owner][msg.sender]
) {
revert Unauthorized();
}
getApproved[id_] = spender_;
emit ERC721Events.Approval(erc721Owner, spender_, id_);
}
function erc20Approve(
address spender_,
uint256 value_
) public virtual returns (bool) {
if (spender_ == address(0)) {
revert InvalidSpender();
}
allowance[msg.sender][spender_] = value_;
emit ERC20Events.Approval(msg.sender, spender_, value_);
return true;
}
function setApprovalForAll(address operator_, bool approved_) public virtual {
if (operator_ == address(0)) {
revert InvalidOperator();
}
isApprovedForAll[msg.sender][operator_] = approved_;
emit ERC721Events.ApprovalForAll(msg.sender, operator_, approved_);
}
function transferFrom(
address from_,
address to_,
uint256 valueOrId_
) public virtual returns (bool) {
if (_isValidTokenId(valueOrId_)) {
erc721TransferFrom(from_, to_, valueOrId_);
} else {
return erc20TransferFrom(from_, to_, valueOrId_);
}
return true;
}
function erc721TransferFrom(
address from_,
address to_,
uint256 id_
) public virtual {
if (from_ == address(0)) {
revert InvalidSender();
}
if (to_ == address(0)) {
revert InvalidRecipient();
}
if (from_ != _getOwnerOf(id_)) {
revert Unauthorized();
}
if (
msg.sender != from_ &&
!isApprovedForAll[from_][msg.sender] &&
msg.sender != getApproved[id_]
) {
revert Unauthorized();
}
if (erc721TransferExempt(to_)) {
revert RecipientIsERC721TransferExempt();
}
_transferERC20(from_, to_, units);
_transferERC721(from_, to_, id_);
}
function erc20TransferFrom(
address from_,
address to_,
uint256 value_
) public virtual returns (bool) {
if (from_ == address(0)) {
revert InvalidSender();
}
if (to_ == address(0)) {
revert InvalidRecipient();
}
uint256 allowed = allowance[from_][msg.sender];
if (allowed != type(uint256).max) {
allowance[from_][msg.sender] = allowed - value_;
}
return _transferERC20WithERC721(from_, to_, value_);
}
function transfer(address to_, uint256 value_) public virtual returns (bool) {
if (to_ == address(0)) {
revert InvalidRecipient();
}
return _transferERC20WithERC721(msg.sender, to_, value_);
}
function safeTransferFrom(
address from_,
address to_,
uint256 id_
) public virtual {
safeTransferFrom(from_, to_, id_, "");
}
function safeTransferFrom(
address from_,
address to_,
uint256 id_,
bytes memory data_
) public virtual {
if (!_isValidTokenId(id_)) {
revert InvalidTokenId();
}
transferFrom(from_, to_, id_);
if (
to_.code.length != 0 &&
IERC721Receiver(to_).onERC721Received(msg.sender, from_, id_, data_) !=
IERC721Receiver.onERC721Received.selector
) {
revert UnsafeRecipient();
}
}
function permit(
address owner_,
address spender_,
uint256 value_,
uint256 deadline_,
uint8 v_,
bytes32 r_,
bytes32 s_
) public virtual {
if (deadline_ < block.timestamp) {
revert PermitDeadlineExpired();
}
if (_isValidTokenId(value_)) {
revert InvalidApproval();
}
if (spender_ == address(0)) {
revert InvalidSpender();
}
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner_,
spender_,
value_,
nonces[owner_]++,
deadline_
)
)
)
),
v_,
r_,
s_
);
if (recoveredAddress == address(0) || recoveredAddress != owner_) {
revert InvalidSigner();
}
allowance[recoveredAddress][spender_] = value_;
}
emit ERC20Events.Approval(owner_, spender_, value_);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return
block.chainid == _INITIAL_CHAIN_ID
? _INITIAL_DOMAIN_SEPARATOR
: _computeDomainSeparator();
}
function supportsInterface(
bytes4 interfaceId
) public view virtual returns (bool) {
return
interfaceId == type(IERC404).interfaceId ||
interfaceId == type(IERC165).interfaceId;
}
function setSelfERC721TransferExempt(bool state_) public virtual {
_setERC721TransferExempt(msg.sender, state_);
}
function erc721TransferExempt(
address target_
) public view virtual returns (bool) {
return target_ == address(0) || _erc721TransferExempt[target_];
}
function _isValidTokenId(uint256 id_) internal pure returns (bool) {
return id_ > ID_ENCODING_PREFIX && id_ != type(uint256).max;
}
function _computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
function _transferERC20(
address from_,
address to_,
uint256 value_
) internal virtual {
if (from_ == address(0)) {
totalSupply += value_;
} else {
balanceOf[from_] -= value_;
}
unchecked {
balanceOf[to_] += value_;
}
emit ERC20Events.Transfer(from_, to_, value_);
}
function _transferERC721(
address from_,
address to_,
uint256 id_
) internal virtual {
if (from_ != address(0)) {
delete getApproved[id_];
_owned.inventoryTransferOut(from_, uint16(id_));
}
if (to_ != address(0)) {
_setOwnerOf(id_, to_);
_owned.inventoryTransferIn(to_, uint16(id_));
} else {
delete _ownedData[id_];
}
emit ERC721Events.Transfer(from_, to_, id_);
}
function _transferERC20WithERC721(
address from_,
address to_,
uint256 value_
) internal virtual returns (bool) {
uint256 erc20BalanceOfSenderBefore = erc20BalanceOf(from_);
uint256 erc20BalanceOfReceiverBefore = erc20BalanceOf(to_);
_transferERC20(from_, to_, value_);
bool isFromERC721TransferExempt = erc721TransferExempt(from_);
bool isToERC721TransferExempt = erc721TransferExempt(to_);
if (isFromERC721TransferExempt && isToERC721TransferExempt) {
} else if (isFromERC721TransferExempt) {
uint256 tokensToRetrieveOrMint = (balanceOf[to_] / units) -
(erc20BalanceOfReceiverBefore / units);
for (uint256 i = 0; i < tokensToRetrieveOrMint; ) {
_retrieveOrMintERC721(to_);
unchecked {
++i;
}
}
} else if (isToERC721TransferExempt) {
uint256 tokensToWithdrawAndStore = (erc20BalanceOfSenderBefore / units) -
(balanceOf[from_] / units);
for (uint256 i = 0; i < tokensToWithdrawAndStore; ) {
_withdrawAndStoreERC721(from_);
unchecked {
++i;
}
}
} else {
uint256 nftsToTransfer = value_ / units;
for (uint256 i = 0; i < nftsToTransfer; ) {
uint256 tokenId = uint256(_owned.getHead(from_));
_transferERC721(from_, to_, tokenId);
unchecked {
++i;
}
}
if (
erc20BalanceOfSenderBefore / units - erc20BalanceOf(from_) / units >
nftsToTransfer
) {
_withdrawAndStoreERC721(from_);
}
if (
erc20BalanceOf(to_) / units - erc20BalanceOfReceiverBefore / units >
nftsToTransfer
) {
_retrieveOrMintERC721(to_);
}
}
return true;
}
function _mintERC20(address to_, uint256 value_) internal virtual {
if (to_ == address(0)) {
revert InvalidRecipient();
}
if (totalSupply + value_ > ID_ENCODING_PREFIX) {
revert MintLimitReached();
}
_transferERC20WithERC721(address(0), to_, value_);
}
function _retrieveOrMintERC721(address to_) internal virtual {
if (to_ == address(0)) {
revert InvalidRecipient();
}
uint256 id;
if (!_storedERC721Ids.empty()) {
id = _storedERC721Ids.popBack();
} else {
++minted;
if (minted == type(uint256).max) {
revert MintLimitReached();
}
id = ID_ENCODING_PREFIX + minted;
}
address erc721Owner = _getOwnerOf(id);
if (erc721Owner != address(0)) {
revert AlreadyExists();
}
_transferERC721(erc721Owner, to_, id);
}
function _withdrawAndStoreERC721(address from_) internal virtual {
if (from_ == address(0)) {
revert InvalidSender();
}
uint16 id = _owned.pop(from_);
_setOwnerOf(id, address(0));
_storedERC721Ids.pushFront(id);
emit ERC721Events.Transfer(from_, address(0), id);
}
function _setERC721TransferExempt(
address target_,
bool state_
) internal virtual {
if (target_ == address(0)) {
revert InvalidExemption();
}
if (state_) {
_clearERC721Balance(target_);
} else {
_reinstateERC721Balance(target_);
}
_erc721TransferExempt[target_] = state_;
}
function _reinstateERC721Balance(address target_) private {
uint256 expectedERC721Balance = erc20BalanceOf(target_) / units;
uint256 actualERC721Balance = erc721BalanceOf(target_);
for (uint256 i = 0; i < expectedERC721Balance - actualERC721Balance; ) {
_retrieveOrMintERC721(target_);
unchecked {
++i;
}
}
}
function _clearERC721Balance(address target_) private {
uint256 erc721Balance = erc721BalanceOf(target_);
for (uint256 i = 0; i < erc721Balance; ) {
_withdrawAndStoreERC721(target_);
unchecked {
++i;
}
}
}
function _getOwnerOf(
uint256 id_
) internal view virtual returns (address ownerOf_) {
uint256 data = _ownedData[id_];
assembly {
ownerOf_ := and(data, _BITMASK_ADDRESS)
}
}
function _setOwnerOf(uint256 id_, address owner_) internal virtual {
uint256 data = _ownedData[id_];
assembly {
data := add(
and(data, _BITMASK_OWNED_INDEX),
and(owner_, _BITMASK_ADDRESS)
)
}
_ownedData[id_] = data;
}
}
文件 5 的 17:ERC404Viewable.sol
pragma solidity ^0.8.0;
import "../ERC404.sol";
abstract contract ERC404Viewable is ERC404 {
using DoubleEndedQueue for DoubleEndedQueue.Uint256Deque;
using LinkedListInventory for LinkedListStorage;
function dequeueFront() external view returns (uint256) {
return _storedERC721Ids.front();
}
function dequeueBack() external view returns (uint256) {
return _storedERC721Ids.back();
}
function dequeueAt(uint256 index) external view returns (uint256) {
return _storedERC721Ids.at(index);
}
function dequeueLength() external view returns (uint256) {
return _storedERC721Ids.length();
}
function dequeueEmpty() external view returns (bool) {
return _storedERC721Ids.empty();
}
function getOwnedLinkedList(address account) external view returns(
Reference[] memory list,
uint16 head,
uint16[] memory tokens
) {
return _owned.getLinkedList(account);
}
}
文件 6 的 17:ERC721Events.sol
pragma solidity ^0.8.20;
library ERC721Events {
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
event Approval(
address indexed owner,
address indexed spender,
uint256 indexed id
);
event Transfer(address indexed from, address indexed to, uint256 indexed id);
}
文件 7 的 17:IERC165.sol
pragma solidity ^0.8.20;
import {IERC165} from "../utils/introspection/IERC165.sol";
文件 8 的 17:IERC404.sol
pragma solidity ^0.8.20;
import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol";
interface IERC404 is IERC165 {
error NotFound();
error InvalidTokenId();
error AlreadyExists();
error InvalidRecipient();
error InvalidSender();
error InvalidSpender();
error InvalidOperator();
error UnsafeRecipient();
error RecipientIsERC721TransferExempt();
error Unauthorized();
error InsufficientAllowance();
error DecimalsTooLow();
error PermitDeadlineExpired();
error InvalidSigner();
error InvalidApproval();
error OwnedIndexOverflow();
error MintLimitReached();
error InvalidExemption();
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function erc20TotalSupply() external view returns (uint256);
function erc721TotalSupply() external view returns (uint256);
function balanceOf(address owner_) external view returns (uint256);
function erc721BalanceOf(address owner_) external view returns (uint256);
function erc20BalanceOf(address owner_) external view returns (uint256);
function erc721TransferExempt(address account_) external view returns (bool);
function isApprovedForAll(
address owner_,
address operator_
) external view returns (bool);
function allowance(
address owner_,
address spender_
) external view returns (uint256);
function owned(address owner_) external view returns (uint16[] memory);
function ownerOf(uint256 id_) external view returns (address erc721Owner);
function tokenURI(uint256 id_) external view returns (string memory);
function approve(
address spender_,
uint256 valueOrId_
) external returns (bool);
function erc20Approve(
address spender_,
uint256 value_
) external returns (bool);
function erc721Approve(address spender_, uint256 id_) external;
function setApprovalForAll(address operator_, bool approved_) external;
function transferFrom(
address from_,
address to_,
uint256 valueOrId_
) external returns (bool);
function erc20TransferFrom(
address from_,
address to_,
uint256 value_
) external returns (bool);
function erc721TransferFrom(address from_, address to_, uint256 id_) external;
function transfer(address to_, uint256 amount_) external returns (bool);
function getERC721QueueLength() external view returns (uint256);
function getERC721TokensInQueue(
uint256 start_,
uint256 count_
) external view returns (uint256[] memory);
function setSelfERC721TransferExempt(bool state_) external;
function safeTransferFrom(address from_, address to_, uint256 id_) external;
function safeTransferFrom(
address from_,
address to_,
uint256 id_,
bytes calldata data_
) external;
function DOMAIN_SEPARATOR() external view returns (bytes32);
function permit(
address owner_,
address spender_,
uint256 value_,
uint256 deadline_,
uint8 v_,
bytes32 r_,
bytes32 s_
) external;
}
文件 9 的 17:IERC721Receiver.sol
pragma solidity ^0.8.20;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 10 的 17:IMinter.sol
pragma solidity ^0.8.0;
interface IMinter {
function decimals() external view returns (uint8);
function supply() external view returns (uint256);
function units() external view returns (uint256);
function setToken(address token_) external;
function mint(uint256 amount) external payable;
}
文件 11 的 17:LinkedListInventory.sol
pragma solidity ^0.8.0;
struct Reference {
uint16 prev;
uint16 next;
}
struct LinkedListU16 {
mapping( uint16 => uint16 ) positionOfToken;
uint16[] tokens;
Reference[] list;
uint32 tailAndHeadIdx;
}
struct LinkedListStorage {
mapping(address => LinkedListU16) self;
}
library LinkedListInventory {
using BitFieldU16 for bytes32;
using BitFieldU16 for uint16;
using BitFieldU16 for uint256;
using LinkedListInventory for LinkedListStorage;
error ValidateLinkedListError_ItemAlreadyVisited(uint16 tidIndex);
error ValidateLinkedListError_PrematureTermination();
error ValidateLinkedListError_NextTidIndexExceedsLength(uint16 tidIndex);
function tids(LinkedListStorage storage s, address account) internal view returns (uint16[] memory) {
return s.self[account].tokens;
}
function tidsOrdered(LinkedListStorage storage s, address account) internal view returns (uint16[] memory) {
uint16 currIndex = s.getHeadIndex(account);
uint256 len = s.length(account);
uint16[] memory tids = new uint16[](len);
for(uint256 i = 0; i < len; i++) {
tids[len-(i+1)] = s.self[account].tokens[currIndex];
currIndex = s.getReference(account, currIndex).next;
}
return tids;
}
function exists(LinkedListStorage storage s, address account, uint16 tid) internal view returns (bool) {
return s.positionOfToken(account, tid) > 0;
}
function length(LinkedListStorage storage s, address account) internal view returns (uint256) {
return s.self[account].tokens.length;
}
function getHeadIndex(LinkedListStorage storage s, address account) internal view returns (uint16 head) {
( ,head) = s.getTailAndHeadIdx(account);
}
function getTailIndex(LinkedListStorage storage s, address account) internal view returns (uint16 tail) {
(tail,) = s.getTailAndHeadIdx(account);
}
function getTailAndHeadIdx(LinkedListStorage storage s, address account) internal view returns (uint16 tail, uint16 head) {
uint32 tailAndHead = s.self[account].tailAndHeadIdx;
head = uint16(tailAndHead & 0x0000FFFF);
tail = uint16(tailAndHead >> 16);
}
function setTailAndHeadIdx(LinkedListStorage storage s, address account, uint16 tail, uint16 head) internal {
uint32 tailAndHead;
tailAndHead = uint32(tail) << 16;
tailAndHead |= head;
s.self[account].tailAndHeadIdx = tailAndHead;
}
function getHead(LinkedListStorage storage s, address account) internal view returns (uint16) {
return s.self[account].tokens[s.getHeadIndex(account)];
}
function lastTokenAndIndex(LinkedListStorage storage s, address account) internal view returns (uint16, uint16) {
uint16 lastIndex = uint16(s.self[account].tokens.length - 1);
return (s.self[account].tokens[lastIndex], lastIndex);
}
function positionOfToken(LinkedListStorage storage s, address account, uint16 token) internal view returns (uint16) {
return s.self[account].positionOfToken[token];
}
function getReference(LinkedListStorage storage s, address account, uint16 index) internal view returns (Reference memory) {
return s.self[account].list[index];
}
function getLinkedList(LinkedListStorage storage s, address account) internal view returns(
Reference[] memory list,
uint16 head,
uint16[] memory tokens
) {
(, uint16 head) = s.getTailAndHeadIdx(account);
return (s.self[account].list, head, s.self[account].tokens);
}
function inventoryTransferFrom(
LinkedListStorage storage s,
address from,
address to,
uint16 tid
) internal {
s.inventoryTransferOut(from, tid);
s.inventoryTransferIn(to, tid);
}
function inventoryPopFrom(LinkedListStorage storage s, address from, address to) internal {
uint16 tid = s.pop(from);
s.inventoryTransferIn(to, tid);
}
function inventoryPopFrom(
LinkedListStorage storage s,
address from,
address to,
uint256 num
) internal {
for (uint256 i = 0; i < num; i++) {
s.inventoryPopFrom(from, to);
}
}
function inventoryTransferIn(
LinkedListStorage storage s,
address account,
uint16 tid
) internal {
uint16 newEdgeIdx = uint16(s.self[account].tokens.length);
(uint16 tailIdx, uint16 formerHeadIdx) = s.getTailAndHeadIdx(account);
s.self[account].tokens.push(tid);
Reference memory newRef = Reference({prev: 0, next: formerHeadIdx});
if (newEdgeIdx > 0) {
newRef.next = formerHeadIdx;
s.self[account].list[formerHeadIdx].prev = newEdgeIdx;
}
s.self[account].list.push(newRef);
s.setTailAndHeadIdx(account, tailIdx, newEdgeIdx);
s.self[account].positionOfToken[tid] = newEdgeIdx + 1;
}
function inventoryTransferOut(LinkedListStorage storage s, address account, uint16 tid) internal {
uint16 hole = s.positionOfToken(account, tid) - 1;
Reference memory holeRef = s.getReference(account, hole);
if (s.self[account].list.length > 1) {
(uint16 tail, uint16 head) = s.getTailAndHeadIdx(account);
(uint16 edgeTid, uint16 edge) = s.lastTokenAndIndex(account);
if ( hole == head ) {
head = holeRef.next;
} else if ( hole == tail ) {
tail = holeRef.prev;
} else {
uint16 prev = holeRef.prev;
uint16 next = holeRef.next;
s.self[account].list[next].prev = prev;
s.self[account].list[prev].next = next;
}
if ( edge != hole ) {
Reference memory edgeRef = s.getReference(account, edge);
uint16 prev = edgeRef.prev;
uint16 next = edgeRef.next;
if ( edge == head ) {
head = hole;
s.self[account].list[next].prev = hole;
} else if ( edge == tail ) {
tail = hole;
s.self[account].list[prev].next = hole;
} else {
s.self[account].list[next].prev = hole;
s.self[account].list[prev].next = hole;
}
s.self[account].list[hole].prev = edgeRef.prev;
s.self[account].list[hole].next = edgeRef.next;
s.self[account].positionOfToken[edgeTid] = hole + 1;
s.self[account].tokens[hole] = edgeTid;
}
s.setTailAndHeadIdx(account, tail, head);
} else {
delete s.self[account].tailAndHeadIdx;
}
s.self[account].tokens.pop();
s.self[account].list.pop();
delete s.self[account].positionOfToken[tid];
}
function pop(LinkedListStorage storage s, address account) internal returns (uint16 tid) {
tid = s.getHead(account);
s.inventoryTransferOut(account, tid);
}
uint16 private constant SET_REF_TO_ZERO = 0xFFFF;
function _validateAndBuildList(uint16[] memory list, uint16 head) internal pure returns (Reference[] memory, uint32) {
uint256 blen = uint16(list.length).bitmapLength();
bytes32[] memory visitedBitmap = new bytes32[](blen);
Reference[] memory built = new Reference[](list.length);
uint32 tail_p;
uint32 head_p = head;
uint16 prev;
uint16 current = head;
for(uint256 i = 0; i < list.length - 1; i++) {
uint256 bitmapIndex = current.bitmapIndex();
bytes32 currBitfield = visitedBitmap[bitmapIndex];
if (current >= list.length)
revert ValidateLinkedListError_NextTidIndexExceedsLength(current);
if (currBitfield.contains(current))
revert ValidateLinkedListError_ItemAlreadyVisited(current);
visitedBitmap[bitmapIndex] = currBitfield.set(current);
if ( i > 0 ) {
built[current].prev = prev;
}
built[current].next = list[current];
prev = current;
current = list[current];
}
built[current].prev = prev;
tail_p = current;
return (built, (tail_p << 16 | head_p));
}
function commitLinkedList(LinkedListStorage storage s, uint16[] calldata newList, uint16 newHead) internal {
address account = msg.sender;
(uint16 tailIdx, uint16 headIdx) = s.getTailAndHeadIdx(account);
uint256 len = s.length(account);
require( len > 0, "Nothing to reorder." );
require( newList.length == len, "Wrong list size committed." );
(Reference[] memory changeList, uint32 newTailAndHead) = _validateAndBuildList(newList, newHead);
uint16 newTail = uint16(newTailAndHead >> 16);
if (newHead != headIdx || newTail != tailIdx) {
s.setTailAndHeadIdx(account, newTail, newHead);
}
for(uint256 i = 0; i < changeList.length; i++) {
s.self[account].list[i] = changeList[i];
}
}
}
library BitFieldU16 {
function set(bytes32 bitfield, uint16 item) internal pure returns (bytes32) {
uint16 index = item % 256;
return bitfield | bytes32(0x01 << index);
}
function contains(bytes32 bitField, uint16 item) internal pure returns (bool) {
uint16 index = item % 256;
return uint256(bitField >> index) & 0x01 == 1;
}
function bitmapLength(uint16 item) internal pure returns (uint256 length) {
length = bitmapIndex(item) + 1;
}
function visitBitmapAt(uint16 item) internal pure returns (uint256 index, uint16 position) {
unchecked { index = item / 256; }
position = uint16(item - (index * 256));
}
function bitmapIndex(uint16 item) internal pure returns (uint256 index) {
unchecked {
index = item / 256;
}
}
}
文件 12 的 17:Math.sol
pragma solidity ^0.8.20;
library Math {
error MathOverflowedMulDiv();
enum Rounding {
Floor,
Ceil,
Trunc,
Expand
}
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 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) {
if (b == 0) {
return a / b;
}
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0 = x * y;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
if (denominator <= prod1) {
revert MathOverflowedMulDiv();
}
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (0 - denominator);
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 (unsignedRoundsUp(rounding) && 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 + (unsignedRoundsUp(rounding) && 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 + (unsignedRoundsUp(rounding) && 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 + (unsignedRoundsUp(rounding) && 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
}
}
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
return uint8(rounding) % 2 == 1;
}
}
文件 13 的 17:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 14 的 17:PixieRealm404.sol
pragma solidity ^0.8.0;
import {
ERC404,
ERC404Viewable
} from "./extensions/index.sol";
import { IMinter } from "./periphery/IMinter.sol";
import { Ownable } from "openzeppelin-contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract PixieRealm404 is Ownable, ERC404Viewable {
constructor(
string memory name_,
string memory symbol_,
IMinter minter_,
address initialOwner_
)
Ownable(initialOwner_)
ERC404(name_, symbol_, minter_.decimals())
{
_setBaseURI("https://pixierealm.io/api/pixie404?mode=meta&tid=");
uint256 ERC20TotalSupply = minter_.supply() * minter_.units();
uint256 ERC20MinterSupply = ERC20TotalSupply * 12 / 100;
_setERC721TransferExempt(address(minter_), true);
_mintERC20(address(minter_), ERC20MinterSupply);
_setERC721TransferExempt(initialOwner_, true);
_mintERC20(initialOwner_, ERC20TotalSupply - ERC20MinterSupply);
}
function setERC721TransferExempt(address who, bool whitelist) external onlyOwner {
_setERC721TransferExempt(who, whitelist);
}
function tokenURI(uint256 id_) public view override returns (string memory) {
string memory baseURI = __baseURI;
return string.concat(baseURI, Strings.toString(id_));
}
string private __baseURI;
function _baseURI() internal view returns (string memory) {
return __baseURI;
}
function setBaseURI(string memory baseURI) public onlyOwner {
_setBaseURI(baseURI);
}
function _setBaseURI(string memory baseURI_) internal {
__baseURI = baseURI_;
}
}
文件 15 的 17:SignedMath.sol
pragma solidity ^0.8.20;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 16 的 17:Strings.sol
pragma solidity ^0.8.20;
import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";
library Strings {
bytes16 private constant HEX_DIGITS = "0123456789abcdef";
uint8 private constant ADDRESS_LENGTH = 20;
error StringsInsufficientHexLength(uint256 value, uint256 length);
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), HEX_DIGITS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toStringSigned(int256 value) internal pure returns (string memory) {
return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
}
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) {
uint256 localValue = value;
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_DIGITS[localValue & 0xf];
localValue >>= 4;
}
if (localValue != 0) {
revert StringsInsufficientHexLength(value, length);
}
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
}
}
文件 17 的 17:index.sol
pragma solidity ^0.8.0;
import { ERC404Viewable } from "./ERC404Viewable.sol";
import { ERC404 } from "../ERC404.sol";
{
"compilationTarget": {
"src/PixieRealm404.sol": "PixieRealm404"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
":ds-test/=lib/ds-test/src/",
":erc404/=lib/erc404/contracts/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
":src/=src/"
]
}
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"contract IMinter","name":"minter_","type":"address"},{"internalType":"address","name":"initialOwner_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyExists","type":"error"},{"inputs":[],"name":"DecimalsTooLow","type":"error"},{"inputs":[],"name":"InsufficientAllowance","type":"error"},{"inputs":[],"name":"InvalidApproval","type":"error"},{"inputs":[],"name":"InvalidExemption","type":"error"},{"inputs":[],"name":"InvalidOperator","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"InvalidSpender","type":"error"},{"inputs":[],"name":"InvalidTokenId","type":"error"},{"inputs":[],"name":"MintLimitReached","type":"error"},{"inputs":[],"name":"NotFound","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"OwnedIndexOverflow","type":"error"},{"inputs":[],"name":"PermitDeadlineExpired","type":"error"},{"inputs":[],"name":"QueueEmpty","type":"error"},{"inputs":[],"name":"QueueFull","type":"error"},{"inputs":[],"name":"QueueOutOfBounds","type":"error"},{"inputs":[],"name":"RecipientIsERC721TransferExempt","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"UnsafeRecipient","type":"error"},{"inputs":[{"internalType":"uint16","name":"tidIndex","type":"uint16"}],"name":"ValidateLinkedListError_ItemAlreadyVisited","type":"error"},{"inputs":[{"internalType":"uint16","name":"tidIndex","type":"uint16"}],"name":"ValidateLinkedListError_NextTidIndexExceedsLength","type":"error"},{"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":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ID_ENCODING_PREFIX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"valueOrId_","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":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"dequeueAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dequeueBack","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dequeueEmpty","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dequeueFront","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dequeueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"}],"name":"erc20Approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"erc20BalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc20TotalSupply","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":"value_","type":"uint256"}],"name":"erc20TransferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"erc721Approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"erc721BalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"erc721TotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target_","type":"address"}],"name":"erc721TransferExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"erc721TransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getERC721QueueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"start_","type":"uint256"},{"internalType":"uint256","name":"count_","type":"uint256"}],"name":"getERC721TokensInQueue","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getOwnedLinkedList","outputs":[{"components":[{"internalType":"uint16","name":"prev","type":"uint16"},{"internalType":"uint16","name":"next","type":"uint16"}],"internalType":"struct Reference[]","name":"list","type":"tuple[]"},{"internalType":"uint16","name":"head","type":"uint16"},{"internalType":"uint16[]","name":"tokens","type":"uint16[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"name":"owned","outputs":[{"internalType":"uint16[]","name":"","type":"uint16[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"erc721Owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"value_","type":"uint256"},{"internalType":"uint256","name":"deadline_","type":"uint256"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"newList","type":"uint16[]"},{"internalType":"uint16","name":"newHead","type":"uint16"}],"name":"reorderOwned","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"id_","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":"id_","type":"uint256"},{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"safeTransferFrom","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":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bool","name":"whitelist","type":"bool"}],"name":"setERC721TransferExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state_","type":"bool"}],"name":"setSelfERC721TransferExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id_","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"valueOrId_","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"units","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]