6

I didn't try yet, but let's suppose the following:

  • I have an ERC721 contract token with a total Supply of 101
  • My contract can mint and burn
  • The first token has id 0 and the last one has id 100
  • I burned the token with id 50.

Can I mint again the token with id 50?

2 Answers 2

5

An implementation which allows re-mint of a burned token will be considered a valid implementation of the ERC-721 standard. And in fact this functionality is described and possible with the reference implementation cited in the standard.

Also if you read that implementation it has notes about your specific question:

  /**
   * @dev Burns a NFT.
   * @notice This is a private function which should be called from user-implemented external burn
   * function. Its purpose is to show and properly initialize data structures when using this
   * implementation. Also, note that this burn implementation allows the minter to re-mint a burned
   * NFT.
   * @param _tokenId ID of the NFT to be burned.
   */
  function _burn(
  ...

Source: https://github.com/0xcert/ethereum-erc721/blob/ba888772931a62068d849b5a0e3fbd3aad3965e2/src/contracts/tokens/nf-token.sol#L360-L365

Further discussion on this topic is at https://github.com/0xcert/ethereum-erc721/issues/198

End result is that the reference implementation (https://github.com/0xcert/ethereum-erc721) has the main example, nf-token-mock.sol including a mint and not a burn because it could lead to confusing re-mint as you describe.

5

It depends on the implementation of your mint, burnToken, addToken and removeToken functions.

The ERC-721 pattern does not declare a mint function, in the same way that ERC-20 doesn't either. So, if your mint function requires that the token ID has not been used before, then the answer to your question is "no". Otherwise, it's probably "yes, just be careful".

Following the links in ERC721.org, you'll find this basic implementation. Go to line 371 there and you'll see something like this:

function _mint(address _to, uint256 _tokenId) internal {
    require(_to != address(0));
    _addToken(_to, _tokenId);
    Transfer(0x0, _to, _tokenId);
}

So, in this case, it appears that you can mint it again because it only requires that to is not address(0). But in line 410 we get this:

function _addToken(address _to, uint256 _tokenId) private {
    require(tokenOwner[_tokenId] == address(0));
    tokenOwner[_tokenId] = _to;
    uint256 length = balanceOf(_to);
    ownedTokens[_to].push(_tokenId);
    ownedTokensIndex[_tokenId] = length;
    totalTokens = totalTokens.add(1);
}

The require there guarantees the token has no owner in that moment. And that leads us to the burn and removeToken implementations. There's no burnToken function in this example, but note that the IS a removeToken().

function _removeToken(address _from, uint256 _tokenId) private {
    require(ownerOf(_tokenId) == _from);

    uint256 tokenIndex = ownedTokensIndex[_tokenId];
    uint256 lastTokenIndex = balanceOf(_from).sub(1);
    uint256 lastToken = ownedTokens[_from][lastTokenIndex];

    tokenOwner[_tokenId] = 0;
    ownedTokens[_from][tokenIndex] = lastToken;
    ownedTokens[_from][lastTokenIndex] = 0;
    ownedTokens[_from].length--;
    ownedTokensIndex[_tokenId] = 0;
    ownedTokensIndex[lastToken] = tokenIndex;
    totalTokens = totalTokens.sub(1);
  }

It effectively sets the owner of that token to 0 and clears all references. If you follow that implementation and call removeToken inside you burnToken function, that token ID will belong to no one after being burned. And in that case, the answer to your question is YES, you can mint a token that has been burned before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.