Here is my function, event and modifier:

event TransferComplete();     

modifier isApproved(address[] memory contractArr) {
    require(contractArr.length > 0, "Length Zero");
    for (uint256 i = 0; i < contractArr.length; i++) {
        address currAddr = contractArr[i];
        require(currAddr != zero, "Contract address is ZERO");
        bool isApproved = IERC721(currAddr).isApprovedForAll(_msgSender(), address(this));
        require(isApproved == true, "Not Approved");
function sendTokens(address[] memory contractAddrs, uint256[] memory tokenIds, address otherAddress) external isApproved(contractAddrs) {
    for (uint256 i = 0; i < contractAddrs.length; i++) {
        IERC721 tokenContract = IERC721(contractAddrs[i]);
        tokenContract.safeTransferFrom(_msgSender(), otherAddress, tokenIds[i]);
    emit TransferComplete;

The sendTokens function has isApproved modifier which checks if the contractAddrs being passed have approved my contract for transferring their ERC721 tokens. I setup a hardhat deploy script which deploys this contract on my hardhat node with mainnet fork, sets approvals for a NFT contract address, and then calls sendTokens function with approved contract address and a token ID. Everything works as expected and and I see the TransferComplete event in my transaction receipt.

The problem is that when I call the same sendTokens function from my React frontend using metamask, the transaction fails with a couple of different reasons. Console logs show that execution reverts on the IERC721(currAddr).isApprovedForAll line in the modifier during the first loop.

Most times the error is

Error: Transaction reverted without a reason string

But sometimes its also

Error: Transaction reverted: function selector was not recognized and there's no fallback function

I have double checked everything and tried various things but none worked. Here is what I tried which didn't work:

Verify if the ABI and Bytecode being generated by Hardhat runtime environment during deployment match the ones I'm importing in React frontend.
Set manual gasLimits
Use Ganache or Anvil instead of Hardhat node
Use Frame and Brave wallets to make sure its not a metamask issue
Verify that ethers version being used by Hardhat runtime environment is the same being used on the frontend
Deployed on Goerli, same results -> HRE function call succeeds but React one fails

Any insights would be helpful and appreciated. Thank you.

1 Answer 1


I was passing an incorrect address from UI but passing the correct address in the Hardhat script. Since the address being passed wasn't an ERC721 contract, the transaction was failing.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.