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
Defines a token interface for EIP-20 tokens that supports executing recipient contract code after transfer or transferFrom, or spender contract code after approve in a single transaction.
Abstract
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 any code on a receiver or spender contract after an EIP-20transfer, transferFrom or approve so, to make an action, it is required to send another transaction.
This introduces complexity on UI development and friction on adoption because users must wait for the first transaction to be executed and then send the second one. They must also pay GAS twice.
This proposal aims to make tokens capable of performing actions more easily and working without the use of any other listener.
It allows to make a callback on a receiver or spender contract, after a transfer or an approval, in a single transaction.
There are many proposed uses of Ethereum smart contracts that can accept EIP-20 callbacks.
Examples could be
to create a token payable crowdsale
selling services for tokens
paying invoices
making subscriptions
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 EIP-721onERC721Received and ERC721TokenReceiver behaviours.
Specification
Implementing contracts MUST implement the EIP-1363 interface as well as the EIP-20 and EIP-165 interfaces.
pragma solidity^0.8.0;
interfaceERC1363isERC20, ERC165 {
/* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) *//** * @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 amount uint256 The amount of tokens to be transferred * @return true unless throwing */function transferAndCall(addressto, uint256amount) externalreturns (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 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(addressto, uint256amount, bytesmemorydata) externalreturns (bool);
/** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param sender address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param amount uint256 The amount of tokens to be transferred * @return true unless throwing */function transferFromAndCall(addresssender, addressto, uint256amount) externalreturns (bool);
/** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param sender address The address which you want to send tokens from * @param to address The address which you want to transfer to * @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(addresssender, addressto, uint256amount, bytesmemorydata) externalreturns (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 amount uint256 The amount of tokens to be spent */function approveAndCall(addressspender, uint256amount) externalreturns (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 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(addressspender, uint256amount, bytesmemorydata) externalreturns (bool);
}
interfaceERC20 {
function totalSupply() externalviewreturns (uint256);
function balanceOf(addressaccount) externalviewreturns (uint256);
function transfer(addressrecipient, uint256amount) externalreturns (bool);
function transferFrom(addresssender, addressrecipient, uint256amount) externalreturns (bool);
function allowance(addressowner, addressspender) externalviewreturns (uint256);
function approve(addressspender, uint256amount) externalreturns (bool);
event Transfer(addressindexedfrom, addressindexedto, uint256value);
event Approval(addressindexedowner, addressindexedspender, uint256value);
}
interfaceERC165 {
function supportsInterface(bytes4interfaceId) externalviewreturns (bool);
}
A contract that wants to accept ERC1363 tokens via transferAndCall or transferFromAndCallMUST implement the following interface:
/** * @title ERC1363Receiver interface * @dev Interface for any contract that wants to support `transferAndCall` or `transferFromAndCall` * from ERC1363 token contracts. */interfaceERC1363Receiver {
/* * Note: the ERC-165 identifier for this interface is 0x88a7ca5c. * 0x88a7ca5c === bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)")) *//** * @notice Handle the receipt of ERC1363 tokens * @dev Any ERC1363 smart contract calls this function on the recipient * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the * 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 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(addressspender, addresssender, uint256amount, bytesmemorydata) externalreturns (bytes4);
}
A contract that wants to accept ERC1363 tokens via approveAndCallMUST implement the following interface:
/** * @title ERC1363Spender interface * @dev Interface for any contract that wants to support `approveAndCall` * from ERC1363 token contracts. */interfaceERC1363Spender {
/* * Note: the ERC-165 identifier for this interface is 0x7b04a2d0. * 0x7b04a2d0 === bytes4(keccak256("onApprovalReceived(address,uint256,bytes)")) *//** * @notice Handle the approval of ERC1363 tokens * @dev Any ERC1363 smart contract calls this function on the recipient * after an `approve`. This function MAY throw to revert and reject the * 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 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)"))` * unless throwing */function onApprovalReceived(addresssender, uint256amount, bytesmemorydata) externalreturns (bytes4);
}
Note that transferAndCall and 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.
Rationale
The choice to use transferAndCall, transferFromAndCall and approveAndCall derives from the EIP-20 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.
Backwards Compatibility
This proposal has been inspired also by many previous informal standards.
Unlike these proposals, EIP-1363 doesn't override the EIP-20transfer and transferFrom methods and defines the interfaces IDs to be implemented maintaining backward compatibility with EIP-20.
Security Considerations
The approveAndCall and transferFromAndCall methods can be affected by the same issue of the standard EIP-20approve 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.
One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards (EIP-20#issuecomment-263524729).
The GitHub repository vittominacori/erc1363-payable-token contains the reference implementation.
The reference implementation is also available via npm and can be installed with npm install erc-payable-token.
The text was updated successfully, but these errors were encountered:
ERC-1363 Payable Token
Simple Summary
Defines a token interface for EIP-20 tokens that supports executing recipient contract code after
transfer
ortransferFrom
, or spender contract code afterapprove
in a single transaction.Abstract
The following are the transfer, transferFrom, approve and callback functions standardized in this EIP:
transferAndCall
andtransferFromAndCall
will call anonTransferReceived
on aERC1363Receiver
contract.approveAndCall
will call anonApprovalReceived
on aERC1363Spender
contract.Motivation
There is no way to execute any code on a receiver or spender contract after an EIP-20
transfer
,transferFrom
orapprove
so, to make an action, it is required to send another transaction.This introduces complexity on UI development and friction on adoption because users must wait for the first transaction to be executed and then send the second one. They must also pay GAS twice.
This proposal aims to make tokens capable of performing actions more easily and working without the use of any other listener.
It allows to make a callback on a receiver or spender contract, after a transfer or an approval, in a single transaction.
There are many proposed uses of Ethereum smart contracts that can accept EIP-20 callbacks.
Examples could be
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 EIP-721
onERC721Received
andERC721TokenReceiver
behaviours.Specification
Implementing contracts MUST implement the EIP-1363 interface as well as the EIP-20 and EIP-165 interfaces.
A contract that wants to accept ERC1363 tokens via
transferAndCall
ortransferFromAndCall
MUST implement the following interface:A contract that wants to accept ERC1363 tokens via
approveAndCall
MUST implement the following interface:Note that
transferAndCall
andtransferFromAndCall
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.Rationale
The choice to use
transferAndCall
,transferFromAndCall
andapproveAndCall
derives from the EIP-20 naming. They want to highlight that they have the same behaviours oftransfer
,transferFrom
andapprove
with the addition of a callback on receiver or spender contracts.Backwards Compatibility
This proposal has been inspired also by many previous informal standards.
Unlike these proposals, EIP-1363 doesn't override the EIP-20
transfer
andtransferFrom
methods and defines the interfaces IDs to be implemented maintaining backward compatibility with EIP-20.Security Considerations
The
approveAndCall
andtransferFromAndCall
methods can be affected by the same issue of the standard EIP-20approve
andtransferFrom
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.One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards (EIP-20#issuecomment-263524729).
Test Cases
The repository with the reference implementation contains all the tests.
Implementation
The GitHub repository vittominacori/erc1363-payable-token contains the reference implementation.
The reference implementation is also available via npm and can be installed with
npm install erc-payable-token
.The text was updated successfully, but these errors were encountered: