ERC7160TL

Git Source

Inherits: ERC721Upgradeable, EIP2981TLUpgradeable, OwnableAccessControlUpgradeable, ICreatorBase, IERC721TL, IStory, IERC4906, IERC7160

Author: transientlabs.xyz

Sovereign ERC-7160 Creator Contract with Story Inscriptions

When unpinned, the latest metadata added for a token is returned from tokenURI and tokenURIs

State Variables

VERSION

String representation of uint256

String representation for address

string public constant VERSION = "3.0.1";

ADMIN_ROLE

bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");

APPROVED_MINT_CONTRACT

bytes32 public constant APPROVED_MINT_CONTRACT = keccak256("APPROVED_MINT_CONTRACT");

_counter

uint256 private _counter;

storyEnabled

bool public storyEnabled;

tlNftDelegationRegistry

ITLNftDelegationRegistry public tlNftDelegationRegistry;

blocklistRegistry

IBlockListRegistry public blocklistRegistry;

_burned

mapping(uint256 => bool) private _burned;

_tokenUris

mapping(uint256 => string) private _tokenUris;

_multiMetadatas

mapping(uint256 => MultiMetadata) private _multiMetadatas;

_multiMetadataBaseUris

string[] private _multiMetadataBaseUris;

_batchMints

BatchMint[] private _batchMints;

Functions

constructor

constructor(bool disable);

Parameters

NameTypeDescription
disableboolBoolean to disable initialization for the implementation contract

initialize

tx.origin is used in the events here as these can be deployed via contract factories and we want to capture the true sender

function initialize(
    string memory name,
    string memory symbol,
    string memory personalization,
    address defaultRoyaltyRecipient,
    uint256 defaultRoyaltyPercentage,
    address initOwner,
    address[] memory admins,
    bool enableStory,
    address initBlockListRegistry,
    address initNftDelegationRegistry
) external initializer;

Parameters

NameTypeDescription
namestringThe name of the 721 contract
symbolstringThe symbol of the 721 contract
personalizationstringA string to emit as a collection story. Can be ASCII art or something else that is a personalization of the contract.
defaultRoyaltyRecipientaddressThe default address for royalty payments
defaultRoyaltyPercentageuint256The default royalty percentage of basis points (out of 10,000)
initOwneraddressThe owner of the contract
adminsaddress[]Array of admin addresses to add to the contract
enableStoryboolA bool deciding whether to add story fuctionality or not
initBlockListRegistryaddressAddress of the blocklist registry to use
initNftDelegationRegistryaddressAddress of the TL nft delegation registry to use

totalSupply

Function to get total supply minted so far

function totalSupply() external view returns (uint256);

setApprovedMintContracts

Function to set approved mint contracts

Access to owner or admin

function setApprovedMintContracts(address[] calldata minters, bool status) external onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
mintersaddress[]Array of minters to grant approval to
statusboolStatus for the minters

mint

Function to mint a single token

Requires owner or admin

function mint(address recipient, string calldata uri) external onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
recipientaddressThe recipient of the token - assumed as able to receive 721 tokens
uristringThe token uri to mint

mint

Function to mint a single token

Requires owner or admin

function mint(address recipient, string calldata uri, address royaltyAddress, uint256 royaltyPercent)
    external
    onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
recipientaddressThe recipient of the token - assumed as able to receive 721 tokens
uristringThe token uri to mint
royaltyAddressaddress
royaltyPercentuint256

batchMint

Function to batch mint tokens

Requires owner or admin

function batchMint(address recipient, uint128 numTokens, string calldata baseUri)
    external
    onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
recipientaddressThe recipient of the token - assumed as able to receive 721 tokens
numTokensuint128Number of tokens in the batch mint
baseUristringThe base uri for the batch, expecting json to be in order, starting at file name 0, and SHOULD NOT have a trailing /

airdrop

Function to airdrop tokens to addresses

Requires owner or admin

function airdrop(address[] calldata addresses, string calldata baseUri) external onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
addressesaddress[]Dynamic array of addresses to mint to
baseUristringThe base uri for the batch, expecting json to be in order, starting at file name 0, and SHOULD NOT have a trailing /

externalMint

Function to allow an approved mint contract to mint

Requires the caller to be an approved mint contract

function externalMint(address recipient, string calldata uri) external onlyRole(APPROVED_MINT_CONTRACT);

Parameters

NameTypeDescription
recipientaddressThe recipient of the token - assumed as able to receive 721 tokens
uristringThe token uri to mint

burn

Function to burn a token

Caller must be approved or owner of the token

function burn(uint256 tokenId) external;

Parameters

NameTypeDescription
tokenIduint256The token to burn

setDefaultRoyalty

Function to set the default royalty specification

Requires owner or admin

function setDefaultRoyalty(address newRecipient, uint256 newPercentage) external onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
newRecipientaddressThe new royalty payout address
newPercentageuint256The new royalty percentage in basis (out of 10,000)

setTokenRoyalty

Function to override a token's royalty info

Requires owner or admin

function setTokenRoyalty(uint256 tokenId, address newRecipient, uint256 newPercentage)
    external
    onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
tokenIduint256The token to override royalty for
newRecipientaddressThe new royalty payout address for the token id
newPercentageuint256The new royalty percentage in basis (out of 10,000) for the token id

addTokenUris

Function to add token uris

Written to take in many token ids and a base uri that contains metadata files with file names matching the index of each token id in the tokenIds array (aka folderIndex)

No trailing slash on the base uri

Must be called by contract owner, admin, or approved mint contract

function addTokenUris(uint256[] calldata tokenIds, string calldata baseUri) external;

Parameters

NameTypeDescription
tokenIdsuint256[]Array of token ids that get metadata added to them
baseUristringThe base uri of a folder containing metadata - file names start at 0 and increase monotonically

tokenURIs

Get all token uris associated with a particular token

If a token uri is pinned, the index returned SHOULD be the index in the string array

function tokenURIs(uint256 tokenId) external view returns (uint256 index, string[] memory uris, bool pinned);

Parameters

NameTypeDescription
tokenIduint256The identifier for the nft

Returns

NameTypeDescription
indexuint256An unisgned integer that specifies which uri is pinned for a token (or the default uri if unpinned)
urisstring[]A string array of all uris associated with a token
pinnedboolA boolean showing if the token has pinned metadata or not

pinTokenURI

Pin a specific token uri for a particular token

This call MUST revert if the token does not exist

function pinTokenURI(uint256 tokenId, uint256 index) external;

Parameters

NameTypeDescription
tokenIduint256The identifier of the nft
indexuint256The index in the string array returned from the tokenURIs function that should be pinned for the token

unpinTokenURI

Unpin metadata for a particular token

This call MUST revert if the token does not exist

function unpinTokenURI(uint256 tokenId) external;

Parameters

NameTypeDescription
tokenIduint256The identifier of the nft

hasPinnedTokenURI

Check on-chain if a token id has a pinned uri or not

This call MUST revert if the token does not exist

function hasPinnedTokenURI(uint256 tokenId) external view returns (bool);

Parameters

NameTypeDescription
tokenIduint256The identifier of the nft

Returns

NameTypeDescription
<none>boolpinned A bool specifying if a token has metadata pinned or not

tokenURI

function tokenURI(uint256 tokenId) public view override(ERC721Upgradeable) returns (string memory uri);

addCollectionStory

Function to let the creator add a story to the collection they have created

Depending on the implementation, this function may be restricted in various ways, such as limiting the number of times the creator may write a story.

function addCollectionStory(string calldata, string calldata story) external onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
<none>string
storystringThe story written and attached to the token id

addCreatorStory

Function to let the creator add a story to any token they have created

Depending on the implementation, this function may be restricted in various ways, such as limiting the number of times the creator may write a story.

function addCreatorStory(uint256 tokenId, string calldata, string calldata story)
    external
    onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
tokenIduint256The token id to which the story is attached
<none>string
storystringThe story written and attached to the token id

addStory

Function to let collectors add a story to any token they own

Depending on the implementation, this function may be restricted in various ways, such as limiting the number of times a collector may write a story.

function addStory(uint256 tokenId, string calldata, string calldata story) external;

Parameters

NameTypeDescription
tokenIduint256The token id to which the story is attached
<none>string
storystringThe story written and attached to the token id

setStoryStatus

Function to enable or disable collector story inscriptions

