ERCs icon indicating copy to clipboard operation
ERCs copied to clipboard

Add ERC: uRWA - Universal Real World Asset Interface

Open xaler5 opened this issue 7 months ago • 2 comments

This EIP defines a minimal and implementation-agnostic interface for Real World Assets (RWAs), intended to unify compliance-related functionality across ERC-20, ERC-721, and ERC-1155 tokens. The interface introduces core primitives (recall, isUserAllowed, isTransferAllowed) that support regulated token use cases, such as enforcement actions and transfer restrictions, without prescribing how those policies are implemented.

The standard deliberately omits non-essential and opinionated features such as role-based access control, metadata handling, pausing, or on-chain identity mechanisms. These are left to implementers to integrate as needed, enabling maximum flexibility and reducing surface area for unnecessary gas costs or over-specification. This promotes composability and ease of integration across DeFi and institutional applications without compromising base token behavior.

Author: @xaler5 Discussion: https://ethereum-magicians.org/t/erc-universal-rwa-interface/23972

xaler5 avatar May 01 '25 07:05 xaler5

✅ All reviewers have approved.

eip-review-bot avatar May 01 '25 07:05 eip-review-bot

I believe it's good enough as Draft, will keep playing with implementations while waiting for any feedback.

xaler5 avatar May 23 '25 10:05 xaler5

I leave a list of suggestions backed by the PR I proposed at the implementation repository (https://github.com/xaler5/uRWA/pull/1).

  1. Rename FrozenChange to Frozen for clarity. IMHO, "change" is redundant: why else would you be emitting an event?
    /// @notice Emitted when `setFrozen` is called, changing the frozen `amount` of `tokenId` tokens for `user`.
    /// @param user The address of the user whose tokens are being frozen.
    /// @param tokenId The ID of the token being frozen.
    /// @param amount The amount of tokens frozen.
    event Frozen(address indexed user, uint256 indexed tokenId, uint256 indexed amount);
    
  2. Rename ERC7943NotAvailableAmount to ERC7943InsufficientUnfrozenBalance for consistency with ERC-6093's ERC20InsufficientAllowance, ERC20InsufficientBalance, ERC721InsufficientApproval, ERC1155InsufficientBalance, and ERC1155InsufficientApproval.
  3. Redefine ERC7943InsufficientUnfrozenBalance / ERC7943NotAvailableAmount to not throw in cases where ERC-6093's ERC20InsufficientBalance or ERC1155InsufficientBalance would throw, to improve error specificity.
    /// @notice Error reverted when a transfer is attempted from `user` with an `amount` less or equal than its balance, but greater than its unfrozen balance.
    /// @param user The address holding the tokens.
    /// @param tokenId The ID of the token being transferred. 
    /// @param amount The amount being transferred.
    /// @param available The amount of tokens that are available to transfer.
    error ERC7943InsufficientUnfrozenBalance(address user, uint256 tokenId, uint256 amount, uint256 available);
    
  4. Require that force transfers unfreeze tokens before executing the transfer, so that no Transfer event is emitted with more tokens that are unfrozen for the sender, before a Frozen / FrozenChange event.
    + MUST bypass freezing validation and update the freezing status if required, emitting a `Frozen` event before the `Transfer` and `ForceTransfer` events.
    - SHOULD bypass the freezing validations and update the freezing status accordingly after applying the state changes. If this happens it MIGHT emit a FrozenChange event accordingly.
    
  5. Require (or recommend) that burning unfreezes tokens instead of reverting due to ERC7943InsufficientUnfrozenBalance / ERC7943NotAvailableAmount.
    + Burning MUST run validation to prohibit burning more assets than the ones available.
    + Burning MUST bypass freezing validation and update the freezing status if required, emitting a `Frozen` event before the `Transfer` event.
    - Burning SHOULD run validation to prohibit burning more assets than the one available (difference between balance and frozen amount).
    
  6. Recommend that error specificity is prioritized, that is, broad errors such as ERC7943NotAllowedTransfer should be thrown after more specific ones such as ERC7943InsufficientUnfrozenBalance / ERC7943NotAvailableAmount or ERC7943NotAllowedUser.

tinom9 avatar May 28 '25 17:05 tinom9

Thank you so much @tinom9 for this in deep analysis and for contributing at making this better.

  • 1 agree.
  • 2 As mentioned here I believe "inssuficient" suggest a general lack of funds while "unavailable" better express temporary conditions not necessary related to a lack of funds. Wdyt ?
  • 3 Agree but this is impementation specific since those more specific errors are outside of the scope for this EIP. Are you suggesting putting a guideline in the EIP draft itself about it ?
  • 6 Agreed. Again here, probably adding a guideline for it in the EIP draft would do the job ?

For 4. and 5. I also provided some argumentsin the Eth magician reply, if you can take a look.

looking forward to keep discussing about it :muscle:

xaler5 avatar May 29 '25 15:05 xaler5

The commit f71ee58e4f07377315b9a858874c27d01101361f (as a parent of 0f8daaacc3f312093bb1dda07b1047d4997565cc) contains errors. Please inspect the Run Summary for details.

github-actions[bot] avatar Jun 02 '25 19:06 github-actions[bot]

Thanks @SamWilsn for great feedback. I've incorporated some changes. Fell free to mark as resolved anything you find good now or to iterate :)

xaler5 avatar Jun 10 '25 18:06 xaler5

Thanks @tinom9

  • Generalized "transfer" event instead of Transfer
  • Added specification of isTransferAllowed in need of calling isUserAllowed in from and to
  • Reverted the Frozen event to not have previous value emitted, only the new one is emitted now (This to reflect latest response in eth magicians forum).

xaler5 avatar Jun 20 '25 09:06 xaler5