On February 2, Pandora, a project focusing on NFT fragmentation, was launched. Its core feature is ERC404, a token standard that combines ERC20 and ERC721 and has the characteristics of native liquidity and NFT fragmentation. As a newly launched protocol, ERC404 has triggered extensive community discussions. The daily trading volume of its first project, Pandora, has also exceeded $50 million. More projects based on ERC404 or similar token standards are ready to be launched.

Since ERC404 was directly open sourced to the community for experiments without the discussion and review of an Ethereum Improvement Proposal (EIP) and an Ethereum Request for Comments (ERC), the protocol itself has many areas that need improvement. The Beosin security team will conduct a detailed analysis of the design mechanism and contract code of ERC404 to help crypto users understand ERC404.

What is ERC404?

ERC404 is a new experimental protocol that "fuses" two token standards, ERC20 and ERC721. To put it simply, ERC404 allows NFTs to be split and traded like ERC20 tokens. ERC404 tokens are both ERC20 tokens and NFTs, that is, one ERC404 token can be regarded as one ERC20 token or one NFT.

When a user purchases an ERC404 token, the user's wallet will automatically receive a Replicant NFT. When the user sells the token, the corresponding NFT will be automatically destroyed.

Take Pandora, the first project of ERC404, as an example. The ERC404 token of this project is PANDORA, and its corresponding Replicant NFT is Pandora Replicants. The total supply of PANDORA tokens is 10,000, so the corresponding total supply of Pandora NFTs is also 10,000.

When a user purchases PANDORA tokens on Uniswap, holding 1 PANDORA token is equivalent to holding 1 Pandora NFT at the same time. You can then choose to sell PANDORA tokens or go to NFT trading markets such as OpenSea to sell Pandora NFT. It is also possible for users to purchase Pandora NFTs first and then choose to sell PANDORA tokens on DEX.

Users can trade ERC404 tokens as ERC20 or ERC721 tokens

Since ERC404 involves two characteristics of ERC20 tokens and NFTs, the following are the design features of ERC404, which are also things that users need to pay attention to:


1. 
If ERC404 tokens are traded as ERC20 tokens, decimals will be involved and considered. ERC404 stipulates that the number of tokens is rounded down to the corresponding NFT number. For example, if a user holds 2.9 PANDORA tokens, he/she only holds 2 Pandora NFT from an NFT perspective.


2. 
In ERC404 v1, if ERC404 tokens are traded as ERC20 tokens, the corresponding NFT will be destroyed and a new NFT will be generated during trading. In this way, each time a new NFT is generated, its ID number will be added from the highest ID number of the original NFT. ERC404 v2 changes this burning mechanism, which will be explained later. Since Pandora NFT is set to have a rarity, users will trade Pandora tokens to increase the rarity of Pandora NFT for arbitrage, and replace the original NFT with a rarer Pandora NFT.


3. 
In the case of ERC404 v1, if a user holds 2.9 PANDORA tokens and sells 1 PANDORA token, the token has no rarity, but the corresponding NFT has different rarity. When selling 1 token, the last Pandora NFT received by the user will be destroyed first so users need to pay attention to the rarity of the NFT corresponding to the PANDORA token. It is recommended that one address only stores one PANDORA token, corresponding to one Pandora NFT, or users can directly trade their Pandora NFTs.

ERC404 code analysis

ERC404 v1 was released on Github by Acme, a former software engineer at Coinbase, and has many spaces for improvement. With the help of the community, the ERC404 team is currently building and improving ERC404 and launched ERC404 v2 on February 15. ERC404 v2 greatly reduces the gas consumption and optimizes the mechanism for buying and selling ERC404 tokens. Its latest code repository is https://github.com/Pandora-Labs-Org/erc404.

This time we will use the Beosin VaaS tool to scan the ERC404 v2 smart contract, analyze the ERC404 v2 codes, and provide security suggestions for ERC404 projects with Beosin security experts:

Beosin VaaS

The contracts of ERC404 v2 mainly include ERC404.sol, ERC721Receiver.sol and DoubleEndedQueue.sol. DoubleEndedQueue is a new data structure introduced by the ERC404 team to change the logic of trading token and burning NFT.

ERC404 v2, similar to v1, is a hybrid implementation of ERC721 and ERC20, allowing ERC721 tokens to be represented as ERC20 tokens. Among them, each ERC721 token corresponds to a fixed number of ERC20 tokens (determined by the units parameter). When transferring ERC721 tokens, the corresponding ERC20 tokens are transferred in units.

Compared to v1, ERC404 v2 has the following improvements:


1. 
Support EIP-2612

