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.