Learn how to use the Permit function of the DAI Stablecoin


You are already aware that executing transactions on the Ethereum network (including Polygon, Arbitrum, and Optimism) requires #Gas fees.

What is Gas and Gas Fee? Please read here: shorturl.at/nLWZ7

Now when the price of the Native Token is “affordable”, there is not much noise around gas fees; however, as soon as the price of the Native Token starts climbing your Twitter feeds will be filled with the high gas fee hue and cry. For obvious reasons.

Add to the above, we have the fact that interacting with certain smart contracts, for example, the Uniswap Router Contract (Uniswap App), a user has to make 2 transactions:

  1. first the approve function to allow a fixed number of tokens that can be used by the other smart contract in a transaction and
  2. second, the smart contract call which will then call thetransferFrom.

It is easy to guess that this increases the overall gas costs for doing transactions.

While there are multiple methods in which the “high” gas fees issue has been tackled by the industry, this article is just focusing on, probably the first large-scale implementation: the DAI Smart Contract’s Permit Function.

If you are designing your smart contracts that will require the issuance and management of ERC20 Tokens, it will be in your interest to design your ERC20 Token Smart Contract with this function.

While in theory, we could be writing for a lot more, instead we are doing a quick demo of the use case of the Permit function in the Smart Contract for the DAI Stablecoin.

Let's get our hands dirty

(A) Local Set-up

You can clone the tutorials repo from here: Github and then progress to the eip-2612 folder

(B) Installation

Once the code is set up on your local system, you need to make sure you install all the dependencies using npm i or yarn install depending on your personal preference.

(C) What is happening in the Code

Lines 1 to 17 are straightforward; so are lines 19 to 21.

Lines 18: nonce

This is NOT the nonce of any wallet address. This is the nonce that is maintained by the DAI Contract independently. Reason: imagine if I were to grant an signed message, approving your address to use my DAI. This message is used by you, but not once, but twice → this would technically qualify as “Double Spending” and hence the maintenance of an independent nonce by the DAI Smart Contract

Line 63: The signing of the message. Type: _signTypedData

Now, DAI follows the EIP712 standard for typed message signing. I will not complicate this (unless someone really wants, then just mention it in the comment below). In simple terms, it is a standard that needs to be adopted for the purpose of signing a message that can be put into “execution” by the Smart Contract and in this case, the DAI Smart Contract.

As you can see, the _signTypedData requires 3 parameters:

  • domain: think of these as the details of the smart contract for which this message is intended to be
  • types: defines the names and types of the individual items of the message
  • message: literally the message that you would like to pass to the smart contract.

Seeing the above in action

(a) Run the script: node scripts/sign.js

  • Yes, I am not using Hardhat, cause I do not need to. You can get the job done by using Ethers alone. It is just generating the signature.
  • For convenience, I have set the nonce to the value that the contract returns. That is to say, it will automatically fetch the correct nonce, based on the value stored in the contract.
  • For security purposes, I am setting the deadline to be 15 seconds from the current block. timestamp. That is to say that this signature must be lodged with the Smart Contract in 15 seconds of generation. Then, I will deliberately fail to register this signature in 15 seconds and lodge a transaction. It should fail

(b) Once it is run after using your environment variables, you will get something similar to the below image in your console:

(c) Testing if the approval went through:

— creating a Private Testnet on buildbear.io, forking from the Ethereum Mainnet

— first getting some tokens into a different account from the BuildBear Faucet:

—Visiting the DAI Smart Contract in my Private Testnets Explorer:

— Using the Permit Function (in the Write Contract part): 📝

— Executing the transaction (Obviously failed transaction): ❌

— checking why it failed by visiting the trace of the tx: 🤯

and voila! I was able to see what happened inside the transaction and not just the revert reason.

Trying to run the same script but this time with 2 mins as the expiry and re-doing everything for a successful tx will lead to:

Obviously, if you notice that I lodged the above transaction from a completely different account, which would otherwise be known as the ‘relayer’. This account paid the gas price for submitting to the blockchain that the account 0xD31950cD762281b9849c33bfa5CE9A42B756155 shall have permission to transfer my DAI tokens.


And that is all in relation to how to use the Permit Function in the DAI contract.

About BuildBear

BuildBear provides you with a private test node, making the testing process smooth and efficient.

To learn more about BuildBear, read here docs

Get the above Github code from here. 👈

If you appreciate what we are doing, please follow us on Twitter and Join the Telegram group if you haven’t done yet.

And please give us a clap 👏 if you like our work and please do share this article.

Thank you.


Dipesh (https://linktr.ee/d_sukh) and Shivam (Twitter || LinkedIn)

Let’s get started then, Shall we?