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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions