ERC: Universal RWA Interface

This proposal introduces a minimal, standardized interface for Real World Asset (RWA) tokenization that is designed to be maximally compatible across existing token standards such as ERC-20, ERC-721, and ERC-1155. It focuses on providing only the essential compliance and enforcement functions common to regulated assets, without imposing specific implementation patterns or additional optional features.

Non-essential capabilities like pausing, metadata handling, or identity integrations are intentionally excluded from the standard, as they tend to be opinionated and vary greatly depending on the specific RWA use case. This approach ensures broad interoperability and minimal friction for adoption while allowing developers to extend functionality as needed within their own contracts.

4 Likes

A very basic reference implementation can be found at

Thanks for the comment @magicians

I fully agree that RWA is a too broad spectrum.

A key challenge is that each type of RWA possesses unique characteristics that necessitate specific on-chain capabilities for proper representation. Consider tokenized shares: they require features like dividend distribution, which implies a need for the token contract to track historical balances. Additionally, shares are often non-fractional, a property not natively supported by a pure ERC-20 without custom additions. Carbon credits, by contrast, have different needs, such as robust metadata handling to accurately reflect emissions data and manage redemption. Varying regulatory requirements further differentiate what’s needed for compliance across different asset classes.

This analysis of diverse asset requirements, coupled with a review of current RWA tokenization standards, strongly suggested me that a monolithic approach is unsuitable. Instead, a modular and flexible architecture is paramount – one that identifies and focuses on the minimal common base layer required by all RWAs, allowing specific features and compliance modules to be built flexibly on top.

Curious to know your thoughts on the specific of the proposed interface

1 Like

First of all, great job on the proposal, it adds great value to make it token-agnostic.

I think it’s difficult to select which permissioning features to include and which to intentionally exclude from the standard.

If we’re aiming for a truly minimal implementation, one could argue that some parts can be omitted, as it could be reduced to a transfer-check standard. Similar to ERC-902 and ERC-1462.

  1. Exclude recall, and achieve the functionality through mint and burn. Specificity and simplicity are lost.
  2. Exclude isUserAllowed; the same functionality is achieved with isTransferAllowed. Error-handling specificity is lost.

I then believe there are two possible paths for this standard:

  1. Universal token transfer check, non-opinionated on the admin or functionality standpoint. Additional ERCs can be built on top to standardize whitelisting, pausing/unpausing, access-control, or other compliance mechanisms.
  2. Universal RWA token, with core token functionality embedded: forceTransfer/recall, freezeTokens, frozenBalance. Compliance functionality should be built on top, similarly to the previous option.

I believe a security/RWA/permissioned token standard should be opinionated on the core token functionality.

I propose the following changes:

  1. Add mint and burn methods to the interface. Specify that isUserAllowed(to) must be run on mint, and that isUserAllowed(from) must not be run on burn—T-REX-like.
  2. Specify that isUserAllowed(to) must be run on recall and that isUserAllowed(from) must not be run on recall.
  3. Add freezeTokens, unfreezeTokens, and frozenBalance methods, plus TokensFrozen and TokensUnfrozen events. In my experience, token freezing is always required by regulators. It can be implemented as a separate module, but if we assume isUserAllowed provides the necessary specificity, token freezing should be required too. burn and recall should unfreeze tokens as needed.
  4. Prepend errors with an ERCX prefix, similar to ERC-6093.
  5. Rename recall to forceTransfer, and Recalled to ForcedTransfer. Recalled has a meaning of returning or withdrawing; I would stick to the core action and call it a forced transfer, regardless of the underlying reason it’s used. This is obviously a nit.
2 Likes

Thanks a lot @tinom9 for your comments ! Those are extremely valuable.

I think out of the two options we’re converging on the idea of an Universal RWA token standard that includes key token-level functionalities but that is also maximally compatible and easy to integrate. Here are my responses to your suggestions and a few clarifying questions to continue the conversation:


Mint and Burn

Your proposal to include mint and burn functions makes sense in most cases to me, especially in asset classes like equity or tokenized commodities. However, some RWA implementations, such as fixed-supply debt instrument, require immutable supply characteristics. In these cases, mint and burn may not be applicable at all, or maybe only one of the two.

Would you consider making mint and burn a SHOULD requirement in the EIP? This would maintain flexibility for fixed-supply cases while still encouraging standardization for the majority of use cases. Also, specifying that isUserAllowed(to) applies to mint and isUserAllowed(from) is exempt for burn makes sense, will integrate this into the description.


Error Prefixes (ERCX)

I really liked your suggestion. I’ll go ahead and include it.


recall/forceTransfer Naming

I completely agree with renaming recall to forceTransfer. Other terms like confiscation, revocation, or recovery describe reasons, not the underlying action, which is indeed a forced movement of assets. But let’s consider also the next topic for the naming part.


Freeze Functionality

I’m on board with supporting freezing functionality, especially since regulatory requirements often mandate it. However, I’d like to clarify the functional distinction between freezeTokens and forceTransfer.

