I am trying to implement ERC-2981 in a ERC-721A contract. The below code compiles and deploys fine. After a test mint, the transaction overview seems fine:

enter image description here

However, the token tracker shows no transfers, no holders, and indicates an ERC-20 token:

enter image description here

The tokens also do not show up on opensea rinkeby. After setting up default royalties, ERC-2981 shows up correctly on https://royaltyregistry.xyz/, however.

I have tested this contract without ERC-2981 and it works fine without the above problem. I have also tested this contract without ERC-2981 but left the override of the supportsInterface function (only overriding ERC-721A in this case) in there, and it seems to work fine as well.

See https://etherscan.io/address/0x466cfcd0525189b573e794f554b8a751279213ac#code for a similar implementation of a well known project that seems to be working fine.

What's the problem here? Is it just an indexing matter? I am new to coding smart contracts, so forgive me in case the answer is trivial.

Thanks a lot, cheers

Edit: https://rinkeby.etherscan.io/address/0x0a75259419639e20bc85f785682de51689fd717b

    // SPDX-License-Identifier: MIT

    pragma solidity ^0.8.7;

    import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
    import "@openzeppelin/contracts/access/Ownable.sol";
    import "@openzeppelin/contracts/token/common/ERC2981.sol";
    import "erc721a/contracts/ERC721A.sol";

    contract SimpleContract is ERC721A, ERC2981, Ownable, ReentrancyGuard {

        uint256 public constant MAX_SUPPLY = 10000;
        uint256 public constant MAX_MINTS_WALLET = 1;

        string private _baseTokenURI;

        bool public isSaleOpen;

        mapping (address => uint256) public totalMints;

        constructor(string memory tokenData) ERC721A("Simple Contract", "SICO") {
            _baseTokenURI = tokenData;

        function toggleSaleOpen() external onlyOwner {
            isSaleOpen = !isSaleOpen;

        modifier callerIsUser() {
            require(tx.origin == msg.sender, "Cannot be called by a contract");

        function freeMint() external callerIsUser nonReentrant {
            require(isSaleOpen, "Sale not open");
            require(MAX_SUPPLY > totalSupply(), "Sold out");
            require((totalMints[msg.sender]) < MAX_MINTS_WALLET, "Only one free mint per wallet");
            _safeMint(msg.sender, 1);
            totalMints[msg.sender] += 1;

        function _baseURI() internal view virtual override returns (string memory) {
            return _baseTokenURI;

        function withdraw() external onlyOwner nonReentrant {
            (bool success, ) = msg.sender.call{value: address(this).balance}("");
            require(success, "Transfer failed");

        // ERC2981 functions

        // @dev Required override
        function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, ERC2981) returns (bool) {
            return super.supportsInterface(interfaceId);

        function setDefaultRoyalty(address receiver, uint96 feeNumerator) external onlyOwner {
            _setDefaultRoyalty(receiver, feeNumerator);

        function deleteDefaultRoyalty() external onlyOwner {
  • What's the contract address? In any case Etherscan is a closed source block explorer so it may takes some time for information to propagate.
    – Ismael
    Commented Jul 6, 2022 at 17:02
  • rinkeby.etherscan.io/address/…
    – user104179
    Commented Jul 6, 2022 at 18:37
  • Time doesn't seem to be the matter as I have been testing this for days, and all tests that include ERC-2981 still don't show up correctly in the token tracker view.
    – user104179
    Commented Jul 7, 2022 at 9:07
  • Usually etherscan doesn't update frequently testnets, rinkeby, ropsten, ... Sometime even important features are missing. You could try asking directly to their customer support.
    – Ismael
    Commented Jul 11, 2022 at 17:55

1 Answer 1


I was experiencing the same issue recently which was mystifying; but it looks like this is a breaking change in V4 of ERC721A - ERC721A no longer has OpenZeppelin support, and so as per https://chiru-labs.github.io/ERC721A/#/migration?id=supportsinterface, in order to support this now, you need to rewrite the supportsInterface function as follows:

function supportsInterface(
    bytes4 interfaceId
) public view virtual override(ERC721A, ERC2981) returns (bool) {
    // Supports the following `interfaceId`s:
    // - IERC165: 0x01ffc9a7
    // - IERC721: 0x80ac58cd
    // - IERC721Metadata: 0x5b5e139f
    // - IERC2981: 0x2a55205a
        ERC721A.supportsInterface(interfaceId) || 

Some more details here: https://github.com/chiru-labs/ERC721A/issues/304

Your Answer

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