I am trying to create an app that has two contracts and one contract needs to get the approval from the user to spend ERC20 tokens to another contract. While trying to create a hardhat unit test for it, I got stuck at below step.

await token.connect(contractA).approve(contractB, spendAmount);

The token is the ERC20 token here and the contractA and contractB are the contract instances created along the way of test.

The contractA needs to approve contractB to spend the token. While I understand that contractA is not the type of Signer, I need to figure out how to get the signer for/from it. Also the error I get obviously is as this.

Error: invalid signer or provider (argument="signerOrProvider",...

2 Answers 2


Contracts don't have private keys in EVM blockchains so they can't sign the transactions, as you said in first paragraph a contract needs a approval from user, so its the user who can approve the ERC20 tokens directly from ERC20 contract. But you are calling approve function of ERC20 from your contractA so its the contractA who calls the approve function not the user. You need to directly call the approve function form ERC20 contract.

  • ContractA you need to provide function to approve:

    function approveERC20(address token, address spender, uint256 amount) public onlyOwner {
       IERC20(token).approve(spender, amount);
  • Your test will be:

      await contractA.connect(signer).approveERC20(token, contractB.address, amount)
  • I tried to do the same, additionally ContractA would implement Ownable, but still getting below error: Error: invalid address or ENS name ... code=INVALID_ARGUMENT, version=contracts/5.7.0) Commented Dec 13, 2022 at 13:47
  • invalid address or ENS name that's mean input address not valid
    – 0xcuonghx
    Commented Dec 14, 2022 at 9:28

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.