ERC-1363 is an ERC-20 extension that adds callback hooks to token transfers and approvals. It solves the fundamental two-step problem with ERC-20: the approve + transferFrom dance that requires two transactions, confuses users, and creates a window where tokens can be lost if the receiving contract doesn’t pull them.
With ERC-1363, a token holder can transfer tokens and notify the recipient in a single transaction. The standard was formalized as EIP-1363 and has an OpenZeppelin implementation.
The approve-and-transfer problem#
The standard ERC-20 workflow for interacting with a smart contract looks like this:
- User calls
approve(spender, amount)on the token contract, granting the spender an allowance. - User calls a function on the spender contract (e.g.
stake(amount)). - The spender contract internally calls
transferFrom(user, self, amount)to pull the tokens.
This is two transactions, two gas payments, and a race condition (the allowance sits open between steps 1 and 2). If the user calls transfer directly instead of approve, the receiving contract has no way to know tokens arrived – they’re effectively stuck.
ERC-1363 collapses this into one step.
The interface#
ERC-1363 adds four functions to the ERC-20 interface:
|
|
And two receiver interfaces that contracts must implement to accept these calls:
|
|
The receiver returns a magic value (bytes4 selector) to confirm it handled the callback – the same pattern used by ERC-721’s onERC721Received. If the receiver doesn’t return the correct value, the transaction reverts.
How it works#
transferAndCall: Transfers tokens to the recipient, then calls onTransferReceived on the recipient. The recipient can decode the data parameter to determine what action to take (e.g. stake, deposit, purchase).
approveAndCall: Sets an allowance for the spender, then calls onApprovalReceived on the spender. The spender can immediately pull the tokens within the same transaction.
Both paths are atomic – if the callback reverts, the transfer or approval reverts too.
Concrete example#
A staking contract using ERC-1363:
|
|
The user calls token.transferAndCall(stakingPool, amount) – one transaction, tokens are transferred and staked.
Comparison with related standards#
| Standard | Mechanism | Receiver interface | Notable adoption |
|---|---|---|---|
| ERC-1363 | transferAndCall + approveAndCall |
IERC1363Receiver, IERC1363Spender |
OpenZeppelin, various DeFi tokens |
| ERC-677 | transferAndCall only |
onTokenTransfer |
Chainlink LINK |
| ERC-777 | Hooks via ERC-1820 registry | IERC777Recipient |
Deprecated due to reentrancy risks |
ERC-1363 is the most complete of the three: it supports both transfer and approval callbacks, uses the battle-tested magic-value pattern, and doesn’t require an external registry like ERC-777. ERC-777 was deprecated by OpenZeppelin in v5 due to persistent reentrancy vulnerabilities stemming from its pre-transfer hooks.
Limitations#
- Receiver must opt in – contracts that don’t implement
IERC1363Receiverwill causetransferAndCallto revert. Plaintransferstill works (it’s just ERC-20), but then you lose the callback. - Not widely adopted yet – most existing DeFi contracts expect the traditional approve-then-call pattern. A token being ERC-1363 doesn’t help unless the receiving protocol supports the callback.
- Extra interface surface – contracts accepting ERC-1363 tokens need to implement and audit the receiver interface, adding code and attack surface.
External links#
- EIP-1363: Payable Token
- OpenZeppelin ERC-1363 docs
- vittominacori/erc1363-payable-token – reference implementation