Skip to main content

Gasless Token Approvals? Let’s Talk ERC-2612 permit()

· 4 min read

“Web3 and blockchain run on protocols — every improvement is a protocol upgrade, not just a feature update.”
— 0x_scater


Introduction

When building in Web3, understanding protocol-level innovations is critical. One such innovation is ERC-2612, which upgrades the standard ERC-20 token approval mechanism to support gasless approvals.

This blog explores:

  • Why ERC-2612 exists
  • How it improves the user experience
  • How it works under the hood using EIP-712 signatures
  • Why it’s important for onboarding and adoption

Let’s compare the traditional ERC-20 flow with ERC-2612.


Traditional ERC-20 Flow

ERC-20 token transfers with smart contracts (like staking, DEXs, etc.) require two transactions:

Old Flow (ERC-20):

  1. approve(spender, amount)
    • Sent by token owner X
    • Requires ETH to pay for gas
  2. transferFrom(owner, recipient, amount)
    • Called by the contract Y

participant X as User
participant T as Token Contract
participant Y as Protocol Contract

X->>T: approve(Y, amount)
Note right of X: Pays gas
Y->>T: transferFrom(X, Y, amount)

Drawbacks:

Requires two on-chain transactions

1.Users must own ETH to approve

2.Onboarding becomes harder (especially for new users who don’t have ETH yet)

Introduce ERC-2612: The permit()

ERC-2612 introduces a new function:

function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v, bytes32 r, bytes32 s
) external;

This allows a user (owner) to sign a gasless approval off-chain and any relayer (spender or someone else) to submit it on-chain.

Flow (ERC-2612):

1.X signs an EIP-712 message off-chain

2.Y (or any relayer) calls permit() + transferFrom()

Single transaction and No ETH required from X

    participant X as User
participant Y as Relayer
participant T as Token Contract
X->>X: Sign permit message (EIP-712)
Y->>T: permit(X, Y, amount, ...)
Y->>T: transferFrom(X, Y, amount)

Query raises:How does it work?

The permit() function uses the EIP-712 standard to verify typed data signatures.

EIP-712 Typed Data Signature:

EIP-712 allows for secure and human-readable signing by hashing a structured payload. This avoids generic sign() messages, enabling wallet providers (like MetaMask) to show readable content.

Example of payload:

{
"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": "MyToken",
"version": "1",
"chainId": 1,
"verifyingContract": "0xYourTokenAddress"
},
"message": {
"owner": "0xX...",
"spender": "0xY...",
"value": "1000000000000000000",
"nonce": 0,
"deadline": 1742680400
}
}

Real Permit() code:

/ Token contract includes this:
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v, bytes32 r, bytes32 s
) external {
require(block.timestamp <= deadline, "Permit: expired deadline");

bytes32 digest = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR,
keccak256(abi.encode(
PERMIT_TYPEHASH,
owner,
spender,
value,
nonces[owner]++,
deadline
))
)
);

address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress == owner, "Invalid signature");

_approve(owner, spender, value);
}

Why need ERC-2612?

  1. Gasless UX: New users can approve tokens without ETH — just sign a message.

  2. One-Tx Flow: Only one transaction to complete an approval and usage, improving developer and user experience.

  3. Relayer-Friendly :Projects can sponsor gas fees for onboarding using relayers.

  4. Protocol-Level Upgrade: It’s not just a frontend trick — it changes the way ERC-20 tokens behave at the contract level.

Real-World Applications

  1. DEXs (like Uniswap) use permit() to enable one-click swaps

  2. DAOs allow gasless voting setups

  3. DeFi protocols onboard users without forcing them to buy ETH

Building With Protocols In Mind

ERC-2612 is a great example of how protocol-level upgrades make real impact.

If you're building in Web3, always ask:

Can I make this process more user-friendly at the protocol level?

Final Thoughts — SCATERLABs

Gasless approvals aren't a feature; they’re a shift in the ERC-20 interaction model.

They show what’s possible when we treat protocols as products.

Let’s keep building with protocols in mind.

— 0x_scater, Founder @ SCATERLABs

Resources i used:

  1. EIP-2612: https://eips.ethereum.org/EIPS/eip-2612

  2. EIP-712: https://eips.ethereum.org/EIPS/eip-712

  3. I use chatgpt for understanding the protocols