{"id":"ERC-6551","name":"Non-fungible Token Bound Accounts","status":"Review","chain":"both","category":{"id":"nft","name":"NFT Capabilities","description":"What NFTs can do beyond basic ownership"},"journeyStages":[{"id":"asset-display","name":"Asset Discovery & Display","description":"Seeing tokens, NFTs, and balances"},{"id":"executing","name":"Executing Transactions","description":"Performing on-chain actions"},{"id":"management","name":"Asset Management","description":"Managing assets over time"}],"uxImpact":"ERC-6551 defines a registry that computes deterministic token-bound account addresses for NFTs and can deploy them as smart-contract accounts. A deployed or counterfactual account can hold assets, but each NFT may have multiple accounts across implementations, registries, chains, and salts; sale contents must be rechecked at settlement.","officialUrl":"https://ercs.ethereum.org/ERCS/erc-6551","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","kind":"proposal","hasDetailedContent":true,"content":{"id":"ERC-6551","specConstraints":[{"id":"erc-6551-canonical-registry","constraint":"The token-bound registry is permissionless, immutable, and ownerless at its canonical address.","appliesTo":"infrastructure","normativity":"normative","specQuote":"The registry is permissionless, immutable, and has no owner. The complete source code for the registry can be found in the [Registry Implementation](#registry-implementation) section. The registry MUST be deployed at address `0x000000006551c19487814612e58FE06813775758` using Nick's Factory (`0x4e59b44847b379578588920cA78FbF26c0B4956C`) with salt `0x0000000000000000000000000000000000000000fd8eb4e1dca713016c518e31`.","specSection":"Specification — Registry","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#registry","designImplication":"Show which registry and deployment path produced a token-bound account. Do not treat an arbitrary registry deployment as equivalent to the canonical trust assumptions."},{"id":"erc-6551-deterministic-account-address","constraint":"A token-bound account address is deterministic from implementation, token contract, token ID, chain ID, and salt.","appliesTo":"application","normativity":"normative","specQuote":"The registry MUST deploy all token bound accounts using the `create2` opcode so that each account address is deterministic. Each token bound account address SHALL be derived from the unique combination of its implementation address, token contract address, token ID, chain ID, and salt.","specSection":"Specification — Registry","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#registry","designImplication":"Make implementation, registry, chain, token, and salt visible when choosing a recipient. Treat counterfactual and deployed addresses as the same selected account only after those inputs match."},{"id":"erc-6551-minimal-proxy","constraint":"The registry deploys each token-bound account as an ERC-1167 minimal proxy with immutable account context appended to its bytecode.","appliesTo":"infrastructure","normativity":"normative","specQuote":"The registry MUST deploy each token bound account as an [ERC-1167](./eip-1167.md) minimal proxy with immutable constant data appended to the bytecode.","specSection":"Specification — Registry","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#registry","designImplication":"When inspecting a token-bound account, show the selected implementation and immutable token context rather than treating the proxy address as a standalone wallet identity."},{"id":"erc-6551-account-delegation","constraint":"Each token-bound account proxy delegates execution to an IERC6551Account implementation.","appliesTo":"account-implementation","normativity":"normative","specQuote":"Each token bound account proxy MUST delegate execution to a contract that implements the `IERC6551Account` interface.","specSection":"Specification — Registry","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#registry","designImplication":"Resolve and display the implementation contract behind a token-bound proxy before offering account actions."},{"id":"erc-6551-account-created-event","constraint":"The registry emits ERC6551AccountCreated after successful account creation.","appliesTo":"application","normativity":"normative","specQuote":"* @dev The registry MUST emit the ERC6551AccountCreated event upon successful account creation.","specSection":"Specification — Registry","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#registry","designImplication":"Use the creation event to distinguish a deployed account from a merely computed address and to populate account history."},{"id":"erc-6551-account-creation-failure","constraint":"The registry reverts with AccountCreationFailed when create2 account deployment fails.","appliesTo":"application","normativity":"normative","specQuote":"* @dev The registry MUST revert with AccountCreationFailed error if the create2 operation fails.","specSection":"Specification — Registry","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#registry","designImplication":"Show deterministic account deployment failure as a distinct recoverable state instead of presenting the counterfactual address as deployed."},{"id":"erc-6551-account-interface-detection","constraint":"Token-bound account implementations must support ERC-165 interface detection.","appliesTo":"account-implementation","normativity":"normative","specQuote":"All token bound account implementations MUST implement [ERC-165](./eip-165.md) interface detection.","specSection":"Specification — Account Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#account-interface","designImplication":"Feature-detect account capabilities before showing execution or signature actions. Do not infer support from an address that merely looks token-bound."},{"id":"erc-6551-account-signature-validation","constraint":"Token-bound account implementations must support ERC-1271 signature validation.","appliesTo":"account-implementation","normativity":"normative","specQuote":"All token bound account implementations MUST implement [ERC-1271](./eip-1271.md) signature validation.","specSection":"Specification — Account Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#account-interface","designImplication":"Show when an account can validate signatures on behalf of its token-bound identity, and keep that capability distinct from ordinary NFT ownership display."},{"id":"erc-6551-account-receive","constraint":"Token-bound accounts implement a receive function so they can receive Ether.","appliesTo":"account-implementation","normativity":"normative","specQuote":"* Accounts MUST implement a `receive` function.","specSection":"Specification — Account Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#account-interface","designImplication":"Only offer native-asset deposit actions when the selected account implementation exposes the receive capability."},{"id":"erc-6551-token-identity-constant","constraint":"The token() identity returned by an account must not change over time.","appliesTo":"account-implementation","normativity":"normative","specQuote":"The return value of this function MUST be constant - it MUST NOT change over time.","specSection":"Specification — Account Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#account-interface","designImplication":"Bind inventory and authority views to the account's returned chain, token contract, and token ID, and flag an implementation that changes that identity."},{"id":"erc-6551-signer-magic-value","constraint":"isValidSigner returns magic value 0x523e3260 when the signer is valid.","appliesTo":"account-implementation","normativity":"normative","specQuote":"* MUST return the bytes4 magic value 0x523e3260 if the given signer is valid.","specSection":"Specification — Account Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#account-interface","designImplication":"Use the account's signer-validation result before enabling execution and show the validating account context in the confirmation."},{"id":"erc-6551-holder-authority","constraint":"By default, the holder of the bound NFT is considered a valid signer for the token-bound account.","appliesTo":"application","normativity":"normative","specQuote":"* By default, the holder of the non-fungible token the account is bound to MUST be considered\n* a valid signer.","specSection":"Specification — Account Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#account-interface","designImplication":"Explain the authority relationship between NFT holder and account signer. Do not display account-held assets as though they were controlled by an unrelated wallet without checking current NFT ownership and implementation rules."},{"id":"erc-6551-account-execution","constraint":"A token-bound account must expose an execution interface for valid signers and signal that support through ERC-165.","appliesTo":"account-implementation","normativity":"normative","specQuote":"All token bound accounts MUST implement an execution interface which allows valid signers to execute arbitrary operations on behalf of the account. Support for an execution interface MUST be signaled by the account using ERC-165 interface detection.","specSection":"Specification — Execution Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#execution-interface","designImplication":"Treat account execution as a high-impact capability. Show the selected token-bound account, valid signer, target, and operation before allowing asset movement."},{"id":"erc-6551-owned-registry-risk","constraint":"An owned or upgradeable registry can expose counterfactual account assets to loss, so applications must include registry security in their model.","appliesTo":"application","normativity":"rationale","specQuote":"Without a canonical registry, some token bound accounts may be deployed using an owned or upgradable registry. This may lead to loss of assets stored in counterfactual accounts, and increases the scope of the security model that applications supporting this proposal must consider.","specSection":"Rationale — Singleton Registry — Trustless Deployments","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#trustless-deployments","designImplication":"Warn when a token-bound account comes from a noncanonical, owned, or upgradeable registry. Do not treat a computed address as trustless without checking its registry assumptions."},{"id":"erc-6551-nft-compatibility-scope","constraint":"The proposal does not require a registry ERC-165 check for ERC-721 compatibility, and semi-fungible or fungible token uses are outside its stated scope.","appliesTo":"application","normativity":"backwards-compatibility","specQuote":"Additionally, this proposal does not require the registry to perform an ERC-165 interface check for ERC-721 compatibility prior to account creation. This maximizes compatibility with non-fungible token contracts that pre-date the ERC-721 standard (such as CryptoKitties) or only implement a subset of the ERC-721 interface (such as ENS NameWrapper names). It also allows the system described in this proposal to be used with semi-fungible or fungible tokens, although these use cases are outside the scope of the proposal.","specSection":"Backwards Compatibility","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#backwards-compatibility","designImplication":"Do not label every registry-created account as an ERC-721-bound account without inspecting the selected token and deployment context."},{"id":"erc-6551-sale-state-recheck","constraint":"Marketplaces should protect sales by checking token-bound account state or asset commitments at fulfillment.","appliesTo":"application","normativity":"security-considerations","specQuote":"To mitigate fraudulent behavior by malicious account owners, decentralized marketplaces SHOULD implement protection against these sorts of scams at the marketplace level. Contracts which implement this EIP MAY also implement certain protections against fraudulent behavior.\n\nHere are a few mitigations strategies to be considered:\n\n- Attach the current token bound account state to the marketplace order. If the state 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.\n- Attach a list of asset commitments to the marketplace order that are expected to remain in the token bound account when the order is fulfilled. If any of the committed assets have been removed from the account since the order was placed, consider the offer void. This would also need to be implemented by the marketplace.","specSection":"Security Considerations — Fraud Prevention","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#fraud-prevention","designImplication":"Recheck account contents and committed assets at settlement. A sale preview must not promise inventory that the token-bound account owner can withdraw before fulfillment."},{"id":"erc-6551-ownership-cycle-risk","constraint":"Ownership cycles can make both an NFT and the assets in its token-bound account permanently inaccessible.","appliesTo":"application","normativity":"security-considerations","specQuote":"All assets held in a token bound account may be rendered inaccessible if an ownership cycle is created. The simplest example is the case of an ERC-721 token being transferred to its own token bound account. If this occurs, both the ERC-721 token and all of the assets stored in the token bound account would be permanently inaccessible, since the token bound account is incapable of executing a transaction which transfers the ERC-721 token.\n\nOwnership cycles can be introduced in any graph of n>0 token bound accounts. On-chain prevention of cycles with depth>1 is difficult to enforce given the infinite search space required, and as such is outside the scope of this proposal. Application clients and account implementations wishing to adopt this proposal are encouraged to implement measures that limit the possibility of ownership cycles.","specSection":"Security Considerations — Ownership Cycles","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#ownership-cycles","designImplication":"Warn before transfers that create token/account cycles and provide a graph-aware recovery or cancellation state. Do not treat a token-bound recipient as automatically safe to send back into itself."},{"id":"account-state-change-signal","constraint":"The account state value SHOULD be modified each time the account changes state.","appliesTo":"account-implementation","normativity":"normative","specSection":"Specification > Account Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#account-interface","designImplication":"Use the state value to invalidate stale sale or asset previews, while preserving an explicit unknown state when an implementation does not expose reliable change tracking.","specQuote":"* @dev Returns a value that SHOULD be modified each time the account changes state."},{"id":"account-authorization-variance","constraint":"Token-bound accounts MAY add authorization logic that invalidates the NFT holder or grants authority to other signers.","appliesTo":"account-implementation","normativity":"normative","specSection":"Specification > Account Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#account-interface","designImplication":"Resolve and show the actual signer and authorization rule before execution; do not assume the current NFT holder is the only valid signer.","specQuote":"* Accounts MAY implement additional authorization logic which invalidates the holder as a\n     * signer or grants signing permissions to other non-holder accounts."},{"id":"execution-interface-variation","constraint":"Token-bound accounts MAY support the listed execution interface, add other operations, or restrict a signer's operations.","appliesTo":"application","normativity":"normative","specSection":"Specification > Execution Interface","specUrl":"https://ercs.ethereum.org/ERCS/erc-6551#execution-interface","designImplication":"Feature-detect the exact execution interface and operations, show signer scope, and provide an unsupported-action state instead of assuming universal account control.","specQuote":"Token bound accounts MAY support the following execution interface:"}],"summary":"ERC-6551 defines a registry that computes deterministic token-bound account addresses for NFTs and can deploy them as smart-contract accounts. A deployed or counterfactual account can hold assets, but each NFT may have multiple accounts across implementations, registries, chains, and salts; sale contents must be rechecked at settlement.","partialDeployment":{"body":"ERC-6551 is Review. Treat token-bound accounts as conditional on the selected registry, implementation, chain, token, salt, deployment state, and wallet/client support; verify account contents again at settlement."},"applicability":{"whenToUse":["Your product addresses: game characters and inventory disconnected.","Your product addresses: nFT profiles can't hold assets.","The flow should deliver: character-associated inventory can be shown and included in a sale only after the selected account contents are rechecked.","Inventory or transfer UI must show quantities and support multi-item actions."],"whenToAvoid":["The product has no NFT-controlled account or asset-management use case.","You cannot verify the chosen registry, implementation, deployment path, and account authority.","The sale flow requires a guaranteed inventory that its settlement mechanism cannot enforce."]},"designerTakeaways":["Show assets held by a selected token-bound account and label whether the address is computed or deployed.","Design a recipient-selection flow around a chosen registry, implementation, chainId, token, and salt; one NFT may have multiple accounts.","Recheck the selected account contents at settlement and distinguish NFT ownership from account-held assets."],"problemsSolved":[{"problem":"Game characters and inventory disconnected","oldWay":"Character is one NFT, items are separate, manually bundle for sale","newWay":"Character-associated account can hold items; a sale must state and recheck which contents are included","impact":"critical"},{"problem":"NFT profiles cannot hold assets","oldWay":"A PFP NFT is treated as only an image.","newWay":"A selected token-bound account can hold assets when the registry, implementation, and account path support it.","impact":"high"},{"problem":"Tracking what belongs to an NFT is ambiguous","oldWay":"Off-chain databases or a single assumed TBA hide which account was used.","newWay":"Show the selected registry, implementation, chainId, token, salt, and the resulting account address.","impact":"high"},{"problem":"NFT trading doesn't include accessories","oldWay":"Buy ape, separately negotiate for hat, shirt, chain","newWay":"Show whether the selected account still holds the hat and whether the sale commits that account content","impact":"medium"},{"problem":"Proving ownership history of nested assets","oldWay":"Trust marketplace metadata, often wrong","newWay":"On-chain trail: this sword was owned by THIS hero","impact":"medium"}],"uxPatterns":[{"name":"NFT Inventory View","description":"Show what an NFT owns inside its wallet","userFlow":["User selects NFT in collection","App fetches NFT's token bound account","Queries account for owned assets","Displays inventory and balances","User can manage items"]},{"name":"Send to NFT","description":"Send assets directly to an NFT's wallet","userFlow":["User selects \"Send to NFT\"","Enters NFT ID or scans","App resolves token bound account","Shows ownership warning","User confirms send"]},{"name":"NFT Marketplace with Inventory","description":"List NFTs showing what's bundled inside","userFlow":["Marketplace lists NFT for sale","Fetches NFT's TBA contents","Shows a time-stamped bundle value estimate","Buyer sees the selected account address and recheck requirement","Settlement rechecks which assets remain in that account"]},{"name":"Airdrop to NFT Holders","description":"Send rewards directly to NFTs, not wallets","userFlow":["Project selects a collection and target registry","Chooses implementation, chainId, and salt policy","System computes or resolves each selected account","Preview lists the exact account addresses and current balances","Batch sends only to the selected account set after recipient review"]}],"uiComponents":[{"name":"TokenBoundAccountView","description":"Display contents of the selected token-bound account, with its implementation, registry, chain, and salt context.","states":["loading","empty","has-assets","error"],"props":["nftContract","tokenId","chainId"]},{"name":"NFTInventory","description":"Grid/list of assets held by a selected token-bound account; show the account parameters and query context.","states":["loading","empty","populated"],"props":["tbaAddress","onSelect","onTransfer"]},{"name":"SendToNFTForm","description":"Form to send assets to a selected token-bound account after resolving its implementation, registry, chain, and salt.","states":["input","resolving","ready","sending","complete"],"props":["asset","onSend"]},{"name":"BundleValueEstimate","description":"Estimate the value of a selected NFT plus account contents from available data; label partial coverage and do not imply a complete valuation.","states":["calculating","ready","partial-data"],"props":["nftValue","bundledAssets[]"]},{"name":"TBACreator","description":"Create the selected token-bound account through its registry when it is not deployed; multiple accounts may exist for one NFT.","states":["checking","not-created","creating","exists"],"props":["nftContract","tokenId","implementation"]}],"antiPatterns":[{"pattern":"Not showing TBA contents on NFT detail pages","why":"Buyers don't know what they're getting","instead":"Show the selected account's contents before purchase and recheck them at settlement","severity":"critical"},{"pattern":"Allowing send to NFT without ownership warning","why":"User sends to NFT thinking owner will get it; NFT sells, assets gone","instead":"Clear warning: \"Goes to NFT, not current owner\"","severity":"critical"},{"pattern":"Assuming all NFTs have TBAs","why":"The registry can compute a counterfactual address before deployment, and assets can be sent there before code exists","instead":"Show computed versus deployed status, then offer createAccount only when the selected implementation and registry are verified","severity":"high"},{"pattern":"Hiding that NFTs can own assets","why":"Users don't realize their NFT has unclaimed value","instead":"Notify only from verified account reads, and identify the registry and implementation that produced the address.","severity":"high"},{"pattern":"Not valuing bundled assets in listings","why":"Mispriced NFTs, buyer/seller confusion","instead":"Show estimated bundle value alongside NFT price","severity":"medium"},{"pattern":"Using technical term \"Token Bound Account\"","why":"Users don't understand what it means","instead":"\"NFT Wallet\", \"NFT Inventory\", \"What's Inside\"","severity":"medium"}],"onMonad":[{"aspect":"Account type","ethereum":"A deployed token-bound account is a contract account associated with an NFT.","monad":"A token-bound contract account is not an EOA. Do not apply a universal 10 MON EOA reserve deduction to its inventory; check the actual transaction sender and execution path.","designImplication":"Verify the registry and account deployment on the selected network. Display the account's assets separately from fees and restrictions that affect the action."}],"keyTakeaways":["ERC-6551 computes or deploys selected token-bound accounts through a registry.","An NFT may have multiple accounts across implementations, registries, chains, and salts.","Show the chosen account parameters and contents before a send or sale.","Warn users when sending to an NFT account rather than its current owner.","Recheck account contents at settlement; do not promise one universal account per NFT."],"technicalNotes":"ERC-6551 defines a registry with account() for computing and createAccount() for deploying deterministic ERC-1167 token-bound accounts. Counterfactual accounts can receive assets before deployment. The address depends on implementation, token contract, token ID, chain ID, and salt, and multiple accounts can exist for one NFT across implementations or registries. Accounts MUST support ERC-165 and ERC-1271 plus an execution interface signaled through ERC-165; the IERC6551Executable.execute() interface is optional, and implementations may choose another interface or restrict operations and signers. Recheck account contents before promising a sale bundle.","sources":[{"label":"Monad reserve-balance rules","url":"https://docs.monad.xyz/developer-essentials/reserve-balance","type":"reference"},{"label":"Official ERC-6551 specification","url":"https://ercs.ethereum.org/ERCS/erc-6551","type":"official-spec"}],"lastUpdated":"2026-09-18","lastReviewed":"2026-09-18"},"sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-6551","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=ERC-6551","type":"discussion"},{"label":"Monad reserve-balance rules","url":"https://docs.monad.xyz/developer-essentials/reserve-balance","type":"reference"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-6551","markdown":"https://www.eipsfordesigners.com/standards/ERC-6551/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-6551/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-6551","official":"https://ercs.ethereum.org/ERCS/erc-6551","discussion":"https://ethereum-magicians.org/search?q=ERC-6551"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}