ERC721 contracts with Smart Wallets Accounts

I am trying to interact with my smart contract using Argent Wallet on the zkSync-Era network. I'm trying to call safeMint() on an ERC721 contract, and each time it throws a cannot estimate gas error. This error is thrown when use ethers' estimateGas and when simply calling the function. If I call the function using Metamask, (EOA account) there is no issue, it works fine. I suspect that there may be an issue with the fact that Argent is smart wallet and thus the account used is Contract Account.

I further suspect that the problem lies with the _checkOnERC721Received, which is called by safeMint to verify the to parameter. Is the ERC721 contract compatible with smart-wallet addresses. My contract also uses access control. Are my suspicions correct?

Please note I have checked and double checked the obvious factors that would cause the cannot estimate gas error such as wrong types on inputs, and and other possible reverts in the code, and I have found nothing and as I said it works fine with Metamask.

Argent Wallet should be implementing onERC721Received to work as a receiver of safeMint. I'm pretty sure they implement it on Ethereum, but I don't know if their zkSync-Era contracts are the same. Do you know where to find the code that the wallet runs?

Please note that this behavior is standard ERC-721 behavior as described in the specification for safeTransferFrom, so there shouldn't be anything that is special about the implementation in OpenZeppelin Contracts.

I tested the function in my smart contract that is causing the problem and Argent wallet address throws the error, while when I call the function with all the same args but using an EOA account it works fine.

I modified my contract to use _mint() instead of _safeMint(), but I'm currently stuck and unable to deploy the contract due to the extremely high fees on the Goerli testnet. When things calm down, and I finally get it deployed I'll run the same test again. If the Argent Account throws an error again we will know that this isn't the issue.

As for the Argent Wallet code, I don't know. I checked quickly on github but didn't see anything.

The behavior may be standard but the OpenZepplin docs for _checkOnERC721Received state:

This is an internal detail of the ERC721 contract and its use is deprecated.

Where are you seeing this? This is not in the documentation for the latest version.


I see. This is an old version of the docs for v2.x. That comment just means that the function was deprecated and in future versions it was made private (not available to be called directly), but it is still used in the implementation.

I finally was able to deploy a new contract which uses _mint() in place of _safeMint() and I was able to mint a token for an Argent Wallet address. So we can conclude that this is a bug with Argent and they need to implement IERC721Receiver.onERC721Received in their wallet application.

Moreover, based on your previous comment, this is still being used in the implementation and so I should try and push Argent to included it in their wallet implementation.

1 Like