5

I am using the OpenZeppelin framework and I've tried to find solutions on how to put a max supply of an ERC-721. The only answers I've found seems unnecessary complex and I haven't been able to make it work. It seems like there should be a simple solution to what seems like a simple problem. This is my current code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/[email protected]/token/ERC721/ERC721.sol";
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/[email protected]/access/Ownable.sol";

contract MyContract is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
    constructor() ERC721("MyContract", "MCT") {}

    function safeMint(address to, uint256 tokenId, string memory uri)
        public
        onlyOwner
    {
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }
}

It's a simple copy paste from the wizard on OpenZeppelin. The owner of the contract will be able to mint and burn tokens after deployment. But I still need to put a max supply to ensure scarcity of the NFTs.

Edit: It seems like I found a solution. It was pretty simple, just make the contract ERC721Enumerable and add require (totalSupply() < maxSupply); to the mint function. Maybe there's some problem with this but so far it seems to work when I test it:

    // SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/[email protected]/token/ERC721/ERC721.sol";
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/[email protected]/access/Ownable.sol";

contract MyToken is ERC721, ERC721Enumerable, ERC721URIStorage, ERC721Burnable, Ownable {
    constructor() ERC721("MyToken", "MTK") {}
    uint256 public constant maxSupply = 2;

    function safeMint(address to, uint256 tokenId, string memory uri)
        public
        onlyOwner
    {
        require (totalSupply() < maxSupply);
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    // The following functions are overrides required by Solidity.

    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}
1
  • You could use a counter and disable mint if it is above certain threshold.
    – Ismael
    Commented Jan 1, 2022 at 21:52

1 Answer 1

1

In my contracts, I use a require statement to check if the new mint count + totalSupply() does not exceed the MAX_SUPPLY that I arbitrarily set.

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.