ERC-6982 Efficient Default Lock Token (Efficient Default Lockable Tokens)

Final · NFTs & multi-token · created 2023-05-02

A standard that adds locking to NFTs (ERC-721) and saves gas by announcing the default lock state once, instead of emitting an event for every token.

Why it is needed

Existing proposals for making NFTs lockable require an event announcing the lock state to be emitted every time a token is minted. For tokens that are permanently locked from creation until they are burned, such as soulbound tokens or non-transferable badges, every token is in the same state, yet an event must still be emitted for each one, which wastes gas (fees). This standard saves gas by announcing the default lock state that applies to all tokens with a single event at contract deployment, and afterwards emitting events only when an individual token's state actually changes. It also defines functions for querying the lock state, so that other contracts and marketplaces can easily check a token's current state.

What to implement

In depth

Role of the DefaultLocked event

DefaultLocked(bool locked) MUST be emitted when the contract is deployed, to fix the default lock state of all tokens. It must be emitted again when the default state changes, and doing so updates the state of every token that has no individual Locked event in one step. The original Rationale states that this event is not limited to being emitted before Locked events and can be emitted again at any time. Its main purpose is to save gas in situations where token behavior changes, such as after a reveal, by handling it with a single DefaultLocked instead of emitting a Locked event for each token.

The Locked event and precedence of individual state

Locked(uint256 indexed tokenId, bool locked) must be emitted when the lock state of a specific token changes. The state recorded by this event overrides the default lock state for that token only. So when reconstructing state from event logs alone, an external party can take the most recent DefaultLocked value as the default and apply a token's Locked event value in preference to it when one exists.

Rules for the two query functions

defaultLocked() returns the current default lock state and must reflect the value announced by the most recent DefaultLocked event. locked(uint256 tokenId) returns the lock state of a specific token. If no Locked event has ever been emitted for that token, it must return the current default state, and if the token does not exist, it must revert. The original Rationale explains that the defaultLocked function helps interaction with other contracts and avoids potential conflicts with ERC-5192, which is already Final.

ERC-165 interface identifier

The ERC-165 interfaceId of this interface is 0x6b61a747. Because it lists ERC-165 as a requirement (requires), a marketplace or another contract can confirm through a supportsInterface query that a contract implements this standard, and then call locked and defaultLocked.

Locked does not mean non-transferable

The original text stresses that a token marked as locked is not necessarily completely non-transferable. The lock state mainly concerns whether the token can be traded on marketplaces and external exchanges, and under certain conditions a transfer can still happen while it is locked. In the Cruna protocol given as an example, when an NFT owner designates an auxiliary wallet called a protector, the token becomes locked, but transfers initiated by that protector are still possible.

Backward compatibility and reference implementation

This standard is fully backward compatible with existing ERC-721 contracts and can be integrated into them without conflicts. The reference implementation addresses the problem that staking an asset in a pool makes you lose ownership, and shows an approach where the pool locks the asset while ownership stays with the original owner. The implementation example is in the proposal's assets directory. The status of this proposal is Final, meaning the specification is settled.

Things to watch out for

Original ERC · ← ERCs