Alert Source Discuss
⚠️ Review Standards Track: ERC

ERC-7531: Staked ERC-721 Ownership Recognition

Recognizing NFT ownership when staked into other contracts.

Authors Francesco Sullo (@sullof)
Created 2023-10-01
Requires EIP-165, EIP-721

Abstract

The ownership of ERC-721 tokens when staked in a pool presents challenges, particularly when it involves older, non-lockable NFTs like, for example, Crypto Punks or Bored Ape Yacht Club (BAYC) tokens. This proposal introduces an interface to address these challenges by allowing staked NFTs to be recognized by their original owners, even after they’ve been staked.

Motivation

Recent solutions involve retaining NFT ownership while “locking” an NFT letting the owner keeping its ownership. However, this requires the NFT contract to implement lockable functionality. Early NFTs were not originally designed as lockable and so they must be staked transferring the ownership to the staking contract.

This prevents the original owner from accessing valuable privileges and benefits associated with their NFTs.

For example:

  • A BAYC NFT holder would lose access to the BAYC Yacht Club and member events when staked.
  • A CryptoPunks holder may miss out on special airdrops or displays only available to verified owners.
  • Owners of other early NFTs like EtherRocks would lose the social status of provable ownership when staked.

By maintaining a record of the original owner, the proposed interface allows these original perks to remain accessible even when the NFT is staked elsewhere. This compatibility is critical for vintage NFT projects lacking native locking mechanisms.

Another important right, is the right to use an asset. For example an NFT can be used to play a game. If the NFT is lent to a user, the ownership of the NFT is transferred to the lending contract. In this case, it can be hard to identify the wallet that has the right to us the NFT in the game, which should be the user.

The interface provides a simple, elegant way to extend staking compatibility to legacy NFTs without affecting their core functionality or benefits of ownership.

Specification

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.

The interface is defined as follows:

interface IERC7531 {

  /**
   * @notice MUST be emitted when the token's technical owner (the contract holding the token) is different 
   *      from its actual owner (the entity with rights over the token). 
   * @dev This scenario is common in staking, where a staking contract is the technical owner. The event MUST  
   *      be emitted in the same or any subsequent block as the Transfer event for the token. 
   *      A later Transfer event involving the same token supersedes this RightsHolderChange event.
   *      To ensure authenticity, entities listening to this event MUST verify that the contract emitting
   *      the event matches the token's current owner as per the related Transfer event.
   *
   * @param tokenAddress The address of the token contract.
   * @param tokenId The ID of the token.
   * @param holder The address of the actual rights holder of the token.
   * @param right The type of right held by the holder. The initial supported rights are:
   *
   *           0x399d2b36   // bytes4(keccak256("ownership"))
   *           0x230a5961   // bytes4(keccak256("usage"))
   *
   *        This allows projects to add more rights without breaking compatibility with this interface. See IERC7531Rights for more details.
   */
  event RightsHolderChange(address indexed tokenAddress, uint256 indexed tokenId, address indexed holder, bytes4 right);

  /**
   * @dev Returns the address of the entity with rights over the token, distinct from the current owner.
   *      The function MUST revert if the token does not exist or is not currently held.
   *
   * @param tokenAddress The address of the ERC-721 contract.
   * @param tokenId The ID of the token.
   * @param right The type of right held by the holder.
   * @return The address of the entity with rights over the token.
   */
  function rightsHolderOf(
    address tokenAddress,
    uint256 tokenId,
    bytes4 right
  ) external view returns (address);
}

The RightsHolderChange event is crucial for accurately identifying the actual owner of a held token. In scenarios where a token is staked in a contract, the ERC-721 Transfer event would incorrectly assign ownership to the staking contract itself. The RightsHolderChange event addresses this discrepancy by explicitly signaling the real owner of the token rights.

Timing of Event Emission:

The RightsHolderChange event MUST be emitted either in the same block as the corresponding Transfer event or in any subsequent block. This approach offers flexibility for existing pools to upgrade their systems without compromising past compatibility. Specifically, staking pools can emit this event for all previously staked tokens, or they can allow users to actively reclaim their ownership. This flexibility ensures that the system can adapt to both current and future states while accurately reflecting the actual ownership of held tokens.

Invalidation of Previous RightsHolderChange Events:

To maintain compatibility with the broader ecosystem and optimize for gas efficiency, any new Transfer event involving the same token invalidates any previous RightsHolderChange event. This approach ensures that the most recent Transfer event reliably reflects the current ownership status, negating the need for additional events upon unstaking.

NFT extension

The two default rights are:

  • 0x399d2b36 // bytes4(keccak256(“ownership”))
  • 0x230a5961 // bytes4(keccak256(“usage”))

