Abstract
This proposal extends ERC-7204 smart-wallet token managers with an off-chain permit flow for approvals. It introduces nonce-tracked tokenPermit, tokenPermitForAll functions, allowing individual allowances and global operator approvals to be set via typed-data signatures presented by relayers. The extension defines canonical EIP-712 schemas, nonce accounting, and execution requirements for compliant implementations.
Motivation
ERC-7204 defines a token management module for smart contract wallets but does not standardize an off-chain signing workflow for approvals. Applications requiring gasless approvals (e.g., delegated spending in DeFi protocols or batch operations) currently need custom encodings and nonce schemes, reducing interoperability. A standardized permit extension enables wallets, relayers, and user interfaces to handle signed approval authorizations uniformly.
Goals:
- Enable wallet owners to delegate individual allowances and operator approvals without on-chain transactions.
- Provide predictable EIP-712 schemas for uniform signing and validation across wallets and tools.
- Preserve backwards compatibility with existing ERC-7204 deployments that do not implement this extension.
This proposal extends ERC-7204 directly to introduce a canonical EIP-712 permit flow within the existing token management model. By defining scoped nonces and standardized typed-data structures, it enables interoperable off-chain approvals without introducing a separate approval mechanism or fragmenting wallet integrations.
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Compliant contract must implement the ERC-165 interfaces
The following additions are REQUIRED for an ERC-7204 compliant module that implements this extension.
Interface
interface IERC8064 {
/// @notice Returns the current nonce for individual approvals of a specific asset and spender
function tokenApproveNonce(address asset, address spender) external view returns (uint256);
/// @notice Returns the current nonce for operator (tokenApproveForAll) approvals
function tokenApprovalForAllNonce(address spender) external view returns (uint256);
/// @notice Sets approval for a specific amount via off-chain signature
function tokenPermit(
address asset,
address spender,
uint256 value,
uint256 invalidAfter,
bytes calldata signature
) external returns (bool success);
/// @notice Sets or revokes operator status via off-chain signature
function tokenPermitForAll(
address spender,
bool approved,
uint256 invalidAfter,
bytes calldata signature
) external returns (bool success);
}
tokenApproveNonceMUST return a monotonically increasing nonce scoped to(asset, spender).tokenApprovalForAllNonceMUST return a monotonically increasing nonce scoped tospender.tokenPermitMUST mirrortokenApprove, using a nonce scoped to(asset, spender).tokenPermitForAllMUST mirrortokenApproveForAll, using a nonce scoped to(spender).
Implementations MUST support wallets that validate signatures through ERC-1271. Wallets MAY wrap signatures but the module MUST unwrap them prior to verification.
Typed Data
| Function | Primary Type | Fields |
|---|---|---|
tokenPermit |
TokenPermit |
wallet, asset, spender, value, nonce, invalidAfter |
tokenPermitForAll |
TokenPermitForAll |
wallet, spender, approved, nonce, invalidAfter |
Every permit MUST use the EIP-712 domain:
name = "TokenManager Permit"version = "1"chainId= the executing chainverifyingContract = address(this)
Nonce Semantics
tokenApproveNonceMUST be scoped per(asset, spender).tokenApprovalForAllNonceMUST be scoped per(spender).
Each permit function MUST increment its nonce immediately before other state changes and MUST revert on signature reuse.
Execution Requirements
Implementations MUST:
- Treat
invalidAfter == 0as non-expiring; otherwise requireblock.timestamp <= invalidAfter. - Determine the wallet address explicitly, either from the execution context or from the signed payload, and validate the EIP-712 digest against that wallet using ERC-1271. Implementations MUST NOT assume that a contract signer can be recovered from the signature itself.
- Verify the provided nonce matches the current stored nonce for the corresponding scope.
- Increment the scoped nonce before invoking the underlying ERC-7204 approval function. The nonce MUST remain incremented even if the downstream approval call reverts.
- Emit the same events as the corresponding ERC-7204 functions.
Rationale
- Naming functions
tokenPermitandtokenPermitForAllaligns with the widely adopted ERC-2612 pattern while distinguishing the two operations. - Scoped nonces provide strong replay protection and allow independent management of different assets and operators.
- Including the
walletowner in the signed message prevents cross-wallet replay attacks. - Internally delegating to existing ERC-7204 approval functions ensures full compatibility with events, storage, and existing tooling.
Backwards Compatibility
Existing ERC-7204 modules remain valid. Clients should feature-detect permit support by checking for IERC8064 via ERC-165 or probing the new function selectors.