Skip to main content
Universal token approval infrastructure by Uniswap. Provides a single approval contract for all DeFi protocols.

When to use it

  • Uniswap’s token-approval contract at one address on every chain it is on. A signature transfer (permitTransferFrom) moves a user’s tokens with a one-time signed permit; an allowance transfer (approve with an expiry, then transferFrom) works like an expiring ERC-20 allowance.
  • sauce run --fund pulls with Permit2 by default: the owner signs, the Pot receives.

Pitfalls for a program

  • The user approves Permit2 itself once per token, by an ordinary ERC-20 approve.
  • A signed permit names the spender (the contract calling Permit2: the Pot), the amount, a nonce and a deadline; nonces are unordered bits, each usable once.
  • Allowance amounts are uint160 and expiries uint48.

In a Sauce program

Pull a user’s tokens into the Pot with their signed permit:

What it offers

  • approve: Set token allowance for a spender via Permit2
  • transferFrom: Transfer tokens using a Permit2 allowance

Notes

  • Same address on all 9 chains (deterministic CREATE2 deployment)
  • Approve once: ERC-20 approve to Permit2, then use Permit2 to manage per-protocol allowances
  • amount is uint160 (not uint256) - max value is type(uint160).max
  • expiration is uint48 unix timestamp - approvals auto-expire for security
  • Uniswap V3/V4, 1inch, and many protocols use Permit2 for token transfers
  • lockdown is an emergency function to batch-revoke compromised approvals

Its names in a program

On Ethereum, Permit2 is a namespace: its contracts need no import.

Deployments

ABI

Permit2ABI

import Permit2ABI from "./protocols/permit2/Permit2ABI.json"; Speaks for: permit2.
  • approve(address token, address spender, uint160 amount, uint48 expiration)
  • transferFrom(address from, address to, uint160 amount, address token)
  • permitTransferFrom(((address token, uint256 amount) permitted, uint256 nonce, uint256 deadline) permit, (address to, uint256 requestedAmount) transferDetails, address owner, bytes signature)
  • nonceBitmap(address owner, uint256 wordPosition) view returns (uint256)
  • lockdown((address token, address spender)[] approvals)

Next steps