ERC-6551: Non-fungible Token Bound Accounts

While you can use the value of salt as input data to the authentication scheme of the account (e.g. for storing the threshold balance of ERC-1155 tokens required to use the account), the primary behavior of salt is to allow multiple account instances for the same account implementation per token. It doesn’t make sense to keep this data private, as it’s not a key. Storing the salt data allows for the account implementation to access it’s value (which enables it to be used within the authentication logic) and allows the account to re-compute its own address locally (which is useful for proving account authenticity when calling into other contracts). In short, salt isn’t designed to store private data.

salt is a required input value for all token bound accounts as it affects the account address computation. Users that don’t wish to customize the salt can default to a salt value of zero. Because salt is not intended to be used for authentication and is required for all accounts, I don’t think it makes sense to change the language here.

Currently the appended data is determined by the registry and cannot be customized. This is to ensure that the bytecode for any token bound account is easily computable without relying on external data sources.

Using a custom implementation allows you to store any data you wish to using smart contract storage. This allows for easy querying of data. However, smart contract storage behind a proxy cannot be constant or immutable.

Correct, although querying whether a given implementation is a smart contract is trivial by extracting the implementation address from the account bytecode and querying it’s code length.

I’d love to hear more about your use case here! What arbitrary data are you hoping to append to the account bytecode? I’d be open to including an optional extraData parameter in the account creation function that allows for additional arbitrary data to be embedded in the account contract if there is sufficient interest. The tradeoff would be making deterministic calculation of token bound account addresses more difficult for applications integrating with ERC-6551.


Let’s take a token bound ERC20 for example, where the NFT gives access to owner methods (e.g. configuration, minting, etc.). In this case the implementation contract would need to introspect name and symbol that would be passed to the registry at the moment of deployment.

Let’s imagine an auction contract where the fee per transaction is set at deployment and cannot be changed, whoever owns the bound NFT will receive the revenue from fees. In this case, the implementation contract should be able to introspect the fee from the proxy bytecode.

Essentially, I believe we should be able to introspect any type of immutable data configurable at deployment, which in a traditional scenario would represent Solidity immutable variables.

Btw, by “introspect” I mean performing Bytecode.codeAt(address(this), start, end) as in the reference implementation, where address(this) would return the EIP-1167 proxy address in a delegatecall, hence we get the proxy bytecode.

That being said, I still believe salt is not a requirement (but an option) for the proxy bytecode, it could be part of extraData in the context of this proposal. On the other hand, having chainId, tokenId, tokenContract is a must.

1 Like

I see. This use case is pretty far outside the scope of this proposal, but should be easy to accomplish without any proposal changes by separating the account and ERC20 contracts. You can create an ERC20 contract and set an existing token bound account address as the owner. That way the ownership of the ERC20 contract is permanently bound to the NFT’s account, but neither the token bound account or the ERC20 contract need to be aware of each other. This also removes the need to append additional data to the token bound account bytecode within the proposal.

This could also be easily accomplished with an external auction contract that uses immutable storage. There is no need to include ERC20 or auction logic inside of a token bound account.

salt is required as a parameter in order for the registry to have the ability to create multiple accounts per instance/NFT combination.

1 Like

I see, then that is a reasonable cause to include it in the bytecode.

You’re right, I failed to see the bigger picture here. Essentially, we can introduce token bound functionality to any smart contract by making certain interactions to be performed via a token bound account.

Still, I wonder if any other folks can find use-cases where the extraData would make sense.

1 Like

Hi @Jay,
Thankyou for this wonderful new ERC and all your replies.

I’m considering implementing this ERC in a project I’m starting, but I’m worried that the interface could change. Is there some expected finalization date? Forgive my lack of experience with the process. Thankyou.

I came here intending to write this same comment.
A project I’m working on could really benefit from TBAs and I’m eager to use 6551, but I’m not familiar enough with the ERC process to know where this proposal stands.
What’s it waiting for? Is it “safe” to implement it today?

The current version of this EIP is in “Draft” status. As the tooltip on the “draft” status on that page indicates, EIPs in draft form might still have significant changes made before finalizing, so it’s not recommended to rely on its current form just yet. The EIP process itself is laid out in EIP-1, which indicates the next step for this EIP is the original author flagging it as ready for peer review, which moves it to the “Review” stage.

1 Like

My options!

