EIP-6059: Parent-Governed Nestable Non-Fungible Tokens

Thanks for this proposal, I’ve been working with NFTs owned by NFTs in a project of my own recently, and I came across this while researching what other people are doing in this area. I’ve got a few thoughts on EIP 6059.

Firstly, just a typo, this should be “supply chains”?

One concrete example of this can be drawn from supply trains use case.

I like the general principle that an NFT from one contract can be the owner of an NFT from a different contract, so I’m pleased to see this spec using that approach. In contrast, EIP-6150 seems to expect that relationships only occur within the same contract, and that limits composability between contracts unaware of each other.

I feel like EIP-6059 is on the right track, but has some implicit assumptions about the type of nesting being modelled by the spec. I think you could get to a more general spec, which is also simpler.

A lot of the spec is describing how to model an ordered list of child NFTs owned by a parent, and a way to add children to the list using a two-step propose-and-accept method, with a secondary list of pending children.

I feel that this part of the spec is describing one approach to solve a general problem. My own use case doesn’t map well to an ordered list of children, as my children are more like object properties with distinct and clear semantic relationships to the parent. Representing them as a list would introduce the problem of validating that the cardinality of the relationships is correct, and of searching the list to find the child of a particular type. The propose-approve addition model is not something I need, so supporting it would feel unnatural.

I feel that a lot of the spec deals with how to create and modify hierarchies of NFTs. Construction of the hierarchy is something that is fairly application-specific, as every application will have their own requirements for what combinations of things are valid and what permissions are required.

For me, there’s more benefit in standardising how to read/interpret a hierarchy than write a hierarchy, as reading can be done by any number of parties, and these parties need standardisation to agree on how to interpret the hierarchy. Whereas writing is a limited-scope operation by a specific party, and the details of how something was created don’t matter for others, so long as they can interpret the result. Standardising writing imposes constraints on how an application can work, whereas standardising reading enables applications to interoperate in ways they otherwise couldn’t.

I think there’s potential to make NFTs more composable, extensible and enable emergent behaviour using NFTs owned by NFTs.

For example, eip-4907 provides a way for NFTs to be rented to 3rd parties, without giving the 3rd party the right to transfer the NFT. But it expects that an NFT implement the spec. i.e. as well as modelling their own domain, it expects an NFT contract to also model the rental domain, which feels like an unnecessary merging of separate concerns, and limits compatibility with existing contracts that are unaware of the spec. This also doesn’t scale — we can’t expect every NFT contract to be re-written to implement a new interface in order to work with new standards (especially considering the immutable, single-identity nature of NFTs).

The same could be achieved without needing the rented NFT to know about the rental spec by using a wrapper rental NFT contract that owns the borrowed NFTs, and transferring ownership of the rental wrapper to the borrower. This allows the rental wrapper to implement arbitrary conditions on the rental (rather than the fixed time duration model used by the 4907). e.g. the wrapper could remain active as long as a superfluid stream paying into it remained solvent. The wrapper would be a proper bearer asset that can be re-sold by the borrower. And the rights of the owner and borrower are protected by the logic of the wrapper rental contract, such that the owner can’t rug-pull the renter by selling the rented NFT, and the borrower can’t transfer the rented NFT.

What’s needed is a standard way to represent semantic information about the relationship between the parent and child NFTs. (e.g. in this example, so that 3rd parties can understand that ownership of the rental NFT implies the owner has this rental agreement with the wrapped NFT.) And more generally, an NFT may not own another NFT but could still express information about it. This feels very much like the problem that Linked Data and the Semantic Web tries to solve — it wouldn’t be practical to create an EIP and specific interface for every domain in which an NFT can express a relationship with another, but it would be practical standardise a way to express such relationships generically, a bit like how EIP-165 or ERC-1820 generically define contract interface compatibility.

Sorry if this is a bit abstract, but I can point to some concrete things for this EIP.

The way ownerOf() is specified breaks compatibility with 721. In my opinion, it should report the contract address that owns the NFT, not the account that owns it transitively. Instead of changing the semantics of ownerOf() the spec should define a new function should for the indirect owner.

However, I’m not sure that such a function is needed. Because 721 already defines ownerOf() which can point to the owning contract, the only thing missing is a standard way to ask the owning contract which of its tokens owns the child NFT.

Similarly, 721’s Transfer event already communicates the transfer of ownership to the parent NFT contract, but an event listener needs to know which tokenId is the owner. Rather than having the child emit a new NestTransfer event, the parent contract could emit a Receive event, containing the tokenId that now owns the child.

This approach would allow regular 721 contracts to interoperate, without needing them to know that their owner is an NFT.

The spec mentions INestable and nestMint which are not defined in the spec.

On the security side of things, an issue I’ve considered in my own nested ownership situation is with selling the nested NFTs, or more generally, allowing other contracts to use them safely. The problem is that if a hierarchy can be modified by its current owner, the owner could list the NFT for sale, and then front-run a sale transaction by removing a child NFT that the buyer was expecting to own after the sale.

In theory this front-running and modification could be detected as part of the contract executing the sale transaction, but in practice NFT marketplaces won’t be aware of NFT nesting, so they need to rely on a hierarchy being immutable.

I address this by making the parent NFT’s tokenId a content address/hash of the child NFTs. Changing the children changes the tokenId, (burns and mints a new parent), so its not possible to be rug-pulled when buying such an NFT hierarchy, as the sale’s transfer will fail because the sold token has been burnt.

Rather than using content addressing, sequential IDs that aren’t re-used could also work, but content-addressing has the property that the same conceptual NFT can be brought back into existence by combining the same children as before.

I think at least some warning of this kind of issue should be added to the security section, even if a general remediation isn’t possible.

2 Likes