ERC-7496: NFT Dynamic Traits


Some recent updates to the spec:

  • Based on feedback, we simplified the getters/setters to a much more concise list of just 3 getters and 1 setter
  • Removed the uri param in the TraitMetadataURIUpdated event since an onchain uri may get long and expensive to emit. The event simply lets offchain indexers know to go fetch the latest from getTraitMetadataURI()
  • Simplified the JSON schema and added more functionality
    • Added dataType and valueMappings
    • Added a validateOnSale property for marketplaces to know what values to guard orders on

Please take a look at these latest round of changes and let us know other things to consider.

Hi authors of ERC-7496, this is Victor, an EIP editor and current operator of AllERCDevs.

I like to invite you to our next AllERCDevs meeting (online) to present for 10min of your ERCs if you are interested!

AllERCDevs is a bi-weekly meeting for ERC authors, builders and editors to meet and help the drafting and adoption of an ERC. The next one is 2024-04-02 UTC 2300, let us know if this time works for you, I can put this ERC in the agenda, or you can add a response directly at (Future) 2024-04-02 (E2S2) AllERCDevs Agenda Thursday (Asia/US friendly time) · Issue #19 · ercref/AllERCDevs · GitHub

Hello everyone. I’m late to the party, but I would love to share my comments and make this ERC more general by including not just basic NFTs but also DeFi assets and derivatives.

I come from a DeFi lending space, and I’m researching ways to query NFTs states with as little knowledge about the state on-chain as possible, thus being maximally open and permissionless. More and more assets are becoming stateful, and more than a token ID is needed to value such assets properly, be they NFT LP tokens, token bundlers & wrappers, or RWAs.

Having a standardized interface for accessing and defining state values is currently the missing piece, and this ERC is the right way forward. However, it is still too focused on marketplaces that sell simple NFT collections. At some point, the DeFi space will have to develop a similar but more minimalistic ERC, which seems unnecessary and duplicated. It would be great if this ERC could be updated to fulfill the needs of DeFi NFTs.

Having a key type as bytes32, which should be a hash of human-readable names, makes a lot of sense.

Also, it is very useful to have an optional metadata URI that helps with trait key discoverability and their format, specifically decimals and value mappings. What is imo unnecessary is validateOnSale and tokenOwnerCanUpdateValue.

  • validateOnSale - I see the motivation for adding it to the metadata, but it should be up to the user to define what condition should be applied to a state. Maybe the user doesn’t care about this particular trait, and the marketplace/protocol would invalidate its order just because token devs thought it was important.
  • tokenOwnerCanUpdateValue - This links to the existence of setters, about which I will talk later.

What is unnecessary and would be better to remove from the ERC is:

  • setters - Setters are usually project-specific, have more descriptive names, are access-controlled, and one modifying transaction can update several state properties simultaneously. Enabling users to update one state property via a marketplace/protocol is imo unnecessary and would lead to unused functions. I recommend removing it from the ERC.
  • most of the trait updated events - Current ERC draft states that updating traits MUST emit one of the events. That cannot be accomplished for every state property. One example is a time-based state property, such as maturity or expiration. In this case, the state property is not updated in a transaction and cannot emit an event. Also, events with range and list parameters do not fit DeFi tokens well. The one event that should stay in the ERC is TraitMetadataURIUpdated, which can always be emitted and is specific for metadata only.

With these changes, this ERC can be an excellent standard for any DeFi token and serve a wide range of cases. If you still need setters and events for trait change, let’s consider dividing this ERC into two.

I would also recommend looking into ERC-5646, which defines a getter function for accessing a state fingerprint instead of one particular property. That is useful in cases where users don’t want any state change without the need to list all state properties. A reserved trait key for state fingerprint or extending that ERC could be a way.

hey @ashhanai, thanks for the detailed review!

I’m happy to try to make this ERC also satisfy needs from the DeFi space so it can be adopted as a wider standard.

  1. The metadata URI is not optional, otherwise the human-readable trait key names or the decoding of the trait value would be unknown.

  2. validateOnSale should be provided by the collection and not the user, since the collection knows which traits needs to be protected against frontrunning (typically only a few key traits and not all of them). Allowing the user to make this decision on-the-fly during order creation would be a weird and confusing UX that the user wouldn’t understand how to properly define without lots of education.

  3. tokenOwnerCanUpdateValue is just provided so a frontend can provide a UI for updating traits if it’s something settable by the token owner, like the NFT name or a property (for example)

  4. IMO it’s very important to have setters otherwise there is no consistent interface that can be developed for users (e.g. if etherscan provides an interface for users to update traits identified by tokenOwnerCanUpdateValue). Also other ERCS like ERC-7498 redeemables needs this to update a trait after an action e.g. redemption.

  5. If an event is not emitted for a trait updated, offchain systems and indexers would never know if a trait changed. There can be some thought of an additional trait type that is dynamic that is not bound to the update events but is more dynamic based on time or other properties.

  6. A reserved trait key for state fingerprint or extending that ERC could be a way.

    I like this idea, it is very useful for the current spec to also have an idea of a state fingerprint of all the traits in case all traits are important to protect against frontrunning and something we’ve considered, but it does add quite a bit of complexity and overhead in implementation.