I have simple ERC721 contract which is successfully deployed and some of the NFT's are minted but when i call


I receive this error:

 uint256 :  Error: Returned error: execution reverted

Any idea how to handle it? Here is some additional source:

balanceOf function:

function balanceOf(address collectionAddress) external view returns(uint256) {
    return MyERC721(collectionAddress).balanceOf(msg.sender);

MyERC721 contract:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract MyERC721 is ERC721 {
  address owner;

  constructor(string memory name_, string memory symbol_, address owner_) ERC721(name_, symbol_) { 
    owner = owner_;

  function safeMint(address to, uint256 tokenId) external {
    require(msg.sender == owner, "NOT_OWNER");

    _safeMint(to, tokenId, "");

  function safeMint(address to, uint256 tokenId, bytes memory data) external {
    require(msg.sender == owner, "NOT_OWNER");
    _safeMint(to, tokenId, data);

and i can see balance is 1 in etherscan:

enter image description here

CollectionManager source:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.9;

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";

import "./MyERC721.sol";
import "./interfaces/ICollectionManager.sol";

contract CollectionManager is ICollectionManager {
  // Collection[] public allCollections;
  mapping(address => address[]) public collectionsOf;
  mapping(address => Collection) public collection;
  function createCollection(string memory name, string memory symbol) external {
    MyERC721 newCollection = new MyERC721(name, symbol, address(this));
    address collectionAddress = address(newCollection);
    address sender = msg.sender;

    collection[collectionAddress].status = Status.Inactive;
    collection[collectionAddress].owner = sender;
    // allCollections.push(collection[collectionAddress])

    emit CollectionCreated(sender, collectionAddress, block.timestamp);

  function setCollectionActive(address collectionAddress) external {
    collection[collectionAddress].status = Status.Active;

    emit CollectionActivated(collectionAddress, block.timestamp);

  function mint(address collectionAddress) external {
    uint256 tokenId = collection[collectionAddress].tokenIdCounter + 1;

    collection[collectionAddress].tokenIdCounter = tokenId;
    MyERC721(collectionAddress).safeMint(msg.sender, tokenId);

  function balanceOf(address collectionAddress) external view returns(uint256) {
    return MyERC721(collectionAddress).balanceOf(msg.sender);

  function totalSupply(address collectionAddress) external view returns(uint256) {
    return ERC721Enumerable(collectionAddress).totalSupply();

2 Answers 2


If your MyERC721 inherits from open-zeppelins ERC721 you don't have to override balanceOf function yourself. The implementation works out-of-the-box and is like this:

function balanceOf(address owner) public view virtual override returns (uint256) {
    require(owner != address(0), "ERC721: balance query for the zero address");
    return _balances[owner];

The issues with your code is, that you are recursively calling the same function again and again. And btw you are passing an user address (msg.sender), but you are using the address as collection address. Try to delete your implementation of balanceOf and you should be fine.

  • yeah but my CollectionManager do not inherit MyERC721 instead of that does multiple collections, here is the code: pastebin.com/tfg3kdUr Oct 20, 2021 at 8:34
  • Are you using hardhat or truffle? Try to debug the reverting tx, it could help you find the error.
    – ashhanai
    Oct 20, 2021 at 10:35
  • Im using hardhat yes Oct 20, 2021 at 10:55
  • But i do txs in etherscan not sure how to debug it from there ;s Oct 20, 2021 at 11:22
  • Basically i Have MyERC721 which overrides safemint and then i do multiple NFT collections using MyERC721 and when trying to get balance MyERC721(address).balanceOf(msg.sender) throws error Oct 20, 2021 at 11:27

Way too old and probably solved ages ago, but your issue is that you're using msg.sender, you should never do that for view functions because unless you specify it explicitely in the code that calls the function, msg.sender is gonna be the 0 address. You should be doing something like this instead :

function balanceOf(address collectionAddress, address user) external view returns(uint256) {
    return MyERC721(collectionAddress).balanceOf(user);

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.