"Invalid signature" error in ERC20Permit (EIP2612)

Hey, I’m using permit for approval via signatures for ERC20 Tokens, I need to execute the permit function from the back-end, I created a transaction but got “Invalid signature”. Permit is called from ERC20 contract ABI.
Here’s my code:

async function makePermit() {
	const contract = new web3.eth.Contract(erc20ABI, contractAddress);
	const privateKey = "";
	const privateAccount = web3.eth.accounts.privateKeyToAccount(privateKey);
	
	const permit = await contract.methods.permit(account, receiverAddress, 1000, 1988064000, 27, r, s);
	

	const tx = {
		from: privateAccount.address,
		to: account,
		data: permit.encodeABI(),
		gas: await permit.estimateGas({ from: privateAccount.address }),
		gasPrice: await web3.eth.getGasPrice()
	};

	const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey);
	const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
	console.log(receipt);	
}

To split my signature I use this:

  const pureSig = sig.replace("0x", "")
  r = new Buffer.from(pureSig.substring(0, 64), 'hex')
  s = new Buffer.from(pureSig.substring(64, 128), 'hex')
  v = new Buffer.from((parseInt(pureSig.substring(128, 130), 16)).toString());

Error screenshot:

Any thoughts? Thanks.

maybe you can compare that data content with an example that already works to see what is different

Yeah been searching for some examples but didn’t found any!

maybe you can find a transaction on chain specific to that EIP

Update: the problem doesn’t come from the split signature values, values are correct.

Still searching since a couple of days, starting to lose hope. If anyone has an idea, please share it.

any idea now? ???

1 Like

Yes I fixed it. It works fine.

1 Like

Can you please share how you managed to fix this, am experiencing same issue while using ethers.js and domain, types, message from @1inch/permit-signed-approvals-utils
also tried with pure js without that sdk and same result, cant get it to work somehow, splitting signature using const {v,r,s} = ethers.utils.splitSignature so cant be signature splitting issue

data_to_sign = JSON.stringify({
    "types": {
        "EIP712Domain": [
            {
                "name": "name",
                "type": "string"
            },
            {
                "name": "version",
                "type": "string"
            },
            {
                "name": "chainId",
                "type": "uint256"
            },
            {
                "name": "verifyingContract",
                "type": "address"
            }
        ],
        "Permit": [
            {
                "name": "owner",
                "type": "address"
            },
            {
                "name": "spender",
                "type": "address"
            },
            {
                "name": "value",
                "type": "uint256"
            },
            {
                "name": "nonce",
                "type": "uint256"
            },
            {
                "name": "deadline",
                "type": "uint256"
            }
        ]
    },
    "primaryType": "Permit",
    "domain": {
        "name": "USD Coin",
        "verifyingContract": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
        "chainId": 1,
        "version": "1"
    },
    "message": {
        "owner": owner,
        "spender": spender,
        "value": 10000,
        "nonce": 0,
        "deadline": 1992689033
    }
})
var params = [owner, dataToSign]
      const signature = await window.ethereum.request({"eth_signTypedData_v4", params, address}, 
        function (err, result) {
          if (err) return console.dir(err)
          if (result.error) {
            handleError({message: result.error})
          }
        })

      const { v,r,s } = ethers.utils.splitSignature(signature)

but after trying to execute on chain permit with all the gained values, it says invalid signature

There is a syntax issue here with the request object (and a few more after this):

const signature = await window.ethereum.request({"eth_signTypedData_v4", params, address}, 

Can you post your full code that you’re using?

Hey, try setting “version” to 2 instead of 1 in your domain section, since usdc is on version 2 this should fix the problem. (This worked for me)
PS: I think you should first follow what @glad said, since what he said can cause problems too.

yea, lol that was actually the whole issue, ty

1 Like