ERC404 v2 has supported EIP-2612, allowing gas-less transactions through signed messages (permissions). "DOMAIN_SEPARATOR" is calculated in the constructor and can be recomputed if the chain ID changes, which improves the compatibility of its contract.

constructor(string memory name_, string memory symbol_, uint8 decimals_) {

    name = name_;

    symbol = symbol_;

if (decimals_ < 18) {

      revert DecimalsTooLow();

}

    decimals = decimals_;

    units = 10 ** decimals;

// EIP-2612 initialization

    INITIAL_CHAIN_ID = block.chainid;

    INITIAL_DOMAIN_SEPARATOR = _computeDomainSeparator();

}


2. 
Safe Transfer Checking

The safeTransferFrom function in its contract follows onERC721Received() in the ERC721 standard and will check the recipient to ensure that the recipient can handle ERC721 tokens (for example, the recipient is a contract).

function safeTransferFrom(

    address from_,

    address to_,

    uint256 id_,

    bytes memory data_

) public virtual {

if (id_ > minted || id == 0) {

      revert InvalidId();

}

transferFrom(from_, to_, id_);

if (

      to_.code.length != 0 &&

ERC721Receiver(to_).onERC721Received(msg.sender, from_, id_, data_) !=

      ERC721Receiver.onERC721Received.selector

) {

      revert UnsafeRecipient();

}

}

3. Improved Minting and Burning Logic

Different from v1, when trading ERC404 v2 tokens, the corresponding NFT will not be destroyed. Instead, all NFT IDs are stored in a double-ended queue for reuse. In this way, the NFT corresponding to ERC404 is the same as the typical ERC721 token. Same as coins. This approach not only reduces gas consumption, but also simplifies the transfer logic of ERC404.

According to ERC404 team, the gas of related burning operations can be saved by 80%

The improvements of ERC404 v2 make ERC404 more scalable and sustainable, but there are still some security risks worthy of attention:


1. 
Whitelist Function

ERC404 allows certain whitelist addresses to transfer ERC721 tokens internally, which can be used to optimize the gas usage of specific contracts or addresses. However, this may also bring about centralization issues or the potential for abuse.

abstract contract ERC404 is IERC404 {

.......

mapping(address => bool) public erc721TransferExempt;

......

// Handles ERC-721 exemptions.

function _transferERC20WithERC721(

//save gas by internally trading

}

}


2. 
Transfer Function Problem

The transferFrom function handles ERC20 and ERC721 transfers, and distinguishes the logic of the two token standards based on the valueOrId_ parameter. Developers or users may make errors when calling this function, because this function has a presumption that if the value of the transfer is greater than the value of the minting count, the transfer is about a transfer of ERC20 tokens.

function transferFrom(

    address from_,

    address to_,

    uint256 valueOrId_

) public virtual returns (bool) {

......

if (valueOrId_ <= _minted) {

// Intention is to transfer as ERC-721 token (id).

      uint256 id = valueOrId_;

......

}


3. 
Gas optimization

Although ERC404 v2 has significantly reduced the gas fee required for user interaction compared to v1, there is still a lot of space for improvement. For example, the ERC404 v2 contract uses a custom error revert NotFound() instead of the require statement with an error message, which increases its gas consumption.


4. 
Lack of emergency pause function

As a newly born protocol, ERC404 may have potential contract vulnerabilities that cannot be ignored. Therefore, when the team develops the contract, an emergency pause function should be considered to set up in the contract and a risk response plan should be formulated to quickly respond and fix vulnerabilities when risks arise.

Previously, Beosin mentioned the above security suggestions to the project team when completing the audit of Avatar, an innovative project based on ERC404, which helped the Avatar team improve the security of its smart contracts and ensure the safe operation of the Avatar project. This audit includes formal verification and manual audit by security experts to ensure that the code has no logical vulnerabilities:

Overall, ERC404 attempts to solve the problems of NFT indivisibility and insufficient liquidity from a new perspective. Compared with the previous NFT fragmentation projects, it starts from native token standards, which is simpler and more effective to implement and provides new methods for trading NFT. However, ERC404 is a relatively complex contract among token contracts. Developers need to pay attention to the characteristics of ERC20 and ERC721 and the risks that may be introduced by adding new functions. Security teams need to carefully examine the interaction between ERC20 and ERC721 functions during audits, as well as the impact of various gas optimization and centralization risks in the ERC404 contracts.

Beosin is a leading global blockchain security company. It has offices in Singapore, Korea, Japan, and other 10+ countries. With the mission of "Securing Blockchain Ecosystem", Beosin provides "All in one" blockchain security solution covering Smart Contract Audit, Risk Monitoring & Alert, KYT/AML, and Crypto Tracing. Beosin has already audited more than 3000 smart contracts and ERC404 projects are welcome to ask for our consultation and audits.