EIP712 Verification Failed

eip712 sign verification is failing. help me to fix it.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";

contract NewToken is ERC20, Ownable, ERC20Permit {
    constructor() ERC20("NewToken", "NT") ERC20Permit("NewToken") {
        _mint(msg.sender, 1000 * 10 ** decimals());
    }

    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }

    function chainId() external view returns (uint256) {
        return block.chainid;
    }
}

test script

const { expect } = require("chai");
const ethSigUtil = require("eth-sig-util");
const Wallet = require("ethereumjs-wallet").default;
const NewToken = artifacts.require("NewToken");
const { BN, constants } = require("@openzeppelin/test-helpers");
const { fromRpcSig } = require("ethereumjs-util");
const fs = require("fs");

contract("NewToken", function (accounts) {
  const [initialHolder, spender] = accounts;
  beforeEach(async function () {
    this.token = await NewToken.new();
  });
  it("accepts owner signature", async function () {
    const nonce = await this.token.nonces(initialHolder);
    const value = new BN(42);
    const wallet = Wallet.generate();
    const owner = wallet.getAddressString();
    const chainId = parseInt((await this.token.chainId()).toString());
    let data = {
      primaryType: "Permit",
      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" },
        ],
      },
      domain: {
        name: "My Token",
        version: "1",
        chainId,
        verifyingContract: this.token.address,
      },
      message: {
        owner,
        spender,
        value,
        nonce,
        deadline: constants.MAX_UINT256,
      },
    };
    const signedVal = ethSigUtil.signTypedMessage(wallet.getPrivateKey(), {
      data,
    });
    const { v, r, s } = fromRpcSig(signedVal);
    await this.token.permit(owner, spender, value, constants.MAX_UINT256, v, r, s);
    expect(await this.token.nonces(owner)).to.be.bignumber.equal('1');
  });
});

I am getting the following error while running the above test script,

     Error: VM Exception while processing transaction: reverted with reason string 'ERC20Permit: invalid signature'
    at NewToken.permit (@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol:65)
    at TruffleContract.permit (node_modules/@nomiclabs/truffle-contract/lib/execute.js:189:26)
    at Context.<anonymous> (test/NewToken.js:55:22)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Repo UR: https://github.com/selvaraman/exploring-eip712

Your JavaScript snippet says name: "My Token" but your Solidity code is setting name to be "NewToken".

1 Like