Solidity – Testing safeTransferFrom with onlyAllowedOperator Using Chai/Hardhat

chaiethers.jshardhatsoliditytesting

I am writing tests for an NFT using safeTransferFrom with onlyAllowedOperator and the tests are failing with and without onlyAllowedOperator. Here's the function:

    function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        safeTransferFrom(from, to, tokenId);
    }

and here's the test:

  describe("ERC721: safeTransferFrom()", function () {

    it("safeTransferFrom(): Safe Transfer From owner to newOwner (address)", async function () {
      const { nft, owner, operator, newOwner, newOperator, minter } = await loadFixture(deployNFTFixture);

      await nft.mintTo(owner.address); // 1
      
      expect(await nft.balanceOf(owner.address)).to.equal(1);
      expect(await nft.balanceOf(newOwner.address)).to.equal(0);

      await nft.functions["safeTransferFrom(address,address,uint256)"](owner.address, newOwner.address, 1);

      expect(await nft.balanceOf(owner.address)).to.equal(0);
      expect(await nft.balanceOf(newOwner.address)).to.equal(1);

    });
  });

I am getting the following message when I run the test:

ERC721: safeTransferFrom()
         safeTransferFrom(): Safe Transfer From owner to newOwner (address) fails:
     Error: Transaction reverted and Hardhat couldn't infer the reason.
    at NFT.safeTransferFrom (contracts/NFT.sol:315)
    ...
    at NFT.safeTransferFrom (contracts/NFT.sol:315)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at runNextTicks (node:internal/process/task_queues:65:3)
    at listOnTimeout (node:internal/timers:526:9)
    at processTimers (node:internal/timers:500:7)
    at async HardhatNode._mineBlockWithPendingTxs (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1815:23)
    at async HardhatNode.mineBlock (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:504:16)
    at async EthModule._sendTransactionAndReturnHash (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1522:18)


I have no idea why the tokens are not being transferred.

Best Answer

I think you have to write this in your solidity file (add super.):

    function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator(from) {
        super.safeTransferFrom(from, to, tokenId);
    }

Otherwise the function looks like it's calling itself over and over.

Related Topic