ERC20 Permit Call

Hey everyone! Hope all is well.

Im in the process of trying to call the permit() function on the DAI contract, however i'm running into a error: "Fail with error 'Dai/invalid-permit".

This is my code:

const { ethers, BigNumber } = require("ethers");
const ABI = require("./abi.json");

const permittee = "0xE592427A0AEce92De3Edee1F18E0157C05861564"; // Address you will be signing allowance for - i.e., wallet, contract like Uniswap SwapRouter

const PRIVATE_KEY = "YOUR_PRIVATE_KEY"; // The Private key 
const CONTRACT_ADDRESS = "0x11fE4B6AE13d2a6055C8D9cF65c55bac32B5d844"; // The Contract that you will call permit() on
const RPC_URL = "YOUR_RPC_URL"; // The RPC Provider URL

const provider = new ethers.providers.StaticJsonRpcProvider(RPC_URL)
const signer = new ethers.Wallet(PRIVATE_KEY, provider)

// Value of tokens to be sent
let value = ethers.utils.parseEther("0.1");

// Unix timestamp for deadline
let deadline = getTimestampInSeconds() + 3200;

function getTimestampInSeconds () {
    return Math.floor( / 1000)

async function main() {

    // Get Chain ID
    const chainId = (await provider.getNetwork()).chainId

    // Initialize contract
    const Token = new ethers.Contract(CONTRACT_ADDRESS, ABI, signer)

    // Get nonce from contract
    const nonce = await Token.nonces(signer.address)

    // Get Contract name
    const name = await
    // Value of tokens to be sent
    const value = ethers.utils.parseEther("0.1");
    // Unix timestamp for deadline
    const deadline = getTimestampInSeconds() + 3200;

    // Define Signature
    const domain = {
        name: name,
        version: "1",
        verifyingContract: Token.address,
        chainId: chainId,

    // Define types
    const types = {
        Permit: [
            {name: "owner", type: "address"},
            {name: "spender", type: "address"},
            {name: "nonce", type: "uint256"},
            {name: "deadline", type: "uint256"},
            {name: "value", type: "uint256"},

    // Define transaction
    const values = {
        owner: signer.address,
        spender: permittee,
        nonce: nonce,
        deadline: deadline,
        value: value,

    // Sign data
    const signature = await signer._signTypedData(domain, types, values);

    // Split signature
    const sig = ethers.utils.splitSignature(signature);

    // Check signature
    let recovered = ethers.utils.verifyTypedData(

    // Get recent gas price
    const gas = await (await provider.getGasPrice()).toString()

    // Call permit
    console.log('Call permit()');

    let num = BigNumber.from(10000000000000)

    let tx = await Token.permit(signer.address, permittee, nonce, num, true, sig.v, sig.r, sig.s, {
        gasPrice: gas,
        gasLimit: 50000

    console.log(`Transaction hash: ${tx.hash} - Waiting for confirmation`)

    // Wait n blocks for confirmation
    await tx.wait(3);

    // Check allowance
    console.log(`Check Allowance: ${await Token.allowance(signer.address, permittee)}`);


main().catch((error) => {
  process.exitCode = 1;

Looking into more insight on what could possible be the issue. I dont think its the version (as I confirmed its 1), maybe its the chainId.

Thanks for the help.

The permit in DAI is not EIP-2612 compliant. See the Backwards Compatibility section in the EIP.