Search code examples
javascriptethereumsolidityetherscanmatic

Why is polygon mumbai giving error when trying to verify contract code?


I have tried using truffle, hardhat, alchemy and remix to do various methods of flattening then verifying or trying to verify using polygon API endpoints but all of them result in the same error:

https://mumbai.polygonscan.com/address/0x520efcceabec19294305930012b86c2712f8c79d

Compiler debug log: Error! Unable to generate Contract ByteCode and ABI Found the following ContractName(s) in source code : Address, Context, Counters, ERC165, ERC721, ERC721Burnable, ERC721Enumerable, ERC721URIStorage, IERC165, IERC721, IERC721Enumerable, IERC721Metadata, IERC721Receiver, Ownable, Strings, VurgeGarage But we were unable to locate a matching bytecode (err_code_2) For troubleshooting, you can try compiling your source code with the Remix - Solidity IDE and check for exceptions

The following is what my smart contract looks like:

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract VurgeGarage is ERC721, ERC721Enumerable, ERC721URIStorage, ERC721Burnable, Ownable {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("VurgeGarage", "VRG") {}

    function _baseURI() internal pure override returns (string memory) {
        return "";
    }

    function mint(address _to, string memory _uri) public onlyOwner {
        safeMint(_to, _uri);
    }

    function safeMint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _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);
    }
}

My hardhat.config.js file:

/**
* @type import('hardhat/config').HardhatUserConfig
*/

require('dotenv').config();
require("@nomiclabs/hardhat-ethers");


const { MUMBAI_API_URL, MUMBAI_PRIVATE_KEY, POLYGONSCAN_API_KEY } = process.env;

module.exports = {
   solidity: "0.8.9",
   defaultNetwork: "polygon_mumbai",
   networks: {
      hardhat: {},
      polygon_mumbai: {
         url: MUMBAI_API_URL,
         accounts: [`0x${MUMBAI_PRIVATE_KEY}`]
      }
   },
   etherscan: {
      apiKey: POLYGONSCAN_API_KEY
   }
}

To deploy the contract I called which returned the contract address:

async function main() {
    const VurgeGarage = await ethers.getContractFactory("VurgeGarage");
 
    // Start deployment, returning a promise that resolves to a contract object
    const vurge_garage = await VurgeGarage.deploy();   
    console.log("Contract deployed to address:", vurge_garage.address);
 }
 
 main()
   .then(() => process.exit(0))
   .catch(error => {
     console.error(error);
     process.exit(1);
   });

Since the flattened contract is over 1,000 lines of code I have not included it. But regardless if I use truffle-flattener or Remix IDE to flatten my contract, the failure to verify still occurs.

One thing I have considered is that I have a migrations.sol contract as well that looks like:

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract Migrations {
  address public owner = msg.sender;
  uint public last_completed_migration;

  modifier restricted() {
    require(
      msg.sender == owner,
      "This function is restricted to the contract's owner"
    );
    _;
  }

  function setCompleted(uint completed) public restricted {
    last_completed_migration = completed;
  }
}

When I originally uploaded and verified this contract to Ropsten.Etherscan I did not have to touch the migrations file but could that be a problem when uploading to mumbai?


Solution

  • I updated solidity version on both hardhat config and my contract. Both files should have the same version.

    and I verified on my deployment script like this:

    import { ethers, upgrades,run } from "hardhat";
     await run("verify:verify", {
       address: myTokenV1.address,
       constructorArguments: [],
     });