You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A contract interface that enables transferring of fungible assets via a signed authorization.
16
-
17
14
## Abstract
18
15
19
16
A set of functions to enable meta-transactions and atomic interactions with [ERC-20](./eip-20.md) token contracts via signatures conforming to the [EIP-712](./eip-712.md) typed message signing specification.
20
17
21
18
This enables the user to:
22
19
23
20
- delegate the gas payment to someone else,
24
-
- pay for gas in the token itself rather than in ETH,
21
+
- pay gas in the token itself rather than in ETH,
25
22
- perform one or more token transfers and other operations in a single atomic transaction,
26
23
- transfer ERC-20 tokens to another address, and have the recipient submit the transaction,
27
24
- batch multiple transactions with minimal overhead, and
28
25
- create and perform multiple transactions without having to worry about them failing due to accidental nonce-reuse or improper ordering by the miner.
29
26
27
+
Please note that this ERC does not apply to smart contract accounts, as the `transfer` and `approve`/`transferFrom` functions from the ERC-20 standards can directly be used.
28
+
29
+
<!-- TODO (Editor's note): we don't permit links outside of the EIP/ERC repositories, with some exceptions noted in EIP-1
30
+
31
+
This ERC has been live in production within the USDC smart contract since 2020, and serves as a critical component of the [x402](https://www.x402.org/) standard.
32
+
33
+
-->
34
+
30
35
## Motivation
31
36
32
-
There is an existing spec, [EIP-2612](./eip-2612), that also allows meta-transactions, and it is encouraged that a contract implements both for maximum compatibility. The two primary differences between this spec and EIP-2612 are that:
37
+
There is an existing spec, [ERC-2612](./eip-2612.md), that also allows meta-transactions, and it is encouraged that a contract implements both for maximum compatibility. The two primary differences between this spec and ERC-2612 are that:
33
38
34
-
-EIP-2612 uses sequential nonces, but this uses random 32-byte nonces, and that
35
-
-EIP-2612 relies on the ERC-20 `approve`/`transferFrom` ("ERC-20 allowance") pattern.
39
+
-ERC-2612 uses sequential nonces, but this uses random 32-byte nonces, and that
40
+
-ERC-2612 relies on the ERC-20 `approve`/`transferFrom` ("ERC-20 allowance") pattern.
36
41
37
-
The biggest issue with the use of sequential nonces is that it does not allow users to perform more than one transaction at time without risking their transactions failing, because:
42
+
The biggest issue with the use of sequential nonces is that it does not allow users to perform more than one transaction at a time without risking their transactions failing, because:
38
43
39
44
- DApps may unintentionally reuse nonces that have not yet been processed in the blockchain.
40
45
- Miners may process the transactions in the incorrect order.
41
46
42
47
This can be especially problematic if the gas prices are very high and transactions often get queued up and remain unconfirmed for a long time. Non-sequential nonces allow users to create as many transactions as they want at the same time.
43
48
44
-
The ERC-20 allowance mechanism is susceptible to the [multiple withdrawal attack](https://blockchain-projects.readthedocs.io/multiple_withdrawal.html)/[SWC-114](https://swcregistry.io/docs/SWC-114), and encourages antipatterns such as the use of the "infinite" allowance. The wide-prevalence of upgradeable contracts have made the conditions favorable for these attacks to happen in the wild.
49
+
The ERC-20 allowance mechanism is susceptible to the <!-- TODO (Editor's note): same note as above.
50
+
[multiple withdrawal attack](https://blockchain-projects.readthedocs.io/multiple_withdrawal.html) -->/<!-- TODO (Editor's note): you can copy the SWC into your assets directory because it's MIT licensed. [SWC-114](https://swcregistry.io/docs/SWC-114) -->, and encourages antipatterns such as the use of the "infinite" allowance. The wide prevalence of upgradeable contracts has made the conditions favorable for these attacks to happen in the wild.
45
51
46
-
The deficiencies of the ERC-20 allowance pattern brought about the development of alternative token standards such as the [ERC-777](./eip-777) and [ERC-677](https://github.com/ethereum/EIPs/issues/677). However, they haven't been able to gain much adoption due to compatibility and potential security issues.
52
+
The deficiencies of the ERC-20 allowance pattern brought about the development of alternative token standards such as the [ERC-777](./eip-777.md) and <!-- TODO (Editor's note): if you'd like to link to ERC-677, you'll need to pull request it into the repository (i.e. upgrade it) [ERC-677](https://github.com/ethereum/EIPs/issues/677)-->. However, they haven't been able to gain much adoption due to compatibility and potential security issues.
@@ -294,7 +300,7 @@ One might say transaction ordering is one reason why sequential nonces are prefe
294
300
- For native Ethereum transactions, when a transaction with a nonce value that is too-high is submitted to the network, it will stay pending until the transactions consuming the lower unused nonces are confirmed.
295
301
- However, for meta-transactions, when a transaction containing a sequential nonce value that is too high is submitted, instead of staying pending, it will revert and fail immediately, resulting in wasted gas.
296
302
- The fact that miners can also reorder transactions and include them in the block in the order they want (assuming each transaction was submitted to the network by different meta-transaction relayers) also makes it possible for the meta-transactions to fail even if the nonces used were correct. (e.g. User submits nonces 3, 4 and 5, but miner ends up including them in the block as 4,5,3, resulting in only 3 succeeding)
297
-
- Lastly, when using different applications simultaneously, in absence of some sort of an off-chain nonce-tracker, it is not possible to determine what the correct next nonce value is if there exists nonces that are used but haven't been submitted and confirmed by the network.
303
+
- Lastly, when using different applications simultaneously, in the absence of some sort of an off-chain noncetracker, it is not possible to determine what the correct next nonce value is if there exists nonces that are used but haven't been submitted and confirmed by the network.
298
304
- Under high gas price conditions, transactions can often "get stuck" in the pool for a long time. Under such a situation, it is much more likely for the same nonce to be unintentionally reused twice. For example, if you make a meta-transaction that uses a sequential nonce from one app, and switch to another app to make another meta-transaction before the previous one confirms, the same nonce will be used if the app relies purely on the data available on-chain, resulting in one of the transactions failing.
299
305
- In conclusion, the only way to guarantee transaction ordering is for relayers to submit transactions one at a time, waiting for confirmation between each submission (and the order in which they should be submitted can be part of some off-chain metadata), rendering sequential nonce irrelevant.
300
306
@@ -310,9 +316,9 @@ One might say transaction ordering is one reason why sequential nonces are prefe
310
316
311
317
## Backwards Compatibility
312
318
313
-
New contracts benefit from being able to directly utilize EIP-3009 in order to create atomic transactions, but existing contracts may still rely on the conventional ERC-20 allowance pattern (`approve`/`transferFrom`).
319
+
New contracts benefit from being able to directly utilize [ERC-3009](./eip-3009.md) in order to create atomic transactions, but existing contracts may still rely on the conventional ERC-20 allowance pattern (`approve`/`transferFrom`).
314
320
315
-
In order to add support for EIP-3009 to existing contracts ("parent contract") that use the ERC-20 allowance pattern, a forwarding contract ("forwarder") can be constructed that takes an authorization and does the following:
321
+
In order to add support for ERC-3009 to existing contracts ("parent contract") that use the ERC-20 allowance pattern, a forwarding contract ("forwarder") can be constructed that takes an authorization and does the following:
316
322
317
323
1. Extract the user and deposit amount from the authorization
318
324
2. Call `receiveWithAuthorization` to transfer specified funds from the user to the forwarder
A fully working implementation of EIP-3009 can be found in [this repository](../assets/eip-3009/EIP3009.sol). The repository also includes [an implementation of EIP-2612](../assets/eip-3009/EIP2612.sol) that uses the EIP-712 library code presented above.
536
+
A fully working implementation of ERC-3009 can be found in [this repository](../assets/eip-3009/ERC3009.sol). The repository also includes [an implementation of ERC-2612](../assets/eip-3009/ERC2612.sol) that uses the EIP-712 library code presented above.
525
537
526
538
## Security Considerations
527
539
528
-
Use `receiveWithAuthorization` instead of `transferWithAuthorization` when calling from other smart contracts. It is possible for an attacker watching the transaction pool to extract the transfer authorization and front-run the `transferWithAuthorization` call to execute the transfer without invoking the wrapper function. This could potentially result in unprocessed, locked up deposits. `receiveWithAuthorization` prevents this by performing an additional check that ensures that the caller is the payee. Additionally, if there are multiple contract functions accepting receive authorizations, the app developer could dedicate some leading bytes of the nonce could as the identifier to prevent cross-use.
540
+
Use `receiveWithAuthorization` instead of `transferWithAuthorization` when calling from other smart contracts. It is possible for an attacker watching the transaction pool to extract the transfer authorization and front-run the `transferWithAuthorization` call to execute the transfer without invoking the wrapper function. This could potentially result in unprocessed, locked up deposits. `receiveWithAuthorization` prevents this by performing an additional check that ensures that the caller is the payee. Additionally, if there are multiple contract functions accepting receive authorizations, the app developer could dedicate some leading bytes of the nonce as an identifier to prevent cross-use.
529
541
530
542
When submitting multiple transfers simultaneously, be mindful of the fact that relayers and miners will decide the order in which they are processed. This is generally not a problem if the transactions are not dependent on each other, but for transactions that are highly dependent on each other, it is recommended that the signed authorizations are submitted one at a time.
531
543
532
-
The zero address must be rejected when using `ecrecover` to prevent unauthorized transfers and approvals of funds from the zero address. The built-in `ecrecover` returns the zero address when a malformed signature is provided.
544
+
The zero address must be rejected when `ecrecover` is used to prevent unauthorized transfers and approvals of funds from the zero address. The built-in `ecrecover` returns the zero address when a malformed signature is provided.
0 commit comments