Let's say we have this bit of code here

    function gift(address _account) external onlyOwner {

        if (totalSupply() + 1 > MAX_SUPPLY) {
            revert Contract__MintGiftExceeded();
        _safeMint(_account, (s_nftIdCounter).current());


I've noticed that in this function while we do not add the gifted NFT to totalSupply(), we only do counters.increment() , and totalSupply() still gets to know the total number of tokens.

So I have been wondering how does that actually work, how come totalSupply() doesn't fail to keep track of the total number of tokens.

  • Which openzepplin extension u inheriting in contract for ERC721 ?
    – 0xAnon
    Aug 30, 2022 at 11:27

2 Answers 2


Since you are using ERC721Enumberable, the change is taken care from ERC721Enumberable.sol _allTokens private variable, and not ERC777 as mentioned by my fellow user here. But yes _safeMint() is the one that is responsible to change the totalSupply() internally.

-> in ERC721.sol there is _safeMint which invokes _mint

-> _mint invokes _beforeTokenTransfer

-> now this _beforeTokenTransfer is virtual and is overriden by ERC721Enumberable contract

-> _beforeTokenTransfer invokes _addTokenToAllTokensEnumeration

-> _addTokenToAllTokensEnumeration invokes _allTokens.push(tokenId); pushes the token in the array

-> totalSupply() reads from _allTokens

  • 1
    Thank you for the answer, now it is even clearer, have a good day !
    – GiorgioDG
    Aug 30, 2022 at 11:58
  • Cheers fren. Happy to help!
    – 0xAnon
    Aug 30, 2022 at 12:00

The total supply will be updated in the _safeMint() function. In the openzeppelin implementation of the ERC777 that happens here.

  • Thank you ! now it is all clear
    – GiorgioDG
    Aug 30, 2022 at 11:34

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.