Skip to content

Commit cc2c7f2

Browse files
committed
Add ERC-7204 permit extension draft
1 parent 2501ffc commit cc2c7f2

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

ERCS/eip-draft_token-permit.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
---
2+
eip: <to be assigned>
3+
title: ERC-7204 Permit Extensions
4+
description: Off-chain permit flow for ERC-7204 token managers
5+
author: Xiang (@wenzhenxiang)
6+
discussions-to: https://ethereum-magicians.org/t/contract-wallet-management-token-permit-extensions/25985
7+
status: Draft
8+
type: Standards Track
9+
category: ERC
10+
requires: 7204, 712
11+
created: 2025-03-22
12+
license: CC0-1.0
13+
---
14+
15+
## Abstract
16+
17+
This proposal extends [ERC-7204](https://eips.ethereum.org/ERCS/erc-7204) smart-wallet token managers with an off-chain authorization flow similar to `permit`. It introduces nonce-tracked `tokenTransferWithSig`, `tokenApproveWithSig`, and `tokenSetApprovalForAllWithSig` functions so that transfers, individual allowances, and global operators can all be delegated after a typed-data signature is presented by the wallet owner. The extension defines canonical EIP-712 schemas, nonce accounting, and execution requirements for compliant implementations.
18+
19+
## Motivation
20+
21+
ERC-7204 describes a token management module for smart contract wallets, but stops short of standardising an off-chain signing workflow. Systems that wish to provide "red packet" transfers or delegated approvals must invent bespoke encodings and nonce tracking, reducing interoperability. A shared permit definition lets wallets, relayers, and user interfaces exchange signed transfer authorisations without bespoke integrations.
22+
23+
Goals:
24+
25+
- Allow wallets to hand out single-use, replay-protected transfer rights and operator approvals without on-chain transactions.
26+
- Produce predictable EIP-712 schemas so that wallet UIs, SDKs, and relayers can sign and validate authorisations in a uniform manner.
27+
- Maintain backwards compatibility with existing ERC-7204 deployments that do not implement permit extensions.
28+
29+
## Specification
30+
31+
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.
32+
33+
The following additions are REQUIRED for an ERC-7204 compliant module that implements this extension.
34+
35+
### Interface
36+
37+
```solidity
38+
interface IERC7204Permit {
39+
function tokenTransferNonce(address owner, address asset, address caller) external view returns (uint256);
40+
41+
function tokenTransferWithSig(
42+
address owner,
43+
address asset,
44+
address to,
45+
uint256 value,
46+
uint256 deadline,
47+
bytes calldata signature
48+
) external returns (bool success);
49+
50+
function tokenApproveNonce(address owner, address asset, address operator, address caller)
51+
external
52+
view
53+
returns (uint256);
54+
55+
function tokenApproveWithSig(
56+
address owner,
57+
address asset,
58+
address operator,
59+
uint256 value,
60+
uint256 deadline,
61+
bytes calldata signature
62+
) external returns (bool success);
63+
64+
function tokenApprovalForAllNonce(address owner, address caller) external view returns (uint256);
65+
66+
function tokenSetApprovalForAllWithSig(
67+
address owner,
68+
address operator,
69+
bool approved,
70+
uint256 deadline,
71+
bytes calldata signature
72+
) external returns (bool success);
73+
}
74+
```
75+
76+
- `tokenTransferNonce` MUST return a monotonically increasing nonce scoped to `(owner, asset, caller)`.
77+
- `tokenTransferWithSig` MUST verify the signature via `isValidSignature`, require `msg.sender` to equal the signed `caller`, reject expired signatures (unless `deadline == 0`), increment the nonce before performing the transfer, and execute the same logic as `tokenTransfer` in ERC-7204.
78+
- `tokenApproveWithSig` MUST mirror `tokenApprove`, using a nonce scoped to `(owner, asset, operator, caller)`.
79+
- `tokenSetApprovalForAllWithSig` MUST mirror `tokenApproveForAll`, using a nonce scoped to `(owner, caller)`.
80+
81+
Implementations MUST support wallets that validate signatures through [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271). Wallets MAY wrap signatures but the module MUST unwrap them prior to verification.
82+
83+
### Typed Data
84+
85+
Compliant implementations MUST hash the following payload and pass it to the wallet's signature validation logic. The `wallet` field identifies the smart wallet that owns the module.
86+
87+
| Function | Primary Type | Fields |
88+
|----------|--------------|--------|
89+
| `tokenTransferWithSig` | `TokenTransferWithSig` | `wallet`, `owner`, `caller`, `asset`, `to`, `value`, `nonce`, `deadline` |
90+
| `tokenApproveWithSig` | `TokenApproveWithSig` | `wallet`, `owner`, `caller`, `asset`, `operator`, `value`, `nonce`, `deadline` |
91+
| `tokenSetApprovalForAllWithSig` | `TokenApprovalForAllWithSig` | `wallet`, `owner`, `caller`, `operator`, `approved`, `nonce`, `deadline` |
92+
93+
Every permit MUST use the EIP-712 domain:
94+
95+
- `name = "TokenManager Permit"`
96+
- `version = "1"`
97+
- `chainId` equal to the executing chain
98+
- `verifyingContract = address(this)`
99+
100+
### Nonce Semantics
101+
102+
- `tokenTransferNonce` MUST be scoped per `(owner, asset, caller)`.
103+
- `tokenApproveNonce` MUST be scoped per `(owner, asset, operator, caller)` to allow independent relayers.
104+
- `tokenApprovalForAllNonce` MUST be scoped per `(owner, caller)`.
105+
106+
Each `WithSig` function MUST increment its nonce immediately before state changes and MUST revert on signature reuse.
107+
108+
### Execution Requirements
109+
110+
Implementations MUST:
111+
112+
1. Treat `deadline = 0` as non-expiring; otherwise enforce `block.timestamp <= deadline`.
113+
2. Increment the scoped nonce before invoking the underlying ERC-7204 function.
114+
3. Emit the same events as the underlying ERC-7204 functions.
115+
4. Revert if signature validation fails, inputs mismatch, or deadlines are exceeded.
116+
117+
Wallets MAY offer helper wrappers, but they MUST NOT alter the semantics described above.
118+
119+
## Rationale
120+
121+
- Binding `caller` prevents relayers from reusing signatures intended for other executors.
122+
- Independent nonce scopes prevent cross-operation replay while supporting multiple relayers per owner.
123+
- Reusing the existing ERC-7204 entry points keeps events and accounting compatible with current deployments.
124+
125+
## Backwards Compatibility
126+
127+
Existing ERC-7204 modules remain valid. Clients SHOULD feature-detect permit support by checking for `IERC7204Permit` via ERC-165 or probing the new function selectors.
128+
129+
## Reference Implementation
130+
131+
A reference implementation will be published after community review. It validates the typed-data digest, increments the scoped nonce before external calls, and delegates to existing ERC-7204 functions so that storage and events remain unchanged.
132+
133+
## Security Considerations
134+
135+
- Nonces MUST increment even if downstream token interactions revert.
136+
- Wallet owners SHOULD bound permit deadlines to reduce the risk of long-lived signatures.
137+
- Relayers MUST ensure their transaction sender equals the signed `caller` to avoid wasted gas.
138+
139+
## Test Cases
140+
141+
A public test suite will accompany the reference implementation. Implementers are encouraged to cover:
142+
143+
- successful submissions for transfers, allowances, and operator approvals by authorised relayers,
144+
- rejection of expired, replayed, or mismatched signatures,
145+
- nonce increment behaviour when token interactions revert,
146+
- replay protection across all nonce scopes.
147+
148+
## Copyright
149+
150+
Copyright and related rights waived via [CC0-1.0](https://creativecommons.org/publicdomain/zero/1.0/).

0 commit comments

Comments
 (0)