Requires owner or admin

function setStoryStatus(bool status) external onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
statusboolThe status to set for collector story inscriptions

setBlockListRegistry

Function to change the blocklist registry

Access to owner or admin

function setBlockListRegistry(address newBlockListRegistry) external onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
newBlockListRegistryaddressThe new blocklist registry

approve

function approve(address to, uint256 tokenId) public override(ERC721Upgradeable, IERC721);

setApprovalForAll

function setApprovalForAll(address operator, bool approved) public override(ERC721Upgradeable, IERC721);

setNftDelegationRegistry

Function to change the TL NFT delegation registry

Access to owner or admin

function setNftDelegationRegistry(address newNftDelegationRegistry) external onlyRoleOrOwner(ADMIN_ROLE);

Parameters

NameTypeDescription
newNftDelegationRegistryaddressThe new blocklist registry

supportsInterface

function supportsInterface(bytes4 interfaceId)
    public
    view
    override(ERC721Upgradeable, EIP2981TLUpgradeable, IERC165)
    returns (bool);

_getBatchInfo

Function to get batch mint info

function _getBatchInfo(uint256 tokenId) internal view returns (address, string memory);

Parameters

NameTypeDescription
tokenIduint256Token id to look up for batch mint info

Returns

NameTypeDescription
<none>addressadress The token owner
<none>stringstring The uri for the tokenId

_ownerOf

Function to override { ERC721Upgradeable._ownerOf } to allow for batch minting

function _ownerOf(uint256 tokenId) internal view override(ERC721Upgradeable) returns (address);

_getMintedMetadataUri

internal function to get original metadata uri from mint

function _getMintedMetadataUri(uint256 tokenId) internal view returns (string memory uri);

_getMultiMetadataUri

internal function to help get metadata from multi-metadata struct

function _getMultiMetadataUri(MultiMetadata memory multiMetadata, uint256 index)
    internal
    view
    returns (string memory uri);

Parameters

NameTypeDescription
multiMetadataMultiMetadataThe multimMtadata struct in memory
indexuint256The index of the multiMetadataLoc

_exists

Function to check if a token exists

function _exists(uint256 tokenId) internal view returns (bool);

Parameters

NameTypeDescription
tokenIduint256The token id to check

_isTokenOwnerOrDelegate

Function to get if msg.sender is the token owner or delegated owner

function _isTokenOwnerOrDelegate(uint256 tokenId) internal view returns (bool);

_isOperatorBlocked

function _isOperatorBlocked(address operator) internal view returns (bool);

Errors

EmptyTokenURI

Token uri is an empty string

error EmptyTokenURI();

MintToZeroAddress

Mint to zero address

error MintToZeroAddress();

BatchSizeTooSmall

Batch size too small

error BatchSizeTooSmall();

AirdropTooFewAddresses

Airdrop to too few addresses

error AirdropTooFewAddresses();

CallerNotApprovedOrOwner

Caller is not approved or owner

error CallerNotApprovedOrOwner();

TokenDoesntExist

Token does not exist

error TokenDoesntExist();

InvalidTokenURIIndex

Index given for ERC-7160 is invalid

error InvalidTokenURIIndex();

NoTokensSpecified

No tokens in tokenIds array

error NoTokensSpecified();

NotOwnerAdminOrMintContract

Not owner, admin, or mint contract

error NotOwnerAdminOrMintContract();

CallerNotTokenOwnerOrDelegate

Caller is not the owner or delegate of the owner of the specific token

error CallerNotTokenOwnerOrDelegate();

OperatorBlocked

Operator for token approvals blocked

error OperatorBlocked();

StoryNotEnabled

Story not enabled for collectors

error StoryNotEnabled();

Structs

BatchMint

Struct defining a batch mint

struct BatchMint {
    address creator;
    uint256 fromTokenId;
    uint256 toTokenId;
    string baseUri;
}

MetadataLoc

Struct for specifying base uri index and folder index

struct MetadataLoc {
    uint128 baseUriIndex;
    uint128 folderIndex;
}

MultiMetadata

Struct for holding additional metadata used in ERC-7160

struct MultiMetadata {
    bool pinned;
    uint256 index;
    MetadataLoc[] metadataLocs;
}