EIP-5633: Composable Soulbound NFT, EIP-1155 Extension

I’ve thought of a similar protocol before. In addition to games, there are many other application scenarios. For example, in crypto city, the property rights of citizens’ houses and vehicles are applicable to non-soulbound NFTs, while educational experience and citizen points can be used as soulbound NFTs.

EIP-5192: Minimal Soulbound NFTs is now final. Maybe this interface can be adopted for EIP-1155 to solve your use case?

1 Like

Thanks! I think it’s a good idea, I’ll check out EIP-5192 and see if it’s possible.


Thanks for reply. It’s a pretty good application scenario.

Contrary to EIP-5192, 5633 solves the problem with well-written and thought-out code. The solution proposed here in 5633 is much better and should and could stand alone.

I would prefer if every soul-bound interface is not itself soul-bound to an EIP that is a less-than-ideal developer, user, aggregate, and analyst experience.

For all soul-bound proposals that address the existing token specification of ERC1155s, 5633 is the best thought-out and most realistic.

Very big supporter of this implementation, thank you, @HonorLabs and I look forward to seeing this EIP progress!

The act of this coming in an extension is a great choice. Yet, with 1155s, they carry one distinct nuance in that batch transfers are a default supported function which means now batchTransferFrom has 2 very costly for-loops to run.

Is there an existing reference implementation of adding this functionality directly into the transfer loop to illustrate that cost impact does not “have to be” high?



 event Soulbound(uint256 indexed id, bool bounded);

the past form of “bind” is “bound”


The verbiage of an EIP can easily be updated :slight_smile:

For verbosity, 5633 serves the problem better than 5192 by removing two specific events that create a long runway for usage and adoption issues.

Based on the fact that wording is your only note of resolve here, I presume you are also in support of 5633?

In this case, all EIP-1155 functions of the contract that transfer the token from one account to another MUST throw, except for mint and burn.

Does this mean a soulbound token can always be burned?

The EIP-5633 implementation overrides function _beforeTokenTransfer of OZ but OZ uses this function in e.g. burn, so that’d mean the reference implementation and the specification are divergent: openzeppelin-contracts/ERC1155.sol at master · OpenZeppelin/openzeppelin-contracts · GitHub

While antithetical to the idea of a psuedonym-bound token, constant forfeiture prevents tokens from becoming scarlet letters as well as absolves all need of token-breaking standards such a consensual minting.

Generally in EIPs, when something is not included in a must, that means it is a CAN such as:

In this case, all EIP-1155 functions of the contract that transfer the token from one account to another MUST throw, except for mint and burn that CAN throw depending on implementation details.


We are very glad you like this proposal, it’s an honor. Our intention is to propose a protocol that is more practical in the real world. Gas cost analysis and optimization is an important task in our next update.

We implement Non-Transferable logic in the function _beforeTokenTransfer, because it’s a most suitable place, the function is called by the three main functional logic: burn, transfer and mint.

User CAN decide whether the token is burnable or not depends on the implementation.

Very precise description, thank you! :clap: :clap:

What are your thoughts in explicitly making it EIP-721 compatible as well? I don’t love the idea of two separate standards for EIP-721 and EIP-1155 when it can serve both.


I think so too. I posted the proposal that is strongly inspired by EIP-5192 and have a similar interfaces. Please take a look.

1 Like

Since EIP5192 is already final it doesn’t make much sense to have both a locked and a isSoulbound function that do the same thing.

1 Like

If all tokens in a contract are soulbound by default, isSoulbound(uint256 id) should return true by default during implementation.

I think the function should throw if the id does not exist using the same pattern as other standards.

The problem with this proposal, as well as with EIP5192, is that they assume that the status of the token switches from transferable to non-transferable and vice versa following a transaction that emits an event. However, this may not always be the case. In the gaming industry, for example, an NFT’s status can change many times a day without any transactions, simply due to changes in context. As a result, the most reliable way to determine whether an NFT is transferable or not is to call a view function.
It is not feasible to implement an interface that requires an event in such scenarios.
So, I believe that events should be removed from this interface. Additionally, I think that the name of the function should be more direct, such as isTransferable, however I could survive to different name :slight_smile:

@HonorLabs I’d be happy to adjust EIP-5633 to use the same nomenclature as EIP-5192 (function locked and Locked and Unlocked events and send a PR on GitHub. Is that interesting to you?


I have the same problem as @sullof. Is removing the event an option for you?

It would make a lot of sense if EIP5633 extends EIP5192.