the topic
// topic · approve / transferfrom · live everywhere · risky

ERC-20 allowance, explained

The DeFi primitive that turns one approval into a standing permission.

updated · 2 min read · by ercs-solved maintainers

Allowance is the reason a Uniswap router, lending vault, bridge, or marketplace can pull ERC-20 tokens from a user's wallet. It is also the reason users accumulate invisible standing approvals across years of DeFi usage.

on this page
  1. What is ERC-20 Allowance?
  2. At a glance
  3. Origin story
  4. The spec
  5. What's broken
  6. Approval and intent are split
  7. Max approvals become the default UX
  8. Allowance is token-local
  9. LUKSO alternative
  10. ERC-20 Allowance vs LSP6
  11. When to use which
  12. FAQ
  13. Sources
  14. Keep reading
at a glance

The standard, in one card.

Core functions
approve · allowance · transferFrom
Canonical spec
EIP-20
Common patches
ERC-2612 · Permit2 · ERC-1363
how the standard came to be

The origin story.#

ERC-20 included approve, allowance, and transferFrom from the beginning. The pattern solved a real problem: contracts needed a way to pull tokens as part of a larger operation. The ERC-20 spec intentionally kept that mechanism small, and the ecosystem filled in the missing UX with routers, signatures, dashboards, and wallet warnings.

the stack, end to end

How ERC-20 Allowance actually works.#

ERC-20 Allowance interface, grouped
owner: approve · decreaseAllowance · permit
spender: transferFrom
read: allowance

The state is simple: allowance[owner][spender] is a number. approve writes it. transferFrom checks it and moves tokens. A spender can spend up to that number until the allowance is reduced, consumed, or reset.

the integration tax

What's broken about ERC-20 Allowance.#

The risk is not that allowance is complicated. The risk is that it is too simple for modern app intent. A user wants to approve one swap, one deposit, or one bridge action. The token contract records a generic spender limit.

  1. Approval and intent are split.#

    The user approves a spender first. The spender chooses the later transferFrom parameters. A wallet can show the approval amount, but it cannot prove that the future spend will match the swap, bridge, or deposit the user thinks they are authorizing.

    ERC-20 approve(spender, value)
    split intent standing grant
    LSP6 AllowedCalls + permissions
    account-scoped call-scoped
    workarounds tried
    • EIP-2612 permit
    • Permit2 signature scopes
    • transaction simulation
    • revoke dashboards

    read the deep-dive

  2. Max approvals become the default UX.#

    Dapps request uint256 max allowances because asking for a fresh approval on every action is expensive and annoying. That makes the spender a long-lived risk even after the user leaves the app.

    ERC-20 approve(router, type(uint256).max)
    unbounded phishable
    LSP6 scoped controller
    revocable least privilege
    workarounds tried
    • exact approvals
    • approval expiration in Permit2
    • revoke.cash
    • wallet warnings
  3. Allowance is token-local.#

    Each token contract owns its own approval table. A user has to audit permissions one token at a time, and a wallet cannot express one coherent policy such as 'this app can swap up to 50 USDC per day and nothing else' across assets.

    allowance token.allowance(owner, spender)
    per-token hard to inventory
    Universal Profile account permissions
    central policy cross-asset
    workarounds tried
    • Permit2 shared router
    • wallet policy engines
    • custom vault wrappers
the LUKSO alternative

LUKSO designed it differently.#

LSP7 keeps an operator model for assets, but the meaningful shift comes when that model is paired with LSP6. The spender is no longer just an address in a token mapping. It can be a named controller whose powers are constrained by the user's account.

spec to spec, at a glance

ERC-20 Allowance vs LSP6 in one table.#

row ERC-20 Allowance LSP6
grant location inside each ERC-20 token on the account via LSP6
spender action transferFrom(owner, to, amount) controller calls through Universal Profile
common UX max approval scoped controller permission
revocation per token / per spender remove or narrow controller
be honest about scope

When to use which.#

people also ask

FAQ.#

  • What is ERC-20 allowance? #

    Allowance is the amount of a token that an owner has approved a spender to transfer with transferFrom. It is set with approve and read with allowance.

  • Why do dapps ask for unlimited allowance? #

    Unlimited allowance avoids repeated approval transactions. The tradeoff is that the spender keeps a standing permission until the user revokes it or the token contract changes the allowance.

  • Does permit remove ERC-20 allowance risk? #

    No. ERC-2612 permit moves the approval into a signature, but the result is still an ERC-20 allowance. It improves UX and can reduce approval transactions; it does not make the spender model disappear.

primary sources

Where this page draws from.#

  1. EIP-20