Would you say the difference is that:

  • freezeTokens keeps tokens in the wallet but locks them;
  • forceTransfer moves the tokens elsewhere?

If so, would it be reasonable to combine both functionalities into a single forceTransfer-like method using a flag (e.g., to address being same as from meaning a freeze or an extra parameter to differentiate between a freeze and a forcedTransfer) ?

(at this point I’d call this function more something like ā€œenforceā€ with no distinction whether is a forced transfer or a freeze).

Alternatively, do you think both freezing and forced movement are fundamentally distinct actions that regulators would want both to be present ? Is it one of the two more primitive than the other ?

Would love your thoughts on whether combining them makes sense or if we should define them separately.


Thanks again for the constructive discussion!

burn

I don’t see a use case where the burn method wouldn’t be necessary for a security or RWA. Pessimistically, every asset should be liquidable at some point, and I only see that happening via the burn method.

For me, if included, it should be a MUST .


mint

Tokens must be minted at some stage. I think there’s a slight trade-off between minting flexibility (ERC20‑style) and standardization (a defined interface).

For me, if included, it should be a MUST , with a MAY revert for custom logic (e.g., when the max supply is reached).


freezeTokens / forceTransfer

I think forceTransfer main serves for court‑ordered or regulatory transfers—inheritances, seizures, etc.—so there’s almost always a recipient for the assets. It can also serve as a general administrative transfer function, and I don’t see any reason to discourage that use.

On the other hand, I see the freezeTokens method used to immobilize assets, during bankruptcy or insolvency proceedings, temporary protective orders, partial claims, etc., with the intention of either unfreezing or forcefully transferring them later.

I believe the debate isn’t so much about merging these functionalities as it is about whether freezing tokens is core enough to be part of the ERC interface. It could be implemented via transfer restrictions—tracking frozen balances in parallel and returning isTransferAllowed = false if the transfer exceeds the unfrozen balance.

I’d prefer built‑in freezing functionality in the standard, as I’ve found regulators in Europe consistently requiring it. However, I could also see the case for a separate freezing module, maybe a different ERC, if making this one leaner is a priority.


Great job, again!

1 Like

Thanks @tinom9 for the follow up !

I’ve done the following changes:

  • Changed errors names to adapt to ERC-6093.
  • Renamed recall to forceTransfer and Recalled to ForcedTransfer.
  • Addressed your feedback on the implementations and examples.

I’ve also adjusted the statements in what integrators should do for transfers,minting and burning. However I still didn’t include the mint and burn functions for the arguments below.

Been thinking about it for the last two days and slightly discussed this also with @frangio and here some argument that I think still holds for not including those functions within this standard:

  • Minting works differently for ERC-20 vs ERC-721/ERC-1155 in the sense that the former doesn’t perform checks on the recipient while the latter usually do.
  • Given the different needed parameters (ie amounts and/or tokenIds), building up a standard function interface for all three kind of tokens might sound as redefining how a minting function should look like for an ERC-20 or an ERC-721.
  • As previously mentioned, fixed-supply debt might represent an use case where an external or public minting function is not needed, and the supply is determined at constructor time. Additionally, liquidating an RWA doesn’t necessarily imply burning them, as secondary market can make them tradeable against stables or other RWAs. Additionally burning might even be prohibited and not necessary for a use case (ie, is it legit to burn tokenized shares ?)

All of this makes me think that a mint and burn function for regulated assets in the form of ERC-20 / ERC-721 / ERC-1155 might be the scope for another standard and might not be extremely necessary to include it here.

Happy to know both of your thoughts @frangio @tinom9

1 Like

Thanks again @xaler!


mint / burn

In terms of mint and burn, I stand on burning, theoretically, being needed in every asset, as any could be liquidated (shares rebuying, company closure/bankruptcy).

Minting should also happen at some point of the lifecycle and I see a point on enforcing fixed-supply through reverts, as opposed to only through constructor mints.

Nonetheless, I believe there are obvious trade-offs for multi-standard token compatibility that, even if up to some extent are implied in this ERC (already using tokenId and amount), as it aims to be universal, can entangle the implementation.

I am onboard with excluding them to keep the standard simple.


freezeTokens

If we exclude mint and burn, I think there is a stronger point to consider excluding freezing functionality, in favor of a leaner ERC.

Nonetheless, it’s still an inclusion for me, and I’d be more than happy to propose an implementation in the Github PR, if you’re up to it.


Universality

Making this standard universal is a challenge per se, and I see two paths upcoming for common functionality:

  1. Different tokens using different interfaces for common logic:
    • mint(address to, uint256 amount)
    • mint(address to, uint256 tokenId)
    • mint(address to, uint256 tokenId, uint256 amount)
  2. Different tokens converging to a common interface:
    • mint(address to, uint256 tokenId, uint256 amount)

Only if we expect tokens converging to a common interface, it makes sense to standardize it. And, in that case, although I believe it’s marginally better to include it in the ERC, it’s still valid to standardize it in a different ERC. This applies to both points above.


Cheers!