This repository contains Solidity implementations of the uRWA (Universal Real World Asset) standard, a minimal interface designed for tokenizing Real World Assets (RWAs). It provides a common ground for regulatory compliance and control features often required for RWAs, while remaining compatible with existing token standards like ERC-20, ERC-721 and ERC-1155.
The smart contracts in this repository are unaudited and are provided for reference and educational purposes only. They have not undergone a formal security audit. Do NOT use this code in a production environment without a thorough professional audit. Use at your own risk.
The uRWA standard, as defined by IERC7943
, aims to provide essential functionalities for RWAs without imposing excessive complexity. Key features of the reference implementation and the IERC7943
interface include:
- Whitelisting: Control which addresses are allowed to interact with the token (see
isUserAllowed
fromIERC7943
andchangeWhitelist
in reference implementations). - Transfer Control: Define rules for when transfers are permitted (
isTransferAllowed
). - Asset Freezing: Control the ability to freeze and unfreeze portions of a user's token balance or specific token IDs (
setFrozen
,getFrozen
). - ForceTransfer Functionality: Allow authorized parties to forcibly transfer tokens, often necessary for regulatory compliance (
forceTransfer
). - Access Control: The reference implementations utilize role-based access control (via OpenZeppelin's
AccessControlEnumerable
) to manage permissions for sensitive actions like minting, burning, forced transfers, managing the whitelist, and changing freeze status.
The IERC7943
interface defines the following core components:
Functions:
forceTransfer(address from, address to, uint256 tokenId, uint256 amount)
: Forcibly moves tokens.setFrozen(address user, uint256 tokenId, uint256 amount)
: Modifies the amount of frozen tokens for a user.getFrozen(address user, uint256 tokenId) returns (uint256 amount)
: Queries the amount of frozen tokens.isTransferAllowed(address from, address to, uint256 tokenId, uint256 amount) returns (bool allowed)
: Checks if a standard transfer is permissible.isUserAllowed(address user) returns (bool allowed)
: Checks if a user is permitted to interact with the token.
Events:
ForcedTransfer(address indexed from, address indexed to, uint256 tokenId, uint256 amount)
: Emitted when tokens are forcibly transferred.FrozenChange(address indexed user, uint256 indexed tokenId, int256 amount)
: Emitted when the freeze status of a user's tokens changes.
Errors:
ERC7943NotAllowedUser(address account)
: Reverted if a user is not allowed for an interaction.ERC7943NotAllowedTransfer(address from, address to, uint256 tokenId, uint256 amount)
: Reverted if a transfer is not permitted by current rules.ERC7943NotAvailableAmount(address user, uint256 tokenId, uint256 amount, uint256 available)
: Reverted if a transfer attempts to move more tokens than are available (unfrozen).
This repository provides three primary implementations:
uRWA20.sol
: An ERC-20 compliant token implementing theIERC7943
interface.uRWA721.sol
: An ERC-721 compliant token implementing theIERC7943
interface.uRWA1155.sol
: An ERC-1155 compliant token implementing theIERC7943
interface.
For a detailed specification and rationale behind the uRWA standard, please refer to the draft EIP document: EIP-UniversalRWA.md
(which corresponds to IERC7943
).
This project uses the Foundry development toolkit.
- Clone the repository:
git clone https://github.com/xaler5/urwa.git
cd urwa
- Install dependencies (submodules):
forge install
Compile the contracts:
yarn build
Run the test suite and coverage:
yarn test
yarn coverage
This project is licensed under the MIT License - see the package.json file for details.