However, there can ben NFTs that only need to validate the ownership, others may need to validate the usage, and others may need to validate both, some other NFT may need to manage totally different rights.

To give NFTs the necessary flexibility, we also propose the following OPTIONAL extension.

interface IERC7531Rights {
  
  /**
   * @dev Returns the list of rights supported by the NFT.
   * @return The list of rights supported by the NFT.
   */
  function supportedERC7531Rights() external view returns (bytes4[] memory);
  
  /**
   * @dev Returns whether the NFT supports a specific right.
   * @param right The right to check.
   * @return Whether the NFT supports the right.
   */
  function supportsERC7531Right(bytes4 right) external view returns (bool);
}

It allows NFTs to return the list of rights they support, and projects to verify it an NFT supports a specific right. Since the rights are identified by the bytes4 hash of the right name, when introducing new rights, NFT projects SHOULD make public statements about the string that corresponds to the bytes4 hash and explain the rationale for it.

If the NFT does not support the interface (for example, if an existing NFT), project using NFTs SHOULD consider only the standard rights.

NFT Projects SHOULD adhere to pre-existing rights, when possible, to avoid the proliferation of rights that could make the system less efficient and more complex.

Rationale

Addressing Non-Lockable NFT Challenges:

Non-lockable NFTs present a unique challenge in decentralized ecosystems, especially in scenarios involving staking or delegating usage rights. The standard ERC-721 ownerOf function returns the current owner of the NFT, which, in the case of staking, would be the staking pool contract. This transfer of ownership to the staking pool, even if temporary, can disrupt the utility or privileges tied to the NFT, such as participation in governance, access to exclusive content, or utility within a specific ecosystem.

The rightsHolderOf Method:

The rightsHolderOf method provides a solution to this challenge. By maintaining a record of the original owner or the rightful holder of certain privileges associated with the NFT, this method ensures that the underlying utility of the NFT is preserved, even when the NFT itself is held in a pool.

Technical Advantages:

  1. Preservation of Utility: This approach allows NFT owners to leverage their assets in staking pools or other smart contracts without losing access to the benefits associated with the NFT. This is particularly important for NFTs that confer ongoing benefits or rights.

  2. Enhanced Flexibility: The method offers greater flexibility for NFT owners, allowing them to participate in staking and other DeFi activities without relinquishing the intrinsic benefits of their NFTs.

  3. Compatibility and Interoperability: By introducing a new method instead of altering the existing ownerOf function, this EIP ensures backward compatibility with existing ERC-721 contracts. This is crucial for maintaining interoperability across various platforms and applications in the NFT space.

  4. Event-Driven Updates: The RightsHolderChange event facilitates real-time tracking of the rights-holder of an NFT. This is particularly useful for third-party platforms and services that rely on up-to-date ownership information to provide services or privileges.

Addressing Potential Misuse:

While this approach introduces a layer of complexity, it also comes with the need for diligent implementation to prevent misuse, such as the wrongful assignment of rights. This EIP outlines security considerations and best practices to mitigate such risks.

Backwards Compatibility

This standard is fully backwards compatible with existing ERC-721 contracts. It can seamlessly integrate with existing upgradeable staking pools, provided they choose to adopt it. It does not require changes to the ERC-721 standard but acts as an enhancement for staking pools.

Security Considerations

A potential risk with this interface is the improper assignment of ownership by a staking pool to a different wallet. This could allow that wallet to access privileges associated with the NFT, which might not be intended by the true owner. However, it is important to note that this risk is lower than transferring full legal ownership of the NFT to the staking pool, as the interface only enables recognizing the staker, not replacing the actual owner on-chain.

Event Authenticity:

There is a concern regarding the potential emission of fake RightsHolderChange events. Since any contract can emit such an event, there’s a risk of misinformation or misrepresentation of ownership. It is crucial for entities listening to the RightsHolderChange event to verify that the emitting contract is indeed the current owner of the token. This validation is essential to ensure the accuracy of ownership information and to mitigate the risks associated with deceptive event emissions.

Reducing the Risk of Inaccurate Ownership Records:

While improper use of this interface poses some risk of inaccurate ownership records, this is an inherent issue with any staking arrangement. The risk is somewhat mitigated by the fact that the owner retains custody rather than transferring ownership.

Due Diligence:

Consumers of privilege-granting NFTs should exercise due diligence when evaluating staking providers. Signs of mismanagement or fraud should be carefully assessed. The interface itself does not enable new manipulation capabilities, but caution is always prudent when interacting with smart contracts and staking pools.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Francesco Sullo (@sullof), "ERC-7531: Staked ERC-721 Ownership Recognition [DRAFT]," Ethereum Improvement Proposals, no. 7531, October 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7531.