Approval failing when trying to send ERC721 to contract?

Hello!

I am trying to send an ERC721 token to another contract that will hold the token (a bidding contract).

I am able to mint a token fine, and I can even create the other contract.

However, I am having a lot of trouble trying to figure out how to extract/get the tokenID (for testing).

:computer: Environment Truffle, Solidity 0.6.0, OpenZeppelin 3.4.

:1234: Code to reproduce
Here is what my contract looks like:

contract MarketPlace is IERC721Receiver {

    MarketPlace public nftContract;

    struct Auction {
        // Current owner of NFT
        address seller;
        // Price (in wei) of NFT
        uint128 price;
        // Time when the auction started
        // NOTE: 0 if this auction has been concluded
        uint64 startedAt;
    }
    event NFTForSale(address _nftAddress);

    mapping (uint256 => Auction) public tokenIdToAuction;

    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {
        return this.onERC721Received.selector;
    }

    constructor(address _nftAddress) public { 
        require(_nftAddress != address(0) && _nftAddress != address(this));
        nftContract = ERC721(_nftAddress);
        emit NFTForSale(_nftAddress);
    }
    

    function createAuction(uint256 _tokenId, uint256 _price, address _seller) external {
        require(msg.sender == address(nftContract));

        Auction memory _auction = Auction(
            _seller,
            uint128(_price),
            uint64(now)
        );
		tokenIdToAuction[_tokenId] = _auction;
        emit NFTForSale(_seller);
    }
}

And the ERC721 is the standard inherit from openzeppelin 721. No fucntions overwritten, etc.

Currently, I am trying to write some tests as follows:
describe(“Instance methods”, () => {

    let tokens;

    before(async () => {

      nft = await Erc721.new();

      auctionContract = await TokenAuction.new(nft.address);

      await nft.createContent(accounts[1], "test");

     // getTotal = await nft.balanceOf(accounts[1]); <-- gets all the tokens owned by account, returns "1"

      // tokens = await nft.tokenOfOwnerByIndex(accounts[1], getTotal ); <-- out of bounds error... 
       Cannot seem to get working even by the index to the tokens index (0/1/2/etc)

      await nft.approve(auctionContract.address, 0); <-- throws error even with above lines commented out and token ID manually inputted (tokenID = 0). 

    });

I’m really stumped here. I need to send the contract the tokenID to create an auction, but I have no idea how!!!

Any help is greatly appreciated.

1 Like

Hi @Routaruo,

Welcome to the community :wave:

I would have expected the following to work with an index of zero, assuming that createContent calls _mint.

tokens = await nft.tokenOfOwnerByIndex(accounts[1], getTotal ); <-- out of bounds error... 

From the documentation: https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#IERC721Enumerable-tokenOfOwnerByIndex-address-uint256-

You can use the OpenZeppelin Contracts tests as examples:

As an aside, I suggest looking at using OpenZeppelin Contracts 4 ERC721 implementation as enumerability is no longer included by default: https://blog.openzeppelin.com/openzeppelin-contracts-4-0/