ERC-5008 ERC-721 nonce extension

Last Call · NFTs & multi-token · created 2022-04-10

An extension that adds a nonce, a number that changes each time an NFT is transferred, to ERC-721 NFTs. By recording the nonce together with a sale order, orders revived by a wallet move can be filtered out, preventing underpriced sales.

Why it is needed

Sale orders on some NFT marketplaces have been attacked, causing NFTs to sell for less than the current market floor price. This happens because if a user moves an NFT to another wallet and later moves it back to the original wallet, a sale order placed in the past can become active again. If an order the owner thought was already canceled becomes active again, it can execute at a price far below what the owner currently wants. The problem is that there is no standard way for a contract to check whether a token has moved since an order was created. This standard defines a per-token nonce that changes on transfer, along with a function to query it. By recording the nonce together with an order, such attacks can be avoided by invalidating orders whose nonce no longer matches the current nonce before execution.

What to implement

In depth

Behavioral requirements of the nonce function

nonce(uint256 tokenId) is a query function that returns the current nonce of a specific NFT. It must revert (throw) if tokenId is not a valid NFT. This function must be implemented as view, so it does not change state and can be read at any time. Since the nonce changes when a token is transferred, external systems such as marketplaces can compare the nonce at order creation time with the nonce queried at execution time to determine whether the token moved in between.

The NonceChanged event

The event NonceChanged(uint256 tokenId, uint256 nonce) is emitted when an NFT's nonce changes. It includes the tokenId of the affected token and the nonce value after the change. By subscribing to this on-chain record, one can track when and to what value each token's nonce changed, allowing systems that validate orders based on the nonce to catch changes without missing any.

ERC-165 identifier 0xce03fdab

The ERC-165 identifier for this interface is 0xce03fdab. Implementing contracts must return true when supportsInterface is called with 0xce03fdab. Callers interacting with an arbitrary ERC-721 contract should first check this value to confirm extension support before calling the nonce function. Since this standard is an extension that requires ERC-165 and ERC-721 (requires: 165, 721), it is built on top of contracts that already implement both standards.

Why it is named nonce rather than transferCount

The function name transferCount was initially considered. However, there may be cases where the nonce needs to change for reasons other than a transfer. The source text cites a change to an important property of the token as an example. For that reason, the name was changed to nonce rather than limiting it to a transfer count. In other words, while the nonce changes when a token is transferred, the name leaves room for it to also change on other significant changes depending on the implementation.

Compatibility and provided implementation materials

This standard is an extension compatible with ERC-721. It does not change existing ERC-721 behavior; it only adds one function and one event, so it does not conflict with the existing ecosystem. The source repository provides test cases (test.ts) and a reference implementation (ERC5008.sol). Implementers can run npm install and npm run test in that directory to run the tests, giving a starting point for checking whether their own implementation matches the behavior expected by the standard.

Document status and security considerations

As of the source text, this proposal's status is Last Call, with the final comment period deadline listed as August 15, 2023. Since this is the final review stage before being finalized as Final, it is best to check the latest status before implementing. The Security Considerations section states only that no security issues have been found, so there is nothing in the source text indicating that this extension itself introduces new security risks.

Original ERC · ← ERCs