Description
Preamble
ERC: 677
Title: transferAndCall Token Standard
Type: Informational
Category: ERC
Status: Draft
Created: 2017-07-17
Requires: ERC20
Simple Summary
Allow tokens to be transferred to contracts and have the contract trigger logic for how to respond to receiving the tokens within a single transaction.
Abstract
This adds a new function to ERC20 token contracts, transferAndCall
which can be called to transfer tokens to a contract and then call the contract with the additional data provided. Once the token is transferred, the token contract calls the receiving contract's function onTokenTransfer(address,uint256,bytes)
and triggers an event Transfer(address,address,uint,bytes)
, following the convention set in ERC223.
Motivation
ERC20 requires a multistep process for tokens to be transferred to a contract. First approve
must be called on the token contract, enabling the contract to withdraw the tokens. Next, the contract needs to be informed that it has been approved to withdraw tokens. Finally, the contract has to actually withdraw the tokens, and run any code related to receiving tokens. This process typically takes two to three steps, which is inefficient and a poor user experience.
While ERC223 solves the described problem with its transfer(address,uint256,bytes)
function, it opens other problems. ERC223 changes the behavior of ERC20's transfer(address,uint256)
, specifying that it should throw if transferring to a contract that does not implement onTokenTransfer
. This is problematic because there are deployed contracts in use that assume they can safely call transfer(address,uint256)
to move tokens to their recipient. If one of these deployed contracts were to transfer an ERC223 token to a contract(e.g. a multisig wallet) the tokens would effectively become stuck in the transferring contract.
This ERC aims to provide the helpful functionality of ERC223 without colliding with it. By giving contracts a reason to implement onTokenTransfer
before ERC223 becomes widely implemented, a smooth transition is provided until a larger part of the Ethereum ecosystem is informed about and capable of handling ERC223 tokens. transferAndCall
behaves similarly to transfer(address,uint256,bytes)
, but allows implementers to gain the functionality without the risk of inadvertently locking up tokens in non-ERC223 compatible contracts. It is distinct from ERC223's transfer(address,uint256,bytes)
only in name, but this distinction allows for easy distinguishability between tokens that are ERC223 and tokens that are simply ERC20 + ERC667.
Specification
Token
transferAndCall
function transferAndCall(address receiver, uint amount, bytes data) returns (bool success)
Transfers tokens to receiver
, via ERC20's transfer(address,uint256)
function. It then logs an event Transfer(address,address,uint256,bytes)
. Once the transfer has succeeded and the event is logged, the token calls onTokenTransfer(address,uint256,bytes)
on the receiver
with the sender, the amount approved, and additional bytes data as parameters.
Receiving Contract
onTokenTransfer
function onTokenTransfer(address from, uint256 amount, bytes data) returns (bool success)
The function is added to contracts enabling them to react to receiving tokens within a single transaction. The from
parameter is the account which just trasfered amount
from the token
contract. data
is available to pass additional parameters, i.e. to indicate what the intention of the transfer is if a contract allows transfers for multiple reasons.
Backwards Compatibility
This proposal is backwards compatible for all ERC20 tokens and contracts. New tokens and contracts moving forward can implement the transferAndCall
functionality, but also still fallback to the original approve
-transferFrom
workflow when dealing with legacy contracts. It does not require any changes or additional steps from already deployed contracts, but enables future contracts to gain this functionality.