ethereumblockchainsmartcontractsmetamaskdecentralized-applications

Error: missing revert data (action="estimateGas", data=null, reason=null, transaction


I'm creating a Dapp that let's a user mint an NFt then list it for sell.this is my ERC721 contract

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

// Uncomment this line to use console.log
// import "hardhat/console.sol";

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

contract Collections is ERC721, ERC721URIStorage,ERC721Enumerable {
    uint256 public _nextTokenId;

    

    constructor()
        ERC721("Colletcion", "CCC")
        
    {}

    function safeMint(address to, string memory uri) public{
        uint256 tokenId = _nextTokenId++;
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
       

    }

    // The following functions are overrides required by Solidity.

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

  // The following functions are overrides required by Solidity.

    function _update(address to, uint256 tokenId, address auth)
        internal
        override(ERC721, ERC721Enumerable)
        returns (address)
    {
        return super._update(to, tokenId, auth);
    }

    function _increaseBalance(address account, uint128 value)
        internal
        override(ERC721, ERC721Enumerable)
    {
        super._increaseBalance(account, value);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721URIStorage, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}


And here is my Market.sol

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

import "hardhat/console.sol";

interface IERC721 {
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function transferFrom(address from, address to, uint256 tokenId) external;
    function ownerOf(uint256 tokenId) external view returns (address);
}

contract Marketplace {
    IERC721 public token;
    address public admin;

    event NFTListed(uint256 indexed tokenId, address indexed owner, uint256 price);
    event NFTSold(uint256 indexed tokenId, address indexed buyer, uint256 price);
    event NFTCanceled(uint256 indexed tokenId, address indexed owner);

    constructor(address _nftAddress, address _admin) {
        require(_nftAddress != address(0), "Invalid NFT address");
        require(_admin != address(0), "Invalid admin address");
        token = IERC721(_nftAddress);
        admin = _admin;
    }

    struct NFT {
        address owner;
        uint256 price;
        bool sold;
    }

    mapping(uint256 => NFT) public nfts;
    bool private locked = false;

    modifier onlyOwner(uint256 _tokenId) {
        require(token.ownerOf(_tokenId) == msg.sender, "Not the owner");
        _;
    }

    modifier onlyAdmin() {
        require(msg.sender == admin, "Not the admin");
        _;
    }

    modifier nonReentrant() {
        require(!locked, "Reentrant call");
        locked = true;
        _;
        locked = false;
    }

    function listNFT(uint256 _tokenId, uint256 _price) external onlyOwner(_tokenId) {
        require(_price > 0, "Price must be greater than zero");

        // Transfer the NFT from the owner to the marketplace contract
        token.transferFrom(msg.sender, address(this), _tokenId);

        // List the NFT
        nfts[_tokenId] = NFT(msg.sender, _price, false);

        emit NFTListed(_tokenId, msg.sender, _price);
    }

    function buyNFT(uint256 _tokenId) external payable nonReentrant {
        NFT storage nft = nfts[_tokenId];
        require(!nft.sold, "NFT already sold");
        require(nft.price == msg.value, "Incorrect price");
        require(nft.owner != msg.sender, "Cannot buy your own NFT");

        nft.sold = true;
        address seller = nft.owner;

        // Transfer the NFT from the marketplace contract to the buyer
        token.safeTransferFrom(address(this), msg.sender, _tokenId);

        // Transfer the payment to the seller
        payable(seller).transfer(msg.value);

        emit NFTSold(_tokenId, msg.sender, msg.value);

        // Remove the NFT from the listings
        delete nfts[_tokenId];
    }

    function cancelNFT(uint256 _tokenId) external onlyAdmin {
        NFT storage nft = nfts[_tokenId];
        require(!nft.sold, "NFT already sold");

        // Transfer the NFT back to the owner
        token.safeTransferFrom(address(this), nft.owner, _tokenId);

        emit NFTCanceled(_tokenId, nft.owner);

        // Remove the NFT from the listings
        delete nfts[_tokenId];
    }

    function getNFT(uint256 _tokenId) external view returns (NFT memory) {
        return nfts[_tokenId];
    }
}

And that is how i'm calling it in my frontend

const list = async (id: string, price: string) => {
    try {
      const signer = await provider.getSigner();
      const nftContract = contract.connect(signer);
      const marketContract = market.connect(signer);
      const marketplaceAddress = import.meta.env
        .VITE_MARKETPLACE_CONTRACT_ADDRESS;
      const tokenId = id;
      const priceInWei = price;

      // Check if the NFT is already approved for the marketplace contract
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      //@ts-ignore
      const currentApproval = await nftContract.getApproved(tokenId);
      if (currentApproval.toLowerCase() !== marketplaceAddress.toLowerCase()) {
        // Approve the marketplace contract to transfer the NFT
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        //@ts-ignore
        const approvalTx = await nftContract.approve(
          marketplaceAddress,
          tokenId
        );
        await approvalTx.wait(1);
      }

      // List the NFT on the marketplace
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      //@ts-ignore
      const listTx = await marketContract.listNFT(tokenId, priceInWei);

      console.log("NFT listing transaction:", listTx.hash);
    } catch (error) {
      console.error("Error listing NFT:", error);
    }
  };

I'm getting these errors

MetaMask - RPC Error: Internal JSON-RPC error. 
data
: 
{hash: null, programCounter: 2492, result: '0x', reason: null, message: 'revert'}
message
: 
"VM Exception while processing transaction: revert"
name
: 
"RuntimeError"
stack
: 
"RuntimeError: VM Exception while processing transaction: revert\n    at exactimate (C:\\Program Files\\WindowsApps\\GanacheUI_2.7.1.0_x64__rb4352f0jd4m2\\app\\resources\\static\\node\\node_modules\\ganache\\dist\\node\\1.js:2:182136)"
[[Prototype]]
: 
Object
message
: 
"Internal JSON-RPC error."

And this one

Table.tsx:103 Error listing NFT: 
Error: missing revert data (action="estimateGas", data=null, reason=null, transaction={ "data": "0x94383f1400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000013", "from": "0xE8495F857774bB61647f280e0FB87987B3A18e3B", "to": "0x453BEF367C09Bd01c6411c747058b1955338B135" }, invocation=null, revert=null, code=CALL_EXCEPTION, version=6.13.0)
    at makeError (ethers.js?v=f8fb06fb:325:15)
    at getBuiltinCallException (ethers.js?v=f8fb06fb:11863:10)
    at _AbiCoder.getBuiltinCallException (ethers.js?v=f8fb06fb:11934:12)
    at BrowserProvider.getRpcError (ethers.js?v=f8fb06fb:19084:26)
    at BrowserProvider.getRpcError (ethers.js?v=f8fb06fb:21502:18)
    at ethers.js?v=f8fb06fb:19272:27

Why am i getting these errors

first i was testing using hardhat network with metamask i tried to switch to ganache that didn't work


Solution

  • The mistake that led to this error was that I was deploying the marketplace contract with parameters misplaced