Slow evolution of ERC-20

ERC-20, what’s next?

History

Why was ERC-20 introduced? Even though it was possible to create smart contracts representing “tokens” before the ERC-20 proposal but those smart contracts are incompatible to each other unless individual developers agreed to honor individual interfaces. There are various implementations of these “tokens” even via the traditional Bitcoin blockchain, though Bitcoin opcodes are too limited to create a fully functional smart contract and some off-chain solutions are required to do it properly.

On Nov 25, 2015 Fabian Vogelsteller and Vitalik Buterin published the “Ethereum Improvement Proposals, no. 20” that describes a standard smart contract “interface” that allows the creation of simple non-fungible tokens. The “interface” specifies that ERC-20 compatible smart contracts must implement a set of methods with defined outcome, though developers still have freedom to implement various kinds of behavior depending on their goals.

EIP-20: ERC-20 Token Standard (arachnid.github.io)

Nevertheless it took more than two years to formally approve the proposal and it was finalized in April 2018. This standard is extremely popular for creating any fungible tokens. Below is the interface of ERC-20:

interface IERC20 {

    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

In addition to the usual software bugs and vulnerabilities (implementation of the standardized class interface does not automatically ensure that the code is perfect) many of the ERC-20 token owners find out that is very easy to lose their tokens by sending them to an addresses of a smart contract since usually it is not possible to send tokens back unless a developer of the smart contract puts the required functionality in advance. You can see an example below of how tokens have been sent to the contract’s address that belongs to a different ERC-20 tokens and get stuck there forever:

EOS: Old Token | 0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0 (etherscan.io)

Introducing ERC-223

In March 2017 a new improved standard was proposed by Dexaran to solve various security issues including the issue mentioned above. The proposal is located here:

https://github.com/ethereum/eips/issues/223

The newly proposed contract interface looks differently:

abstract contract IERC223 {
   
    function name()        public view virtual returns (string memory);
    function symbol()      public view virtual returns (string memory);
    function standard()    public view virtual returns (string memory);
    function decimals()    public view virtual returns (uint8);
    function balanceOf(address who) public virtual view returns (uint);
    function transfer(address to, uint value) public virtual returns (bool success);
    function transfer(address to, uint value, bytes calldata data) public virtual returns (bool success);
     
    event Transfer(address indexed from, address indexed to, uint value);
    event TransferData(bytes data);
}

Doesn’t look very different right? Let’s see inside the code:

function transfer(address _to, uint _value) public override returns (bool success)
    {
        bytes memory _empty = hex"00000000";
        balances[msg.sender] = balances[msg.sender] - _value;
        balances[_to] = balances[_to] + _value;
        if(Address.isContract(_to)) {
            IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty);
        }
        emit Transfer(msg.sender, _to, _value);
        emit TransferData(_empty);
        return true;
    }

The “transfer” method now checks whether a destination actually links to a contract and calls its “tokenReceived” method to finalize transfer. If a destination contract does not implement this method, the “transfer” method will generate an execption and revert execution preventing to sending tokens to non-compatible contract.

Also it is worth mentioning that the method updates balances before calling an external method avoiding the possibility of a re-entrancy vulnerability being exploited.

Another proposal: ERC-827

While the ERC-223 solves some securty issues that are specific to the ERC-20, it does not provide any additional functionality. In Aug 2018 Augusto Lemble made proposal of the new ERC-827 standard:

https://github.com/ethereum/eips/issues/827

The main purpose of the new contract proposal: enable execution of external smart contract methods while approving and transfering tokens, making them “smarter”. It adds a few new methods extending the standard ERC-20 interface:

function transferAndCall(address _to, uint256 _value, bytes memory _data) public payable returns (bool);
function transferFromAndCall(address _from, address _to, uint256 _value, bytes memory _data) public payable returns (bool);
function approveAndCall(address _spender, uint256 _value, bytes memory _data) public payable returns (bool);

These new methods call external methods to trigger desired actions on tokens’ approval and transfer. What is interesting is that OpenZeppelin initially included ERC-827 to their implementation library but the latest GitHub repository dropped it in favour of ERC-1363

Yet another token poposal: ERC-1363

Have you got the feeling that we have a lot of proposals for tokens? This proposal was introduced by Vittorio Minacori in Sep 2018 right after ERC-827:

https://medium.com/coinmonks/ethereum-payable-token-and-how-it-works-3bf3349a6a77
https://medium.com/coinmonks/ethereum-payable-token-and-how-it-works-3bf3349a6a77
interface ERC1363 /* is ERC20, ERC165 */ {
  function transferAndCall(address to, uint256 value) external returns (bool);
  function transferAndCall(address to, uint256 value, bytes memory data) external returns (bool);
  function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
  function transferFromAndCall(address from, address to, uint256 value, bytes memory data) external returns (bool);
  function approveAndCall(address spender, uint256 value) external returns (bool);
  function approveAndCall(address spender, uint256 value, bytes memory data) external returns (bool);
}

It looks similar to ERC-827 but it requires implementation of the ERC-165 that allows the implemention of published smart contract intrefaces and thus makes the implementation more flexible. Of course it also requires the implemention of the “receiver interface” for the smart contract that would like to receive tokens of this type:

function onTransferReceived(address operator, address from, uint256 value, bytes memory data) external returns (bytes4);

Popularity of various token standards

We can see that better and more secure token standards were introduced several years ago and we may expect that smart contract developers use them on a regular basis. Though it is hard to get an exact number of deployed smart contracts that comply to particular standards, it would require the implementation of a scanner that retrieves information about all deployed contracts, ther ABIs and how they match to ERC-20, ERC-223, ERC-867 and ERC-1363, we can use this quick and dirty method to grab available statistics about tokens at the Bloxy.info:

https://bloxy.info/

It has analytics about Ethereum tokens ERC-20, ERC-721 (NFT), ERC-223 and ERC-827 (nothing about ERC-1363).

While exact numbers of ERC-20 tokens is still unknown, the website simply trancates statistics to the first 2500 tokens, it contains information about only 24 of ERC-223 tokens and just seven ERC-827 tokens.

Summary

There are several “smart” token standards that are available for smart contracts developers but it seems that they are not very popular. Possible reasons are:

  • Smart contracts developers are not aware of security implications of the ERC-20 standard and believe that it is “good enough” for their tokens
  • Wide availability of online token “generators” that implements templates only for ERC-20 standard

One possible way to promote new token standards is to restrict acceptance of token smart contracts that are compatible only to the old ERC-20.

Leave a comment