EIP-4987 "held" token standard (NFTs + DeFi)

@SamWilsn your feedback on events brings up another good question. I think there’s a case to be made that this interface should not require any events to be emitted.

One of the main goals is for this interface to be extremely lightweight and non-intrusive. Additional events/gas doesn’t help with that

Plus, we could arguably get all the equivalent data by indexing underlying token Transfer events and filtering where to or from match our holder of interest

Agree… its good idea… very useful…

There are apps where users can deposit their NFTs…
But then its not visible in their wallet and marketplaces…

If this standard being adopted… then user can deposit his NFT to another contract, but it still remains visible in his wallet…

Particularly in our case, we want to allow users prove ownership of their NFTs… including those NFTs already staked into some contracts…

If this standard being supported by staking contract… then we can read heldOwnerOf to find actual owner… also we can listen Hold and Release events… to deterministically reduce database… I think events are important…

1 Like

and events are not so bad… they are not being saved into blockchain… I mean they are much cheaper than storage data in smart contract

1 Like

Thanks for the thoughts here @7flash, glad to hear this would be applicable for your use case

And a general update, the draft has been merged in and can be found published here:

An interface was included for each “held token” type, for example ERC721

/**
 * @notice the ERC721 holder standard provides a common interface to query
 * token ownership and balance information
 */
interface IERC721Holder is IERC165 {
  /**
   * @notice emitted when the token is transferred to the contract
   * @param owner functional token owner
   * @param tokenAddress held token address
   * @param tokenId held token ID
   */
  event Hold(
    address indexed owner,
    address indexed tokenAddress,
    uint256 indexed tokenId
  );

  /**
   * @notice emitted when the token is released back to the user
   * @param owner functional token owner
   * @param tokenAddress held token address
   * @param tokenId held token ID
   */
  event Release(
    address indexed owner,
    address indexed tokenAddress,
    uint256 indexed tokenId
  );

  /**
   * @notice get the functional owner of a held token
   * @param tokenAddress held token address
   * @param tokenId held token ID
   * @return functional token owner
   */
  function heldOwnerOf(address tokenAddress, uint256 tokenId)
    external
    view
    returns (address);

  /**
   * @notice get the held balance of the token owner
   * @param tokenAddress held token address
   * @param owner functional token owner
   * @return held token balance
   */
  function heldBalanceOf(address tokenAddress, address owner)
    external
    view
    returns (uint256);
}