# How Permit2 approvals improve ERC-20 allowance security

**Question:** How do Uniswap's Permit2 approvals improve ERC-20 token allowance security?

**Reference (single source):** Uniswap Labs, `Uniswap/permit2` repository — README and `src/AllowanceTransfer.sol`, commit `cc56ad0f3439c502c246fc5cfcc3db92bb8b7219` (retrieved 2026-10-12).
<https://github.com/Uniswap/permit2/tree/cc56ad0f3439c502c246fc5cfcc3db92bb8b7219>

## Summary

The standard ERC-20 pattern asks users to grant each application a separate, usually unlimited, allowance that never expires and stays in place until the user sends a revocation transaction. Permit2 changes this. The user approves the single Permit2 contract once per token. After that, each application gets a narrower permission: either a signature that is spent in one transaction, or an allowance with a set amount and an expiry time that can be revoked in bulk. The main gain is fewer long-lived "hanging" approvals on a wallet's whole balance. The cost is that much of the trust now sits in Permit2 and in the off-chain signatures users give it.

## Facts (stated in the reference)

1. **One-time signature transfers, with no lasting allowance.** "Owners can sign messages to transfer tokens directly to signed spenders, bypassing setting any allowance… there will never be hanging approvals when using this method. The signature is valid only for the duration of the transaction in which it is spent." (README, Features: Signature Based Token Transfers; Architecture: `SignatureTransfer`)
2. **Expiring approvals.** "Approvals can be time-bound, removing security concerns around hanging approvals on a wallet's entire token balance… an approval that expires will no longer be valid." (README, Features: Expiring Approvals). The code enforces this: `transferFrom` reverts with `AllowanceExpired` when `block.timestamp > allowed.expiration` (`AllowanceTransfer.sol`, line ~79).
3. **Scoped amounts per token and spender.** `AllowanceTransfer` gives "permissions to spenders on a specified amount for a specified duration of time." Allowances are stored per owner, token and spender (README, Architecture; `AllowanceTransfer.sol` `allowance` mapping and `approve(token, spender, uint160 amount, uint48 expiration)`).
4. **Bulk emergency revocation.** "Batch Revoke Allowances: Remove allowances on any number of tokens and spenders in one transaction" (README). This is implemented as `lockdown(TokenSpenderPair[])`, which emits a `Lockdown` event for each pair (`AllowanceTransfer.sol`, line ~97).
5. **Replay protection and signature cancellation.** Signature transfers use "unordered, non-monotonic nonces" (README). Allowance permits must match the current nonce, which is then incremented. Owners can call `invalidateNonces` to cancel signed permits that are still outstanding (`AllowanceTransfer.sol`, lines ~113–140).
6. **Works with any ERC-20 and with contract wallets.** Permit-style approvals are available "even [for tokens] that do not support EIP-2612", and signature checks support EIP-1271 (README).
7. **Prerequisite.** "Users must approve the `Permit2` contract through the specific token contract" before it can be used (README, Integrating).
8. The repository falls under the Uniswap Labs Bug Bounty program (README).

## Inferences (my reasoning, not stated in the source)

- Under plain ERC-20, if an application's spender contract is compromised, the attacker can drain the full balance that any user has left approved to it. Under Permit2 with short expiries or one-time signatures, the exposure is limited to approvals that are still live and not yet expired. This is the core security benefit.
- Revocation is cheaper and more likely to happen: expiry needs no transaction, and `lockdown` covers many pairs in one transaction. So users probably keep fewer stale approvals.
- **Trade-off:** Users usually give the Permit2 contract itself a large or unlimited token allowance (fact 7). Risk therefore concentrates in Permit2: a bug in it would affect every integrating user. Risk also shifts to off-chain signatures. A phishing site that gets a user to sign a Permit2 message could move tokens without the user sending any on-chain approval. These points follow from the design. The reference does not discuss them.

## Uncertainty

- The benefits depend on how applications and wallets set expiries and amounts. The source defines the mechanism but not the defaults integrators actually use (for example, how often the amount is set to `type(uint160).max`, which the code treats as an allowance that does not decrease).
- This report uses one source, maintained by Permit2's own developer. Its security claims have not been checked here against independent audits or incident data. The README mentions neither an `audits/` folder nor its contents.
- Line numbers refer to the pinned commit and may change in later versions.

## Unanswered questions

- How often is Permit2 signature phishing exploited in practice compared with classic unlimited-approval drains? No data was gathered.
- What do external audit reports of Permit2 conclude? They were not reviewed.
- How consistently do wallets display Permit2 signature requests (EIP-712) in a readable way, which is critical to the phishing trade-off?
