Skip to main content

Overview

The Permit2IntentExecutor enables intent execution leveraging Uniswap’s Permit2 system for efficient token permission management with gasless approvals. Source: /src/executor/Permit2Intent/Permit2Executor.sol:43

Key Features

  • Gasless Token Approvals: Use EIP-712 structured signatures instead of on-chain approval transactions
  • Nonce-Based Replay Protection: Efficient storage patterns for per-account nonce tracking
  • EIP-1271 Validation: Support for both EOA and smart contract account signatures
  • Cross-Chain Support: Origin and destination chain execution with Permit2 authorization

Execution Flow

  1. User signs a Permit2-compatible intent with token permissions and operations
  2. Arbiter calls executePreClaimOpsWithPermit2Stub to execute pre-claim operations
  3. Contract validates the signature against Permit2’s domain separator
  4. Nonce is consumed to prevent replay attacks
  5. Pre-claim operations are executed (e.g., token transfers, swaps)
  6. For cross-chain: executeTargetOpsWithPermit2Stub executes on destination

Structs

EIP712Permit2Stub

Core Permit2 parameters for intent execution.
nonce
uint256
Nonce for replay protection, unique per account
expires
uint256
Expiration timestamp for the permit

EIP712Permit2MandateStub

Mandate-specific parameters for Permit2 intent execution on origin chain.
tokenInHash
bytes32
Hash of input token details
minGas
uint128
Minimum gas required for execution of operations
targetAttributesHash
bytes32
Hash of target attributes (account, tokenOut, chain, expires)
destOpsHash
bytes32
Hash of destination operations to execute
qHash
bytes32
Hash of qualifier data specific to this mandate

EIP712Permit2MandateDestinationStub

Mandate-specific parameters for Permit2 destination chain execution.
sponsor
address
Original sponsor address from the origin chain
arbiter
address
Arbiter that facilitated the cross-chain transfer
minGas
uint128
Minimum gas required for pre-claim operations
notarizedChainId
uint256
Chain ID where the order was originally notarized
preClaimOpsHash
bytes32
Hash of pre-claim operations from origin chain
tokenInHash
bytes32
Hash of input token details
qHash
bytes32
Hash of qualifier data
targetStub
Target
Target parameters for fill validation

Target

Target chain fill parameters for Permit2 destination execution.
fillExpiry
uint256
Deadline timestamp for completing the fill
tokenOutHash
bytes32
Hash of expected output tokens

Functions

executePreClaimOpsWithPermit2Stub

Executes pre-claim operations using Permit2-based authorization.
account
address
required
The user account that signed the intent and will execute operations
permit2Stub
EIP712Permit2Stub
required
Core Permit2 parameters including nonce and expiration
mandateStub
EIP712Permit2MandateStub
required
Mandate-specific parameters including token and operation hashes
preClaimOps
Types.Operation
required
Array of operations to execute on the origin chain
signature
bytes
required
EIP-712 signature from the account authorizing the operations
Returns: bytes32 - The computed Permit2 hash used for signature validation
The function immediately consumes the nonce to prevent replay attacks before validating the signature and executing operations.

executeTargetOpsWithPermit2Stub

Executes target operations using Permit2-based authorization on the destination chain.
account
address
required
The user account that signed the intent and will execute operations
permit2Stub
EIP712Permit2Stub
required
Core Permit2 parameters including nonce and expiration
mandateStub
EIP712Permit2MandateDestinationStub
required
Mandate-specific parameters including token and operation hashes for destination
targetOps
Types.Operation
required
Array of operations to execute on the destination chain
signature
bytes
required
EIP-712 signature from the account authorizing the operations
Returns: bytes32 - The computed Permit2 hash used for signature validation
This function can only be called by the authorized router contract. It validates that execution is on the correct target chain and that the fill deadline hasn’t expired.

isPermit2IntentNonceConsumed

Checks if a nonce has been used for a specific account.
nonce
uint256
required
The nonce value to check
account
address
required
The account address that owns the nonce
Returns: bool - True if the nonce has been consumed, false otherwise

Signature Validation

The contract uses EIP-712 signature validation with Permit2’s domain separator:

Hash Computation

  1. Mandate Hash: Combines target attributes, operation hashes, and qualifier data
  2. Permit2 Hash: Combines mandate hash with Permit2-specific fields (token, arbiter, nonce, expires)
  3. Typed Data Digest: Wraps Permit2 hash with domain separator for final signature validation

Validation Modes

Supports multiple signature validation modes via the ValidateSignature base contract:
  • ERC1271: Direct signature validation
  • EMISSARY: Session key validation
  • Hybrid Modes: Fallback combinations for flexibility
See IntentExecutor for detailed validation mode documentation.

Example Usage

Gas Optimization

The contract uses cached Permit2 domain separator to avoid external calls during signature validation, reducing gas costs.

Error Handling

InvalidSignature
error
Thrown when signature validation fails using any configured validation mode
InvalidParams
error
Thrown when fill expiration has passed or chain validation fails
OnlyRouter
error
Thrown when executeTargetOpsWithPermit2Stub is called by non-router address

Security Considerations

Domain Separator Validation: The contract uses Permit2’s domain separator to prevent cross-protocol signature reuse. Signatures are only valid for Permit2 intents.
Nonce Consumption: Nonces are consumed immediately at the start of execution to prevent replay attacks, even if signature validation or execution fails afterward.
Expiration Checks: Both the permit expiration and fill expiration (for destination chain) are validated to prevent execution of stale intents.

Benefits over Standard Approvals

  1. Gas Savings: No separate approval transaction needed
  2. Better UX: Single signature for approval + operation
  3. Granular Control: Per-intent token permissions instead of unlimited approvals
  4. Cross-Chain: Works seamlessly across chains with consistent signatures