Gasless Token Approvals? Let’s Talk ERC-2612 permit()
“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):
approve(spender, amount)
- Sent by token owner
X
- Requires ETH to pay for gas
- Sent by token owner
transferFrom(owner, recipient, amount)
- Called by the contract
Y
- Called by the contract
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?
-
Gasless UX: New users can approve tokens without ETH — just sign a message.
-
One-Tx Flow: Only one transaction to complete an approval and usage, improving developer and user experience.
-
Relayer-Friendly :Projects can sponsor gas fees for onboarding using relayers.
-
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
-
DEXs (like Uniswap) use permit() to enable one-click swaps
-
DAOs allow gasless voting setups
-
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:
-
EIP-2612: https://eips.ethereum.org/EIPS/eip-2612
-
EIP-712: https://eips.ethereum.org/EIPS/eip-712
-
I use chatgpt for understanding the protocols