-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: clarify what erc1363 does with eoa #5167
Closed
vittominacori
wants to merge
8
commits into
ethereum:master
from
vittominacori:fix/clarify-1363-eoa-behavior
Closed
Changes from 5 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
7dc4bb7
fix: clarify what erc1363 does with eoa
vittominacori 2750895
fix: accepted suggested changes on ERC => EIP
vittominacori 3414035
feta: update note text
vittominacori 5d5ceac
feat: updated some params name to be more clear
vittominacori 0426662
fix: add transferFrom and approve removed by suggestion
vittominacori 3c36278
feat: update motivation and summary
vittominacori d779b6c
fix: update backwards compatibility
vittominacori eebe192
fix: update motivation
vittominacori File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -11,41 +11,41 @@ requires: 20, 165 | |||||
--- | ||||||
|
||||||
## Simple Summary | ||||||
Defines a token interface for [ERC-20](./eip-20.md) tokens that supports executing recipient code after `transfer` or `transferFrom`, or spender code after `approve`. | ||||||
Defines a token interface for [EIP-20](./eip-20.md) tokens that supports executing recipient code after `transfer` or `transferFrom`, or spender code after `approve` in a single transaction. | ||||||
|
||||||
## Abstract | ||||||
Standard functions a token contract and contracts working with tokens can implement to make a token Payable. | ||||||
The following are the transfer, transferFrom, approve and callback functions standardized in this EIP: | ||||||
|
||||||
`transferAndCall` and `transferFromAndCall` will call an `onTransferReceived` on a `ERC1363Receiver` contract. | ||||||
|
||||||
`approveAndCall` will call an `onApprovalReceived` on a `ERC1363Spender` contract. | ||||||
|
||||||
## Motivation | ||||||
There is no way to execute code after a [ERC-20](./eip-20.md) transfer or approval (i.e. making a payment), so to make an action it is required to send another transaction and pay GAS twice. | ||||||
There is no way to execute code after an [EIP-20](./eip-20.md) `transfer` or `approval` (i.e. making a payment), so to make an action it is required to send another transaction and pay GAS twice. | ||||||
|
||||||
This proposal wants to make token payments easier and working without the use of any other listener. It allows to make a callback after a transfer or approval in a single transaction. | ||||||
|
||||||
There are many proposed uses of Ethereum smart contracts that can accept [ERC-20](./eip-20.md) payments. | ||||||
There are many proposed uses of Ethereum smart contracts that can accept [EIP-20](./eip-20.md) payments. | ||||||
|
||||||
Examples could be | ||||||
* to create a token payable crowdsale | ||||||
* selling services for tokens | ||||||
* paying invoices | ||||||
* making subscriptions | ||||||
|
||||||
For these reasons it was named as **"Payable Token"**. | ||||||
For these reasons it was originally named **"Payable Token"**. | ||||||
|
||||||
Anyway you can use it for specific utilities or for any other purposes who require the execution of a callback after a transfer or approval received. | ||||||
|
||||||
This proposal has been inspired by the [ERC-721](./eip-721.md) `onERC721Received` and `ERC721TokenReceiver` behaviours. | ||||||
This proposal has been inspired by the [EIP-721](./eip-721.md) `onERC721Received` and `ERC721TokenReceiver` behaviours. | ||||||
|
||||||
## Specification | ||||||
Implementing contracts **MUST** implement the [ERC-1363](./eip-1363.md) interface as well as the [ERC-20](./eip-20.md) and [ERC-165](./eip-165.md) interfaces. | ||||||
Implementing contracts **MUST** implement the [EIP-1363](./eip-1363.md) interface as well as the [EIP-20](./eip-20.md) and [EIP-165](./eip-165.md) interfaces. | ||||||
|
||||||
```solidity | ||||||
pragma solidity ^0.8.0; | ||||||
|
||||||
interface ERC1363 /* is ERC20, ERC165 */ { | ||||||
interface ERC1363 is ERC20, ERC165 { | ||||||
vittominacori marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
/* | ||||||
* Note: the ERC-165 identifier for this interface is 0xb0202a11. | ||||||
* 0xb0202a11 === | ||||||
|
@@ -60,56 +60,56 @@ interface ERC1363 /* is ERC20, ERC165 */ { | |||||
/** | ||||||
* @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver | ||||||
* @param to address The address which you want to transfer to | ||||||
* @param value uint256 The amount of tokens to be transferred | ||||||
* @param amount uint256 The amount of tokens to be transferred | ||||||
* @return true unless throwing | ||||||
*/ | ||||||
function transferAndCall(address to, uint256 value) external returns (bool); | ||||||
function transferAndCall(address to, uint256 amount) external returns (bool); | ||||||
|
||||||
/** | ||||||
* @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver | ||||||
* @param to address The address which you want to transfer to | ||||||
* @param value uint256 The amount of tokens to be transferred | ||||||
* @param amount uint256 The amount of tokens to be transferred | ||||||
* @param data bytes Additional data with no specified format, sent in call to `to` | ||||||
* @return true unless throwing | ||||||
*/ | ||||||
function transferAndCall(address to, uint256 value, bytes memory data) external returns (bool); | ||||||
function transferAndCall(address to, uint256 amount, bytes memory data) external returns (bool); | ||||||
|
||||||
/** | ||||||
* @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver | ||||||
* @param from address The address which you want to send tokens from | ||||||
* @param sender address The address which you want to send tokens from | ||||||
* @param to address The address which you want to transfer to | ||||||
* @param value uint256 The amount of tokens to be transferred | ||||||
* @param amount uint256 The amount of tokens to be transferred | ||||||
* @return true unless throwing | ||||||
*/ | ||||||
function transferFromAndCall(address from, address to, uint256 value) external returns (bool); | ||||||
function transferFromAndCall(address sender, address to, uint256 amount) external returns (bool); | ||||||
|
||||||
|
||||||
/** | ||||||
* @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver | ||||||
* @param from address The address which you want to send tokens from | ||||||
* @param sender address The address which you want to send tokens from | ||||||
* @param to address The address which you want to transfer to | ||||||
* @param value uint256 The amount of tokens to be transferred | ||||||
* @param amount uint256 The amount of tokens to be transferred | ||||||
* @param data bytes Additional data with no specified format, sent in call to `to` | ||||||
* @return true unless throwing | ||||||
*/ | ||||||
function transferFromAndCall(address from, address to, uint256 value, bytes memory data) external returns (bool); | ||||||
function transferFromAndCall(address sender, address to, uint256 amount, bytes memory data) external returns (bool); | ||||||
|
||||||
/** | ||||||
* @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender | ||||||
* and then call `onApprovalReceived` on spender. | ||||||
* @param spender address The address which will spend the funds | ||||||
* @param value uint256 The amount of tokens to be spent | ||||||
* @param amount uint256 The amount of tokens to be spent | ||||||
*/ | ||||||
function approveAndCall(address spender, uint256 value) external returns (bool); | ||||||
function approveAndCall(address spender, uint256 amount) external returns (bool); | ||||||
|
||||||
/** | ||||||
* @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender | ||||||
* and then call `onApprovalReceived` on spender. | ||||||
* @param spender address The address which will spend the funds | ||||||
* @param value uint256 The amount of tokens to be spent | ||||||
* @param amount uint256 The amount of tokens to be spent | ||||||
* @param data bytes Additional data with no specified format, sent in call to `spender` | ||||||
*/ | ||||||
function approveAndCall(address spender, uint256 value, bytes memory data) external returns (bool); | ||||||
function approveAndCall(address spender, uint256 amount, bytes memory data) external returns (bool); | ||||||
} | ||||||
|
||||||
interface ERC20 { | ||||||
|
@@ -128,7 +128,7 @@ interface ERC165 { | |||||
} | ||||||
``` | ||||||
|
||||||
A contract that wants to accept token payments via `transferAndCall` or `transferFromAndCall` **MUST** implement the following interface: | ||||||
A contract that wants to accept ERC1363 tokens via `transferAndCall` or `transferFromAndCall` **MUST** implement the following interface: | ||||||
vittominacori marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
```solidity | ||||||
/** | ||||||
|
@@ -149,18 +149,18 @@ interface ERC1363Receiver { | |||||
* transfer. Return of other than the magic value MUST result in the | ||||||
* transaction being reverted. | ||||||
* Note: the token contract address is always the message sender. | ||||||
* @param operator address The address which called `transferAndCall` or `transferFromAndCall` function | ||||||
* @param from address The address which are token transferred from | ||||||
* @param value uint256 The amount of tokens transferred | ||||||
* @param spender address The address which called `transferAndCall` or `transferFromAndCall` function | ||||||
* @param sender address The address which are token transferred from | ||||||
* @param amount uint256 The amount of tokens transferred | ||||||
* @param data bytes Additional data with no specified format | ||||||
* @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` | ||||||
* unless throwing | ||||||
*/ | ||||||
function onTransferReceived(address operator, address from, uint256 value, bytes memory data) external returns (bytes4); | ||||||
function onTransferReceived(address spender, address sender, uint256 amount, bytes memory data) external returns (bytes4); | ||||||
} | ||||||
``` | ||||||
|
||||||
A contract that wants to accept token payments via `approveAndCall` **MUST** implement the following interface: | ||||||
A contract that wants to accept ERC1363 tokens via `approveAndCall` **MUST** implement the following interface: | ||||||
vittominacori marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
```solidity | ||||||
/** | ||||||
|
@@ -181,24 +181,27 @@ interface ERC1363Spender { | |||||
* approval. Return of other than the magic value MUST result in the | ||||||
* transaction being reverted. | ||||||
* Note: the token contract address is always the message sender. | ||||||
* @param owner address The address which called `approveAndCall` function | ||||||
* @param value uint256 The amount of tokens to be spent | ||||||
* @param sender address The address which called `approveAndCall` function | ||||||
* @param amount uint256 The amount of tokens to be spent | ||||||
* @param data bytes Additional data with no specified format | ||||||
* @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` | ||||||
vittominacori marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
* unless throwing | ||||||
*/ | ||||||
function onApprovalReceived(address owner, uint256 value, bytes memory data) external returns (bytes4); | ||||||
function onApprovalReceived(address sender, uint256 amount, bytes memory data) external returns (bytes4); | ||||||
} | ||||||
``` | ||||||
|
||||||
Note that `transferAndCall`, `transferFromAndCall` MUST revert if the recipient is an EOA address, because EOA recipients do not implement the required ERC1363Receiver interface. | ||||||
Note that `approveAndCall` MUST revert if the spender is an EOA address, because EOA spenders do not implement the required ERC1363Spender interface. | ||||||
|
||||||
vittominacori marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
## Rationale | ||||||
The choice to use `transferAndCall`, `transferFromAndCall` and `approveAndCall` derives from the [ERC-20](./eip-20.md) naming. They want to highlight that they have the same behaviours of `transfer`, `transferFrom` and `approve` with the addition of a callback on receiver or spender. | ||||||
The choice to use `transferAndCall`, `transferFromAndCall` and `approveAndCall` derives from the [EIP-20](./eip-20.md) naming. They want to highlight that they have the same behaviours of `transfer`, `transferFrom` and `approve` with the addition of a callback on receiver or spender contracts. | ||||||
vittominacori marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
## Backwards Compatibility | ||||||
This proposal has been inspired also by [ERC-223](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677) but it uses the [ERC-721](./eip-721.md) approach, so it doesn't override the [ERC-20](./eip-20.md) `transfer` and `transferFrom` methods and defines the interfaces IDs to be implemented maintaining the [ERC-20](./eip-20.md) backwards compatibility. | ||||||
This proposal has been inspired also by [ERC-223](https://github.com/ethereum/EIPs/issues/223) and [ERC-677](https://github.com/ethereum/EIPs/issues/677), but it doesn't override the [EIP-20](./eip-20.md) `transfer` and `transferFrom` methods and defines the interfaces IDs to be implemented maintaining the [EIP-20](./eip-20.md) backwards compatibility. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Happens to also remove all external links There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
|
||||||
## Security Considerations | ||||||
The `approveAndCall` and `transferFromAndCall` methods can be affected by the same issue of the standard [ERC-20](./eip-20.md) `approve` and `transferFrom` method. | ||||||
The `approveAndCall` and `transferFromAndCall` methods can be affected by the same issue of the standard [EIP-20](./eip-20.md) `approve` and `transferFrom` method. | ||||||
|
||||||
Changing an allowance with the `approveAndCall` methods brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. | ||||||
|
||||||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been updated with a new text. Please check here.
https://github.com/ethereum/EIPs/pull/5167/files#diff-d03e52deda369b57949a2bf014c8b41fb8a5c84e072f7fed33b192ed748c2714R24