Skip to content

Support ERC20 Permit in SettlementRouter (business-parameter binding without double signing) #121

@jolestar

Description

@jolestar

Context / Problem

  • We want SettlementRouter to support ERC20 Permit (EIP-2612) so tokens without EIP-3009 can be used.
  • Permit only authorizes spender/value/deadline/nonce; it does NOT bind business params (payTo, facilitatorFee, hook, hookData, salt). Facilitators could tamper these unless we add our own binding.
  • With 3009 we bound nonce == commitment so business params were signed once. Permit nonces are owned by the token contract and cannot be set to a commitment.

Risk

  • If we only rely on Permit: facilitator can change payTo/fee/hook and still use the Permit to pull funds.
  • If we add our own binding: naive approach requires a second signature (one Permit + one Router commitment), which increases client friction.

Proposal (options)

  1. Permit + Router commitment (double signature, minimal deps)

    • Clients sign ERC2612 Permit as usual.
    • Clients also sign a RouterPayment/commitment that includes: token, from, value, deadline, salt, payTo, facilitatorFee, hook, hookData, routerAddress, chainId.
    • Router validates both; idempotency via contextKey = keccak(from, token, commitment).
    • Works with any ERC2612 token. Cost: 2 signatures.
  2. Permit2 with witness (single signature, extra dependency)

    • Use Permit2 (supports “witness” data) to embed business params (payTo/fee/hook/salt) in a single signature.
    • Router verifies witness binding + executes transfer.
    • Fewer signatures, but requires Permit2 deployment & client support; not universal for all tokens.
  3. Unsafe (not recommended)

    • Just use Permit + transferFrom without binding business params; easy but facilitator can tamper payTo/fee/hook.

Suggested path

  • Short term: implement option 1 (double signature) to unblock ERC2612 support safely.
  • Longer term: evaluate option 2 (Permit2 witness) to reduce signatures if we accept the dependency.
  • Keep 3009 path unchanged; add a parallel permit path with its own commitment scheme and events.

Open questions

  • Do we mandate Permit2 as an optional optimization, or keep code strictly ERC2612-compatible?
  • How strict should recovery/idempotency be if transferFrom already happened but commitment not marked settled?
  • Event shape: use a separate SettledWithPermit or add a mode field?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions