文件 1 的 19:Address.sol
pragma solidity 0.8.4;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 19:CircumnavigationOpenEdition.sol
pragma solidity 0.8.4;
import "./NiftyBuilderInstance.sol";
import "./ICircumnavigationURI.sol";
contract CircumnavigationOpenEdition is NiftyBuilderInstance {
ICircumnavigationURI public circumnavigationContract;
constructor(
address niftyRegistryContract,
address defaultOwner,
address circumnavigationContractAddress) NiftyBuilderInstance(
"Circumnavigation Collector Only Open Edition by Dave Pollot",
"CIRCUMNAVIGATION OE",
2,
1,
"",
"Dave Pollot",
niftyRegistryContract,
defaultOwner) {
circumnavigationContract = ICircumnavigationURI(circumnavigationContractAddress);
}
function tokenURI(uint256 tokenId) external virtual view override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
return circumnavigationContract.cITokenURI();
}
}
文件 3 的 19:Clones.sol
pragma solidity 0.8.4;
library Clones {
function clone(address implementation) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create(0, ptr, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
instance := create2(0, ptr, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
mstore(add(ptr, 0x38), shl(0x60, deployer))
mstore(add(ptr, 0x4c), salt)
mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
predicted := keccak256(add(ptr, 0x37), 0x55)
}
}
function predictDeterministicAddress(address implementation, bytes32 salt)
internal
view
returns (address predicted)
{
return predictDeterministicAddress(implementation, salt, address(this));
}
}
文件 4 的 19:Context.sol
pragma solidity 0.8.4;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 5 的 19:ERC165.sol
pragma solidity 0.8.4;
import "../interface/IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 19:ERC721.sol
pragma solidity 0.8.4;
import "../interface/IERC721.sol";
import "../interface/IERC721Receiver.sol";
import "../interface/IERC721Metadata.sol";
import "../util/Context.sol";
import "../util/Strings.sol";
import "../standard/ERC165.sol";
import "./NiftyEntity.sol";
contract ERC721 is NiftyEntity, Context, ERC165, IERC721, IERC721Metadata {
uint immutable public _id;
uint immutable public _typeCount;
address immutable public _defaultOwner;
uint immutable public topLevelMultiplier;
uint immutable public midLevelMultiplier;
string private _name;
string private _symbol;
string private _baseURI;
mapping(uint256 => string) private _niftyTypeName;
mapping(uint256 => string) private _niftyTypeIPFSHashes;
mapping (uint256 => address) internal _owners;
mapping (address => uint256) internal _balances;
mapping (uint256 => address) private _tokenApprovals;
mapping (address => mapping (address => bool)) private _operatorApprovals;
constructor(string memory name_,
string memory symbol_,
uint256 id_,
string memory baseURI_,
uint256 typeCount_,
address defaultOwner_,
address niftyRegistryContract) NiftyEntity(niftyRegistryContract) {
_name = name_;
_symbol = symbol_;
_id = id_;
_baseURI = baseURI_;
_typeCount = typeCount_;
_defaultOwner = defaultOwner_;
midLevelMultiplier = 100000;
topLevelMultiplier = id_ * 1000000000;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC721).interfaceId
|| interfaceId == type(IERC721Metadata).interfaceId
|| super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) external virtual view override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory tokenIdStr = Strings.toString(tokenId);
return string(abi.encodePacked(_baseURI, tokenIdStr));
}
function tokenIPFSHash(uint256 tokenId) external view returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: IPFS hash query for nonexistent token");
uint256 niftyType = _getNiftyTypeId(tokenId);
return _niftyTypeIPFSHashes[niftyType];
}
function _getNiftyTypeId(uint256 tokenId) internal view returns (uint256) {
if(tokenId <= topLevelMultiplier) {
return 0;
} else {
return (tokenId - topLevelMultiplier) / midLevelMultiplier;
}
}
function tokenName(uint256 tokenId) external view returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: Name query for nonexistent token");
uint256 niftyType = _getNiftyTypeId(tokenId);
return _niftyTypeName[niftyType];
}
function _setTokenIPFSHashNiftyType(uint256 niftyType, string memory ipfs_hash) internal {
require(bytes(_niftyTypeIPFSHashes[niftyType]).length == 0, "ERC721Metadata: IPFS hash already set");
_niftyTypeIPFSHashes[niftyType] = ipfs_hash;
}
function _setNiftyTypeName(uint256 niftyType, string memory nifty_type_name) internal {
_niftyTypeName[niftyType] = nifty_type_name;
}
function _setBaseURI(string memory baseURI_) internal {
_baseURI = baseURI_;
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
require(operator != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[_msgSender()][operator] = approved;
emit ApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(address from, address to, uint256 tokenId) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
}
function _transfer(address from, address to, uint256 tokenId) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
require(to != address(0), "ERC721: transfer to the zero address");
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
private returns (bool)
{
if (isContract(to)) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver(to).onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
}
文件 7 的 19:ERC721Burnable.sol
pragma solidity 0.8.4;
import "../core/ERC721.sol";
abstract contract ERC721Burnable is Context, ERC721 {
function burn(uint256 tokenId) public virtual {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
_burn(tokenId);
}
}
文件 8 的 19:ICircumnavigationURI.sol
pragma solidity 0.8.4;
interface ICircumnavigationURI {
function cITokenURI() external view returns (string memory);
function cIITokenURI() external view returns (string memory);
function cIIITokenURI(uint8 niftyType) external view returns (string memory);
function cIOneOfOneTokenURI() external view returns (string memory);
function cIIOneOfOneTokenURI() external view returns (string memory);
}
文件 9 的 19:ICloneablePaymentSplitter.sol
pragma solidity 0.8.4;
import "./IERC165.sol";
import "../util/SafeERC20.sol";
interface ICloneablePaymentSplitter is IERC165 {
event PayeeAdded(address account, uint256 shares);
event PaymentReleased(address to, uint256 amount);
event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
event PaymentReceived(address from, uint256 amount);
function initialize(address[] calldata payees, uint256[] calldata shares_) external;
function totalShares() external view returns (uint256);
function totalReleased() external view returns (uint256);
function totalReleased(IERC20 token) external view returns (uint256);
function shares(address account) external view returns (uint256);
function released(address account) external view returns (uint256);
function released(IERC20 token, address account) external view returns (uint256);
function payee(uint256 index) external view returns (address);
function release(address payable account) external;
function release(IERC20 token, address account) external;
function pendingPayment(address account) external view returns (uint256);
function pendingPayment(IERC20 token, address account) external view returns (uint256);
}
文件 10 的 19:IERC165.sol
pragma solidity 0.8.4;
interface IERC165 {
function supportsInterface(bytes4 interfaceId)
external
view
returns (bool);
}
文件 11 的 19:IERC20.sol
pragma solidity 0.8.4;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 12 的 19:IERC2981.sol
pragma solidity 0.8.4;
import "./IERC165.sol";
interface IERC2981 is IERC165 {
function royaltyInfo(
uint256 _tokenId,
uint256 _salePrice
) external view returns (
address receiver,
uint256 royaltyAmount
);
}
文件 13 的 19:IERC721.sol
pragma solidity 0.8.4;
import "./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;
}
文件 14 的 19:IERC721Metadata.sol
pragma solidity 0.8.4;
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);
}
文件 15 的 19:IERC721Receiver.sol
pragma solidity 0.8.4;
interface IERC721Receiver {
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
}
文件 16 的 19:NiftyBuilderInstance.sol
pragma solidity 0.8.4;
import "./ERC721.sol";
import "../interface/ICloneablePaymentSplitter.sol";
import "../interface/IERC2981.sol";
import "../standard/ERC721Burnable.sol";
import "../util/Clones.sol";
contract NiftyBuilderInstance is ERC721, ERC721Burnable, IERC2981 {
event RoyaltyReceiverUpdated(uint256 indexed niftyType, address previousReceiver, address newReceiver);
event PaymentReleased(address to, uint256 amount);
event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
string private _creator;
uint256 immutable public _percentageTotal;
mapping(uint256 => uint256) public _percentageRoyalty;
mapping (uint256 => address) _royaltySplitters;
mapping (uint256 => address) _royaltyReceivers;
mapping (uint256 => uint256) public _mintCount;
mapping (uint256 => bytes32) private _finalized;
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress);
constructor(
string memory name,
string memory symbol,
uint256 id,
uint256 typeCount,
string memory baseURI,
string memory creator_,
address niftyRegistryContract,
address defaultOwner) ERC721(name, symbol, id, baseURI, typeCount, defaultOwner, niftyRegistryContract) {
_creator = creator_;
_percentageTotal = 10000;
}
function setRoyaltyBips(uint256 niftyType, uint256 percentageRoyalty_) external onlyValidSender {
require(percentageRoyalty_ <= _percentageTotal, "NiftyBuilderInstance: Illegal argument more than 100%");
_percentageRoyalty[niftyType] = percentageRoyalty_;
}
function royaltyInfo(uint256 tokenId, uint256 salePrice) public override view returns (address, uint256) {
require(_exists(tokenId), "NiftyBuilderInstance: operator query for nonexistent token");
uint256 niftyType = _getNiftyTypeId(tokenId);
uint256 royaltyAmount = (salePrice * _percentageRoyalty[niftyType]) / _percentageTotal;
address royaltyReceiver = _getRoyaltyReceiverByNiftyType(niftyType);
require(royaltyReceiver != address(0), "NiftyBuilderInstance: No royalty receiver");
return (royaltyReceiver, royaltyAmount);
}
function initializeRoyalties(address splitterImplementation, uint256 niftyType, address[] calldata payees, uint256[] calldata shares_) external onlyValidSender {
address previousReceiver = _getRoyaltyReceiverByNiftyType(niftyType);
address newReceiver = address(0);
if(payees.length == 1) {
newReceiver = payees[0];
_royaltyReceivers[niftyType] = newReceiver;
delete _royaltySplitters[niftyType];
} else {
delete _royaltyReceivers[niftyType];
require(IERC165(splitterImplementation).supportsInterface(type(ICloneablePaymentSplitter).interfaceId), "Not a valid payment splitter");
newReceiver = payable (Clones.clone(splitterImplementation));
ICloneablePaymentSplitter(newReceiver).initialize(payees, shares_);
_royaltySplitters[niftyType] = newReceiver;
}
emit RoyaltyReceiverUpdated(niftyType, previousReceiver, newReceiver);
}
function getRoyaltyReceiverByTokenId(uint256 tokenId) public view returns (address) {
return _getRoyaltyReceiverByNiftyType(_getNiftyTypeId(tokenId));
}
function getRoyaltyReceiverByNiftyType(uint256 niftyType) public view returns (address) {
return _getRoyaltyReceiverByNiftyType(niftyType);
}
function releaseRoyalties(address payable account) external {
uint256 totalPaymentAmount = 0;
for(uint256 niftyType = 1; niftyType <= _typeCount; niftyType++) {
address paymentSplitterAddress = _royaltySplitters[niftyType];
if(paymentSplitterAddress != address(0)) {
ICloneablePaymentSplitter paymentSplitter = ICloneablePaymentSplitter(paymentSplitterAddress);
uint256 pendingPaymentAmount = paymentSplitter.pendingPayment(account);
if(pendingPaymentAmount > 0) {
totalPaymentAmount += pendingPaymentAmount;
paymentSplitter.release(account);
}
}
}
if(totalPaymentAmount > 0) {
emit PaymentReleased(account, totalPaymentAmount);
}
}
function releaseRoyalties(IERC20 token, address account) external {
uint256 totalPaymentAmount = 0;
for(uint256 niftyType = 1; niftyType <= _typeCount; niftyType++) {
address paymentSplitterAddress = _royaltySplitters[niftyType];
if(paymentSplitterAddress != address(0)) {
ICloneablePaymentSplitter paymentSplitter = ICloneablePaymentSplitter(paymentSplitterAddress);
uint256 pendingPaymentAmount = paymentSplitter.pendingPayment(token, account);
if(pendingPaymentAmount > 0) {
totalPaymentAmount += pendingPaymentAmount;
paymentSplitter.release(token, account);
}
}
}
if(totalPaymentAmount > 0) {
emit ERC20PaymentReleased(token, account, totalPaymentAmount);
}
}
function pendingRoyaltyPayment(address account) external view returns (uint256) {
uint256 totalPaymentAmount = 0;
for(uint256 niftyType = 1; niftyType <= _typeCount; niftyType++) {
address paymentSplitterAddress = _royaltySplitters[niftyType];
if(paymentSplitterAddress != address(0)) {
ICloneablePaymentSplitter paymentSplitter = ICloneablePaymentSplitter(paymentSplitterAddress);
totalPaymentAmount += paymentSplitter.pendingPayment(account);
}
}
return totalPaymentAmount;
}
function pendingRoyaltyPayment(IERC20 token, address account) external view returns (uint256) {
uint256 totalPaymentAmount = 0;
for(uint256 niftyType = 1; niftyType <= _typeCount; niftyType++) {
address paymentSplitterAddress = _royaltySplitters[niftyType];
if(paymentSplitterAddress != address(0)) {
ICloneablePaymentSplitter paymentSplitter = ICloneablePaymentSplitter(paymentSplitterAddress);
totalPaymentAmount += paymentSplitter.pendingPayment(token, account);
}
}
return totalPaymentAmount;
}
function _encodeTokenId(uint256 niftyType, uint256 tokenNumber) private view returns (uint256) {
return (topLevelMultiplier + (niftyType * midLevelMultiplier) + tokenNumber);
}
function _getFinalized(uint256 niftyType) public view returns (bool) {
bytes32 chunk = _finalized[niftyType / 256];
return (chunk & bytes32(1 << (niftyType % 256))) != 0x0;
}
function setFinalized(uint256 niftyType) public onlyValidSender {
uint256 quotient = niftyType / 256;
bytes32 chunk = _finalized[quotient];
_finalized[quotient] = chunk | bytes32(1 << (niftyType % 256));
}
function creator() public view virtual returns (string memory) {
return _creator;
}
function setBaseURI(string memory baseURI) public onlyValidSender {
_setBaseURI(baseURI);
}
function setNiftyName(uint256 niftyType, string memory niftyName) public onlyValidSender {
_setNiftyTypeName(niftyType, niftyName);
}
function setNiftyIPFSHash(uint256 niftyType, string memory hashIPFS) public onlyValidSender {
_setTokenIPFSHashNiftyType(niftyType, hashIPFS);
}
function mintNifty(uint256 niftyType, uint256 count) public onlyValidSender {
require(!_getFinalized(niftyType), "NiftyBuilderInstance: minting concluded for nifty type");
uint256 tokenNumber = _mintCount[niftyType] + 1;
uint256 tokenId00 = _encodeTokenId(niftyType, tokenNumber);
uint256 tokenId01 = tokenId00 + count - 1;
for (uint256 tokenId = tokenId00; tokenId <= tokenId01; tokenId++) {
_owners[tokenId] = _defaultOwner;
}
_mintCount[niftyType] += count;
_balances[_defaultOwner] += count;
emit ConsecutiveTransfer(tokenId00, tokenId01, address(0), _defaultOwner);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) {
return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId);
}
function _getRoyaltyReceiverByNiftyType(uint256 niftyType) private view returns (address) {
if(_royaltyReceivers[niftyType] != address(0)) {
return _royaltyReceivers[niftyType];
} else if(_royaltySplitters[niftyType] != address(0)) {
return _royaltySplitters[niftyType];
}
return address(0);
}
}
文件 17 的 19:NiftyEntity.sol
pragma solidity 0.8.4;
contract NiftyEntity {
address internal immutable niftyRegistryContract;
modifier onlyValidSender() {
NiftyRegistry niftyRegistry = NiftyRegistry(niftyRegistryContract);
bool isValid = niftyRegistry.isValidNiftySender(msg.sender);
require(isValid, "NiftyEntity: Invalid msg.sender");
_;
}
constructor(address _niftyRegistryContract) {
niftyRegistryContract = _niftyRegistryContract;
}
}
interface NiftyRegistry {
function isValidNiftySender(address sending_key) external view returns (bool);
}
文件 18 的 19:SafeERC20.sol
pragma solidity 0.8.4;
import "../interface/IERC20.sol";
import "./Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 19 的 19:Strings.sol
pragma solidity 0.8.4;
library Strings {
bytes16 private constant alphabet = "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);
}
}
{
"compilationTarget": {
"contracts/core/CircumnavigationOpenEdition.sol": "CircumnavigationOpenEdition"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1500
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"niftyRegistryContract","type":"address"},{"internalType":"address","name":"defaultOwner","type":"address"},{"internalType":"address","name":"circumnavigationContractAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":true,"internalType":"address","name":"toAddress","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"niftyType","type":"uint256"},{"indexed":false,"internalType":"address","name":"previousReceiver","type":"address"},{"indexed":false,"internalType":"address","name":"newReceiver","type":"address"}],"name":"RoyaltyReceiverUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_defaultOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"niftyType","type":"uint256"}],"name":"_getFinalized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_id","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_mintCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_percentageRoyalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_percentageTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_typeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"circumnavigationContract","outputs":[{"internalType":"contract ICircumnavigationURI","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creator","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","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":"niftyType","type":"uint256"}],"name":"getRoyaltyReceiverByNiftyType","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRoyaltyReceiverByTokenId","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"splitterImplementation","type":"address"},{"internalType":"uint256","name":"niftyType","type":"uint256"},{"internalType":"address[]","name":"payees","type":"address[]"},{"internalType":"uint256[]","name":"shares_","type":"uint256[]"}],"name":"initializeRoyalties","outputs":[],"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":"midLevelMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"niftyType","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mintNifty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"pendingRoyaltyPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"pendingRoyaltyPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"releaseRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"releaseRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"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":"uint256","name":"niftyType","type":"uint256"}],"name":"setFinalized","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"niftyType","type":"uint256"},{"internalType":"string","name":"hashIPFS","type":"string"}],"name":"setNiftyIPFSHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"niftyType","type":"uint256"},{"internalType":"string","name":"niftyName","type":"string"}],"name":"setNiftyName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"niftyType","type":"uint256"},{"internalType":"uint256","name":"percentageRoyalty_","type":"uint256"}],"name":"setRoyaltyBips","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenIPFSHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"topLevelMultiplier","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"}]