Just posting a link to a competing EIP idea isn’t all that helpful in furthering discussion. If you think the proposal in this thread can be improved in specific ways, can you call out what those specifically are? The EIP idea you’re promoting is for very different use-cases (cross-chain interactions) and therefore I don’t really see how it adds “options” to this proposal?

There is a discussion going on about the name of the function to get the owner of the bound account. That must be solved before move from Draft to another state. That, of course, is a problem for everyone is implementing this EIP.

@jay I am assuming that you are going with isValidSigner. Any news about it? I haven’t seen any PR on the repo.

I am mainly concerned about usage scenarios. For example, whether this standard can collect assets in multiple chains. As I said in the article, I have an nft on eth. Can I use this to hold other nfts on polygan? ? And can this nft be held by multiple parties and jointly promoted?

The goal of ERC-6551 is to give each ERC-721 token a token-bound account with full Ether account functionality, which makes NFTs no longer just static assets, but with more utility and functionality, opening up a world of new possibilities. The realization of this concept may lead to a variety of new applications and innovations that will allow NFT to play an even greater role in the digital asset and blockchain space.

ERC-6551 does not cover those two scenarios. However it does serve as a base logic layer that both those ideas could be built on top of as separate EIPs/applications.

ERC6551 specifies a way to associate smart-contract wallets to any NFT. That works only on the chain where the account is deployed. To manage assets on different chains you should use a bridge like Wormhole, but that is out of the scope of this proposal. If you like to explore that, you can consider using GitHub - ndujaLabs/wormhole-tunnel

About the second question, you can do that letting a multi-signature wallet hold the NFT that holds the bound-account.

The ERC-6551 DRAFT looks really complicated and does not clearly demonstrate why such a complicated use case is required.

For just one example: the first use case is trustless counterfactual sending of NFTs. But then later it talks about upgradable contracts, which is the opposite of trustless.

The many levels of complexity that are added by this contract are not sufficiently motivated by motivation section text in the draft.

@fulldecent appreciate the comments! Can you expand on your complexity concerns?

This proposal specifies a canonical registry from which to deploy smart contract accounts owned by NFTs. Each account is an ERC-1167 proxy to a contract which implements an interface defined in the proposal. Given the stated motivation of giving every NFT an account, how would you recommend simplifying the proposal to achieve this goal?

The proposal does not mention or rely on upgradable contracts (although there has been some discussion about them in this thread). Can you provide some more details about your concerns here?

1 Like

Has the team considered, looked at or spoke to the Charged Particles team? CP has been doing this for a couple years and has lots of trial and error and I think there is a lot to be learned from them as well as possible collab.

Can you give some examples of what these applications are?

Is this extract from the ERC spec not contradictory?

    /// By default, token bound accounts MUST allow the owner of the ERC-721 token
    /// which owns the account to execute arbitrary calls using `executeCall`.
    /// Token bound accounts MAY implement additional authorization mechanisms
    /// which limit the ability of the ERC-721 token holder to execute calls.

If the ERC specifies that TBAs must allow execution of arbitrary calls by NFT owner but may limit these calls, then arbitrary calls are not allowed, no?

In addition…

Suggestion: change of verbiage.

Having the TBA return as owner the account that owns the NFT goes against the spirit of “the NFT owns the TBA”.

To mitigate this, I suggest changing the function name to tokenOwner.

    /// @dev Returns the owner of the ERC-721 token which controls the account
    /// if the token exists.
    /// This is value is obtained by calling `ownerOf` on the ERC-721 contract.
    /// @return Address of the owner of the ERC-721 token which owns the account
    function owner() external view returns (address);

In addition, is this factually correct?

The specification proposed above allows ERC-721 tokens to have multiple token bound accounts, one per implementation address.

If you change the salt, given the same implementation you get a different TBA, no?

Lastly, regarding this mentioned asset rug mitigation:

Here are a few mitigations strategies to be considered:

* Attach the current token bound account nonce to the marketplace order. If the nonce of the account has changed since the order was placed, consider the offer void. This functionality would need to be supported at the marketplace level.

What is there to stop a third party approved operator from moving the assets thus avoiding increment of the nonce?


I made the same proposal a while ago and you can read a long discussion starting from ERC-6551: Non-fungible Token Bound Accounts - #125 by sullof
A lot of comments after you can see @jay saying that they are working on renaming the function.
However, it would be very helpful if the name of function is defined as soon as possible.

1 Like