ERROR: Transaction reverted by EVM

Hey, I’m using the permit function to give approval to an specified amount of tokens with signature. I get the split r, s and v values from the signature, and I then execute my permit function from back-end with a transaction and a private key. Here’s the problem, when sending the signed transaction to the net, it will suddenly throw out an error: Transaction reverted by EVM. When I go to the transaction hash on etherscan, it says that it got out of gas. Strange thing here, is that I double the estimated gas fees, so it shouldn’t run out of gas. Sometimes the transaction itself doesn’t even use all the gas but just throws out that error.
PS: I tried on remix with ropsten net and it didn’t throw out that error.

Here’s an example:
The gas that I have given is 58200, but it only uses 23280 (see screenshot).
The transaction hash:
https://etherscan.io/tx/0x7f0b702bd886f13ff50f4afb7c8b98626227b4be884fdfa4870449cfb28f3012.


Code for executing the permit:

async function makePermit() {
    try {
        const contract = new web3.eth.Contract(erc20ABI, contractAddress);
        const permit = await contract.methods.permit(account, receiverAddress, 1000, 1988064000, v, r, s); 

        let gasAmount = 23280; //Default value
        const estimatedGasOption = web3.eth.estimateGas({
            from: receiverAddress,
            to: account,
            data: permit.encodeABI(),
        }).then(function(ga) {
            gasAmount = ga * 2.5;
            console.log(gasAmount);
        });
        
        const tx = {
            from: receiverAddress,
            to: contractAddress,
            data: permit.encodeABI(),
            gas: gasAmount,
            gasPrice: await web3.eth.getGasPrice()
        };

        const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey);
        console.log(signedTx);
        const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction); // error is thrown here
        console.log(receipt);    
    } catch (error) {
        console.log(error);
    }
}

Could this be something that influence the error?

  • Wrong r,s and v values
  • Something is wrong when creating the permit message to sign it.

About permit: https://eips.ethereum.org/EIPS/eip-2612
Thanks for your support!

EDIT: I found the problem but don’t know how to solve it, gas is fine, but the values that are used are wrong.

What could be wrong here?

const domain = {
  name: domainName,
  version: domainVersion,
  chainId: chainId,
  verifyingContract: temp,
}

const domainType = [
  { name: 'name', type: 'string' },
  { name: 'version', type: 'string' },
  { name: 'chainId', type: 'uint256' },
  { name: 'verifyingContract', type: 'address' },
]

const splitSig = (sig) => {

  const sign = ethers.utils.splitSignature(sig);
 
  r = sign.r;
  s = sign.s;
  v = sign.v;

  return {
    r, s, v
  }
}

const signTyped = (dataToSign) => {
  return new Promise((resolve, reject) => {
    web3.currentProvider.sendAsync({
      method: "eth_signTypedData_v4",
      params: [account, dataToSign],
      from: account
    }, (err, result) => {
      if (err) return reject(err);
      resolve(result.result)
    })
  })
}

async function createPermit(spender, value, nonce, deadline) {
  const permit = { owner: account, spender, value, nonce, deadline }
  const Permit = [
    { name: "owner", type: "address" },
    { name: "spender", type: "address" },
    { name: "value", type: "uint256" },
    { name: "nonce", type: "uint256" },
    { name: "deadline", type: "uint256" },
  ]
  
  const dataToSign = JSON.stringify({
      types: {
          EIP712Domain: domainType,
          Permit: Permit
      },
      domain: domain,
      primaryType: "Permit",
      message: permit
  });

  const signature = await signTyped(dataToSign)
  const split = splitSig(signature)

  return {
    ...split, signature
  }
}

I then run it with: const permit = await createPermit(receiverAddress, 1000, nonce , 1988064000)

what are the values that are wrong?

r,s and v values I think, I don’t know why they would be wrong tho…
Has the domain name to be the same or can I change that? Domain version is set on 1 but does this depend on the token?

I don’t know exactly, I’m not familiar with this protocol