编译器
0.8.13+commit.abaa5c0e
文件 1 的 20:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) private pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 20:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 3 的 20: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;
}
}
文件 4 的 20:ERC721.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
using SafeMath for uint256;
using Address for address;
using EnumerableSet for EnumerableSet.UintSet;
using EnumerableMap for EnumerableMap.UintToAddressMap;
using Strings for uint256;
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
mapping (address => EnumerableSet.UintSet) private _holderTokens;
EnumerableMap.UintToAddressMap private _tokenOwners;
mapping (uint256 => address) private _tokenApprovals;
mapping (address => mapping (address => bool)) private _operatorApprovals;
string private _name;
string private _symbol;
mapping (uint256 => string) private _tokenURIs;
string private _baseURI;
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
constructor(string memory name_, string memory symbol_){
_name = name_;
_symbol = symbol_;
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "zero address");
return _holderTokens[owner].length();
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
return _tokenOwners.get(tokenId, "nonexistent");
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "nonexistent");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = baseURI();
if (bytes(base).length == 0) {
return _tokenURI;
}
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
return string(abi.encodePacked(base, tokenId.toString()));
}
function baseURI() public view virtual returns (string memory) {
return _baseURI;
}
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
return _holderTokens[owner].at(index);
}
function totalSupply() public view virtual override returns (uint256) {
return _tokenOwners.length();
}
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
(uint256 tokenId, ) = _tokenOwners.at(index);
return tokenId;
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "approval");
require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),
"approval"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "nonexistent");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != _msgSender(), "caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(address from, address to, uint256 tokenId) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "approved");
_transfer(from, to, tokenId);
}
function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "approved");
_safeTransfer(from, to, tokenId, _data);
}
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "implementer");
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _tokenOwners.contains(tokenId);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "nonexistent");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));
}
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
_mint(to, tokenId);
require(_checkOnERC721Received(address(0), to, tokenId, _data), "implementer");
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "zero");
require(!_exists(tokenId), "minted");
_beforeTokenTransfer(address(0), to, tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
_approve(address(0), tokenId);
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
_holderTokens[owner].remove(tokenId);
_tokenOwners.remove(tokenId);
emit Transfer(owner, address(0), tokenId);
}
function _transfer(address from, address to, uint256 tokenId) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "not own");
require(to != address(0), "zero");
_beforeTokenTransfer(from, to, tokenId);
_approve(address(0), tokenId);
_holderTokens[from].remove(tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(from, to, tokenId);
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "nonexistent");
_tokenURIs[tokenId] = _tokenURI;
}
function _setBaseURI(string memory baseURI_) internal virtual {
_baseURI = baseURI_;
}
function _setNameAndSymbol(string memory name_, string memory symbol_) internal virtual {
_name = name_;
_symbol = symbol_;
}
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
private returns (bool)
{
if (!to.isContract()) {
return true;
}
bytes memory returndata = to.functionCall(abi.encodeWithSelector(
IERC721Receiver(to).onERC721Received.selector,
_msgSender(),
from,
tokenId,
_data
), "implementer");
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _ERC721_RECEIVED);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
}
文件 5 的 20:EnumerableMap.sol
pragma solidity ^0.8.0;
import "./EnumerableSet.sol";
library EnumerableMap {
using EnumerableSet for EnumerableSet.Bytes32Set;
struct Map {
EnumerableSet.Bytes32Set _keys;
mapping(bytes32 => bytes32) _values;
}
function _set(
Map storage map,
bytes32 key,
bytes32 value
) private returns (bool) {
map._values[key] = value;
return map._keys.add(key);
}
function _remove(Map storage map, bytes32 key) private returns (bool) {
delete map._values[key];
return map._keys.remove(key);
}
function _contains(Map storage map, bytes32 key) private view returns (bool) {
return map._keys.contains(key);
}
function _length(Map storage map) private view returns (uint256) {
return map._keys.length();
}
function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
bytes32 key = map._keys.at(index);
return (key, map._values[key]);
}
function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
bytes32 value = map._values[key];
if (value == bytes32(0)) {
return (_contains(map, key), bytes32(0));
} else {
return (true, value);
}
}
function _get(Map storage map, bytes32 key) private view returns (bytes32) {
bytes32 value = map._values[key];
require(value != 0 || _contains(map, key), "EnumerableMap: nonexistent key");
return value;
}
function _get(
Map storage map,
bytes32 key,
string memory errorMessage
) private view returns (bytes32) {
bytes32 value = map._values[key];
require(value != 0 || _contains(map, key), errorMessage);
return value;
}
struct UintToAddressMap {
Map _inner;
}
function set(
UintToAddressMap storage map,
uint256 key,
address value
) internal returns (bool) {
return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
}
function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
return _remove(map._inner, bytes32(key));
}
function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
return _contains(map._inner, bytes32(key));
}
function length(UintToAddressMap storage map) internal view returns (uint256) {
return _length(map._inner);
}
function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
(bytes32 key, bytes32 value) = _at(map._inner, index);
return (uint256(key), address(uint160(uint256(value))));
}
function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
(bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
return (success, address(uint160(uint256(value))));
}
function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key)))));
}
function get(
UintToAddressMap storage map,
uint256 key,
string memory errorMessage
) internal view returns (address) {
return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
}
}
文件 6 的 20:EnumerableSet.sol
pragma solidity ^0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
set._values[toDeleteIndex] = lastvalue;
set._indexes[lastvalue] = valueIndex;
}
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}
文件 7 的 20:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 8 的 20:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 9 的 20:IERC721Enumerable.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Enumerable is IERC721 {
function totalSupply() external view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
function tokenByIndex(uint256 index) external view returns (uint256);
}
文件 10 的 20:IERC721Metadata.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 11 的 20:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 12 的 20:IMicroManager.sol
pragma solidity >=0.5.0;
interface IMicroManager {
function microBridge(address _address) external view returns (bool);
function treasuryAddress() external view returns (address);
function microProtocolFee() external view returns (uint256);
function oracleAddress() external view returns (address);
}
文件 13 的 20:IPriceOracle.sol
pragma solidity >=0.5.0;
interface IPriceOracle {
function convertUsdToWei(uint256 usdAmount) external view returns (uint256 weiAmount);
}
文件 14 的 20:MerkleProof.sol
pragma solidity ^0.8.0;
library MerkleProof {
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else {
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
}
}
return computedHash == root;
}
}
文件 15 的 20:MicroNFT.sol
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../MicroUtility.sol";
import "./ERC721.sol";
error SaleInactive();
error PresaleInactive();
error PresaleMerkleNotApproved();
error PurchaseWrongPrice(uint256 correctPrice);
error SoldOut();
error PurchaseTooManyForAddress();
error PresaleTooManyForAddress();
error Canceled();
error IsNotBridge();
error SaleCanNotUpdate();
error PreSaleCanNotUpdate();
error InvalidSaleDetail();
error SaleIsNotEnded();
error NonZero();
error Unauthorized();
error InvalidToken(uint256 tokenId);
contract MicroNFT is ERC721, Ownable, ReentrancyGuard, MicroUtility {
using Strings for uint256;
using SafeMath for uint256;
string public notRevealedUri;
bool private initialized;
uint224 private _currentTokenId;
uint256 private constant STATIC_GAS_LIMIT = 210_000;
struct SaleConfiguration {
uint64 editionSize;
uint16 profitSharing;
address payable fundsRecipient;
uint256 publicSalePrice;
uint32 maxSalePurchasePerAddress;
uint64 publicSaleStart;
uint64 publicSaleEnd;
uint64 presaleStart;
uint64 presaleEnd;
bytes32 presaleMerkleRoot;
bool cancelable;
}
mapping(address => uint256) public totalMintsByAddress;
mapping(address => uint256) public presaleMintsByAddress;
mapping(address => bool) public sharingByAddress;
SaleConfiguration public saleConfig;
event BridgeIn(address indexed _to, uint256 _dstChainId, uint256 _tokenId);
event BridgeOut(
address indexed _from,
uint256 _dstChainId,
uint256 _tokenId
);
event Purchase(
address indexed to,
uint256 indexed quantity,
uint256 indexed price,
uint256 firstMintedTokenId
);
event OpenMintFinalized(
address indexed sender,
uint256 editionSize,
uint256 timeEnd
);
event CancelSaleEdition(address indexed sender, uint256 lastTimeUpdated);
event PublicSaleCollection(address indexed sender, uint256 lastTimeUpdated);
event FundsWithdrawn(
address indexed sender,
address indexed fundsRecipient,
uint256 fund
);
event SharingWithdrawn(
address indexed sender,
address indexed fundsRecipient,
uint256 fund
);
constructor() ERC721("", "") {}
modifier onlyBridge() {
if (!microManager.microBridge(_msgSender())) {
revert IsNotBridge();
}
_;
}
modifier onlyCancelable() {
if (saleConfig.cancelable) {
revert Canceled();
}
_;
}
modifier canMintTokens(uint256 quantity) {
if (
saleConfig.editionSize != 0 &&
quantity + _currentTokenId > saleConfig.editionSize
) {
revert SoldOut();
}
_;
}
modifier onlyPublicSaleActive() {
if (!_publicSaleActive()) {
revert SaleInactive();
}
_;
}
modifier onlyPresaleActive() {
if (!_presaleActive()) {
revert PresaleInactive();
}
_;
}
function init(bytes memory initPayload) external onlyOwner returns (bool) {
if (initialized) {
revert Unauthorized();
}
(
string memory _baseURI,
string memory _notRevealedURI,
string memory _name,
string memory _symbol,
address _owner,
address _manager
) = abi.decode(
initPayload,
(string, string, string, string, address, address)
);
_setManager(_manager);
notRevealedUri = _notRevealedURI;
_setBaseURI(_baseURI);
transferOwnership(_owner);
initialized = true;
_setNameAndSymbol(_name, _symbol);
return true;
}
function tokenURI(
uint256 tokenId
) public view virtual override returns (string memory) {
if (!_exists(tokenId)) {
revert InvalidToken(tokenId);
}
if (bytes(notRevealedUri).length > 0) {
return notRevealedUri;
}
string memory currentBaseURI = baseURI();
return
bytes(currentBaseURI).length > 0
? string(
abi.encodePacked(
currentBaseURI,
tokenId.toString(),
".json"
)
)
: "";
}
function setBaseURI(string memory _newBaseURI) external onlyOwner {
_setBaseURI(_newBaseURI);
}
function setNotRevealedURI(
string memory _notRevealedURI
) external onlyOwner {
notRevealedUri = _notRevealedURI;
}
function adminMint(
address recipient,
uint256 quantity
) external onlyOwner canMintTokens(quantity) returns (uint256) {
_mintNFTs(recipient, quantity);
return _currentTokenId;
}
function setSaleDetail(
bytes memory initPayload
) external onlyCancelable onlyOwner {
if (
saleConfig.publicSaleStart != 0 &&
block.timestamp > saleConfig.publicSaleStart
) {
revert SaleCanNotUpdate();
}
if (
saleConfig.presaleStart != 0 &&
block.timestamp > saleConfig.presaleStart
) {
revert PreSaleCanNotUpdate();
}
SaleConfiguration memory config = abi.decode(
initPayload,
(SaleConfiguration)
);
if (
config.publicSaleStart <= block.timestamp ||
config.publicSaleEnd <= config.publicSaleStart ||
config.profitSharing > 50 ||
config.fundsRecipient == address(0)
) {
revert InvalidSaleDetail();
}
saleConfig = SaleConfiguration({
editionSize: config.editionSize,
profitSharing: config.profitSharing,
fundsRecipient: config.fundsRecipient,
publicSalePrice: config.publicSalePrice,
maxSalePurchasePerAddress: config.maxSalePurchasePerAddress,
publicSaleStart: config.publicSaleStart,
publicSaleEnd: config.publicSaleEnd,
presaleStart: config.presaleStart,
presaleEnd: config.presaleEnd,
presaleMerkleRoot: config.presaleMerkleRoot,
cancelable: false
});
emit PublicSaleCollection(_msgSender(), block.timestamp);
}
function finalizeOpenEdition() external onlyCancelable onlyOwner {
saleConfig.editionSize = uint64(_currentTokenId);
saleConfig.publicSaleEnd = uint64(block.timestamp);
emit OpenMintFinalized(
_msgSender(),
saleConfig.editionSize,
block.timestamp
);
}
function cancelSaleEdition() external onlyCancelable onlyOwner {
if (block.timestamp > saleConfig.publicSaleEnd) {
revert SaleIsNotEnded();
}
saleConfig.cancelable = true;
emit CancelSaleEdition(_msgSender(), block.timestamp);
}
function purchase(
uint256 quantity
)
external
payable
onlyCancelable
canMintTokens(quantity)
onlyPublicSaleActive
nonReentrant
returns (uint256)
{
if (quantity == 0) {
revert NonZero();
}
address sender = _msgSender();
uint256 salePrice = saleConfig.publicSalePrice;
uint256 payableValue = msg.value;
uint256 totalFee = salePrice.mul(quantity).add(
getMicroFeeWei(quantity)
);
if (payableValue < totalFee) {
revert PurchaseWrongPrice(totalFee);
}
uint256 remainder = payableValue.sub(totalFee);
if (
saleConfig.maxSalePurchasePerAddress != 0 &&
totalMintsByAddress[sender].add(quantity).sub(
presaleMintsByAddress[sender]
) >
saleConfig.maxSalePurchasePerAddress
) {
revert PurchaseTooManyForAddress();
}
_mintNFTs(sender, quantity);
totalMintsByAddress[sender] += quantity;
_payoutMicroFee(quantity);
_payoutFundingRaise(salePrice, quantity);
uint256 firstMintedTokenId = sourceGetChainPrepend(
uint224(_currentTokenId - quantity)
).add(1);
emit Purchase({
to: sender,
quantity: quantity,
price: salePrice,
firstMintedTokenId: firstMintedTokenId
});
_payoutRemainder(remainder, sender);
return firstMintedTokenId;
}
function purchasePresale(
uint256 quantity,
uint256 maxQuantity,
uint256 pricePerToken,
bytes32[] calldata merkleProof
)
external
payable
onlyCancelable
nonReentrant
canMintTokens(quantity)
onlyPresaleActive
returns (uint256)
{
address sender = _msgSender();
if (
!MerkleProof.verify(
merkleProof,
saleConfig.presaleMerkleRoot,
keccak256(abi.encode(sender, maxQuantity, pricePerToken))
)
) {
revert PresaleMerkleNotApproved();
}
if (quantity == 0) {
revert NonZero();
}
uint256 salePrice = pricePerToken;
uint256 payableValue = msg.value;
uint256 totalFee = salePrice.mul(quantity).add(
getMicroFeeWei(quantity)
);
if (payableValue < totalFee) {
revert PurchaseWrongPrice(totalFee);
}
uint256 remainder = payableValue.sub(totalFee);
if (presaleMintsByAddress[sender] > maxQuantity) {
revert PresaleTooManyForAddress();
}
_mintNFTs(sender, quantity);
presaleMintsByAddress[sender] += quantity;
totalMintsByAddress[sender] += quantity;
_payoutMicroFee(quantity);
_payoutFundingRaise(salePrice, quantity);
uint256 firstMintedTokenId = sourceGetChainPrepend(
uint224(_currentTokenId - quantity)
).add(1);
emit Purchase({
to: sender,
quantity: quantity,
price: salePrice,
firstMintedTokenId: firstMintedTokenId
});
_payoutRemainder(remainder, sender);
return firstMintedTokenId;
}
function withdrawProfitSharing() external nonReentrant {
address sender = _msgSender();
if (
saleConfig.profitSharing == 0 ||
sharingByAddress[sender] ||
totalMintsByAddress[sender] == 0
) {
revert Unauthorized();
}
if (
!saleConfig.cancelable && saleConfig.publicSaleEnd > block.timestamp
) {
revert SaleIsNotEnded();
}
uint256 rewards = getPendingProfitSharing(sender);
if (rewards > 0) {
uint256 balanceAddress = address(this).balance;
uint256 paymentValue = rewards > balanceAddress
? balanceAddress
: rewards;
_payoutRemainder(paymentValue, sender);
}
sharingByAddress[sender] = true;
emit SharingWithdrawn(address(this), sender, rewards);
}
function getPendingProfitSharing(
address _sender
) public view returns (uint256) {
if (sharingByAddress[_sender]) return 0;
if (
totalMintsByAddress[_sender] > 0 &&
saleConfig.profitSharing > 0 &&
saleConfig.publicSalePrice > 0
) {
uint256 rewards = saleConfig
.publicSalePrice
.mul(totalMintsByAddress[_sender])
.mul(saleConfig.profitSharing)
.div(100);
return rewards;
} else {
return 0;
}
}
function bridgeOut(
address _from,
uint64 _dstChainId,
uint256 _tokenId
) external onlyBridge {
if (
!_isApprovedOrOwner(_msgSender(), _tokenId) ||
ERC721.ownerOf(_tokenId) != _msgSender()
) {
revert Unauthorized();
}
_burn(_tokenId);
emit BridgeOut(_from, _dstChainId, _tokenId);
}
function bridgeIn(
address _toAddress,
uint64 _dstChainId,
uint256 _tokenId
) external onlyBridge {
if (_exists(_tokenId)) {
revert InvalidToken(_tokenId);
}
_safeMint(_toAddress, _tokenId);
emit BridgeIn(_toAddress, _dstChainId, _tokenId);
}
function _mintNFTs(address recipient, uint256 quantity) internal {
uint256 chainPrepend = sourceGetChainPrepend(0);
uint256 tokenId = 0;
for (uint256 i = 0; i < quantity; i++) {
_currentTokenId += 1;
while (_exists(chainPrepend + uint256(_currentTokenId))) {
_currentTokenId += 1;
}
tokenId = sourceGetChainPrepend(_currentTokenId);
_safeMint(recipient, tokenId);
}
}
function sourceGetChainPrepend(uint224 id) internal view returns (uint256) {
return
uint256(
bytes32(abi.encodePacked(uint32(block.chainid), uint224(id)))
);
}
function _publicSaleActive() internal view returns (bool) {
return
saleConfig.publicSaleStart <= block.timestamp &&
saleConfig.publicSaleEnd > block.timestamp;
}
function _presaleActive() internal view returns (bool) {
return
saleConfig.presaleStart <= block.timestamp &&
saleConfig.presaleEnd > block.timestamp;
}
function _payoutFundingRaise(
uint256 salePrice,
uint256 quantity
) internal returns (bool) {
if (saleConfig.fundsRecipient == address(0) || salePrice == 0) {
return false;
}
uint256 totalPurchase = salePrice.mul(quantity);
uint256 profitSharing = totalPurchase.mul(saleConfig.profitSharing).div(
100
);
uint256 funds = totalPurchase > profitSharing
? totalPurchase.sub(profitSharing)
: 0;
_payoutRemainder(funds, saleConfig.fundsRecipient);
emit FundsWithdrawn(_msgSender(), saleConfig.fundsRecipient, funds);
return true;
}
function _payoutRemainder(uint256 value, address recipient) internal {
if (value > 0) {
(bool success, ) = payable(recipient).call{
value: value,
gas: gasleft() > STATIC_GAS_LIMIT ? STATIC_GAS_LIMIT : gasleft()
}("");
if (!success) {
revert PaymentFailed();
}
}
}
}
文件 16 的 20:MicroUtility.sol
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/access/Ownable.sol";
import {IPriceOracle} from "./interfaces/IPriceOracle.sol";
import {IMicroManager} from "./interfaces/IMicroManager.sol";
error PaymentFailed();
contract MicroUtility is Ownable {
IMicroManager public microManager;
uint256 private constant STATIC_GAS_LIMIT = 210_000;
event FeePayout(
uint256 MicroMintFeeWei,
address MicroFeeRecipient,
bool success
);
constructor() {}
function getMicroFeeUsd(
uint256 quantity
) public view returns (uint256 fee) {
fee = microManager.microProtocolFee() * quantity;
}
function getMicroFeeWei(uint256 quantity) public view returns (uint256) {
return _usdToWei(microManager.microProtocolFee() * quantity);
}
function _payoutMicroFee(uint256 quantity) internal {
uint256 microProtocolFee = getMicroFeeWei(quantity);
address payable treasury = payable(microManager.treasuryAddress());
(bool success, ) = treasury.call{
value: microProtocolFee,
gas: gasleft() > STATIC_GAS_LIMIT ? STATIC_GAS_LIMIT : gasleft()
}("");
if (!success) {
revert PaymentFailed();
}
emit FeePayout(microProtocolFee, treasury, success);
}
function _usdToWei(
uint256 amount
) internal view returns (uint256 weiAmount) {
if (amount == 0) {
return 0;
}
weiAmount = IPriceOracle(microManager.oracleAddress()).convertUsdToWei(
amount
);
}
function _setManager(address _manager) internal {
microManager = IMicroManager(_manager);
}
}
文件 17 的 20:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_setOwner(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 18 的 20:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 19 的 20:SafeMath.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
文件 20 的 20:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
{
"compilationTarget": {
"contracts/token/MicroNFT.sol": "MicroNFT"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Canceled","type":"error"},{"inputs":[],"name":"InvalidSaleDetail","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"IsNotBridge","type":"error"},{"inputs":[],"name":"NonZero","type":"error"},{"inputs":[],"name":"PaymentFailed","type":"error"},{"inputs":[],"name":"PreSaleCanNotUpdate","type":"error"},{"inputs":[],"name":"PresaleInactive","type":"error"},{"inputs":[],"name":"PresaleMerkleNotApproved","type":"error"},{"inputs":[],"name":"PresaleTooManyForAddress","type":"error"},{"inputs":[],"name":"PurchaseTooManyForAddress","type":"error"},{"inputs":[{"internalType":"uint256","name":"correctPrice","type":"uint256"}],"name":"PurchaseWrongPrice","type":"error"},{"inputs":[],"name":"SaleCanNotUpdate","type":"error"},{"inputs":[],"name":"SaleInactive","type":"error"},{"inputs":[],"name":"SaleIsNotEnded","type":"error"},{"inputs":[],"name":"SoldOut","type":"error"},{"inputs":[],"name":"Unauthorized","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":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_dstChainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"BridgeIn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"uint256","name":"_dstChainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"BridgeOut","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"lastTimeUpdated","type":"uint256"}],"name":"CancelSaleEdition","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"MicroMintFeeWei","type":"uint256"},{"indexed":false,"internalType":"address","name":"MicroFeeRecipient","type":"address"},{"indexed":false,"internalType":"bool","name":"success","type":"bool"}],"name":"FeePayout","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"fundsRecipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"fund","type":"uint256"}],"name":"FundsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"editionSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timeEnd","type":"uint256"}],"name":"OpenMintFinalized","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":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"lastTimeUpdated","type":"uint256"}],"name":"PublicSaleCollection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"firstMintedTokenId","type":"uint256"}],"name":"Purchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"fundsRecipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"fund","type":"uint256"}],"name":"SharingWithdrawn","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":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"adminMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_toAddress","type":"address"},{"internalType":"uint64","name":"_dstChainId","type":"uint64"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"bridgeIn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint64","name":"_dstChainId","type":"uint64"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"bridgeOut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelSaleEdition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalizeOpenEdition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"getMicroFeeUsd","outputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"getMicroFeeWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"}],"name":"getPendingProfitSharing","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"initPayload","type":"bytes"}],"name":"init","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","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":[],"name":"microManager","outputs":[{"internalType":"contract IMicroManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notRevealedUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"presaleMintsByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"purchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256","name":"maxQuantity","type":"uint256"},{"internalType":"uint256","name":"pricePerToken","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"purchasePresale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"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":[],"name":"saleConfig","outputs":[{"internalType":"uint64","name":"editionSize","type":"uint64"},{"internalType":"uint16","name":"profitSharing","type":"uint16"},{"internalType":"address payable","name":"fundsRecipient","type":"address"},{"internalType":"uint256","name":"publicSalePrice","type":"uint256"},{"internalType":"uint32","name":"maxSalePurchasePerAddress","type":"uint32"},{"internalType":"uint64","name":"publicSaleStart","type":"uint64"},{"internalType":"uint64","name":"publicSaleEnd","type":"uint64"},{"internalType":"uint64","name":"presaleStart","type":"uint64"},{"internalType":"uint64","name":"presaleEnd","type":"uint64"},{"internalType":"bytes32","name":"presaleMerkleRoot","type":"bytes32"},{"internalType":"bool","name":"cancelable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initPayload","type":"bytes"}],"name":"setSaleDetail","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"sharingByAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalMintsByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawProfitSharing","outputs":[],"stateMutability":"nonpayable","type":"function"}]