Skip to content
  1. Home
  2. ERC Standards
  3. ERC Standards
  4. ERC-7943 (uRWA) Explained: The Universal Real-World Asset Interface
ERC Standards

ERC-7943 (uRWA) Explained: The Universal Real-World Asset Interface

ERC-7943 (uRWA) is a minimal, Final interface for compliant RWA tokens across ERC-20, ERC-721 and ERC-1155: transfer checks, freezing and forced transfers. How it works and when to use it.

NUVZ Tokenization Team Updated 6 min read Technically reviewed

ERC-7943, the Universal Real-World Asset (uRWA) interface, defines the smallest common set of functions a compliant RWA token needs — eligibility checks, freezing and forced transfers — and lets you add them to an ERC-20, ERC-721, ERC-1155 or ERC-6909 token without adopting a full framework. It reached Final status in 2026 and was designed to align its naming with ERC-3643 and ERC-7518, so venues, wallets and custodians can integrate RWA tokens through one predictable interface.

Key takeaways

  • Three interface variants: fungible (ERC-20 based), non-fungible (ERC-721 based) and multi-token (ERC-1155 / ERC-6909 based), each detectable through ERC-165.
  • Core views: canSend, canReceive, canTransfer, getFrozenTokens. Core actions: forcedTransfer, setFrozenTokens.
  • It specifies what must be checked, not how — identity, whitelists or claims are your choice.
  • Public transfers must fail when canTransfer, canSend or canReceive return false, and canTransfer must account for frozen balances.

The interface (fungible variant)

function canSend(address account) external view returns (bool allowed);
function canReceive(address account) external view returns (bool allowed);
function canTransfer(address from, address to, uint256 amount) external view returns (bool allowed);
function getFrozenTokens(address account) external view returns (uint256 amount);
function setFrozenTokens(address account, uint256 amount) external returns (bool result);
function forcedTransfer(address from, address to, uint256 amount) external returns (bool result);

event ForcedTransfer(address indexed from, address indexed to, uint256 amount);
event Frozen(address indexed account, uint256 amount);

The ERC-721 variant freezes individual token IDs (setFrozenTokens(account, tokenId, bool)), and the multi-token variant freezes amounts per ID. Custom errors such as ERC7943CannotSend, ERC7943CannotReceive and ERC7943InsufficientUnfrozenBalance give integrators precise failure reasons.

Design principles

  • Minimalism. Only the functions needed for common compliance patterns; no identity framework, no modules.
  • Separation of concerns. canSend and canReceive check account eligibility independently, so you can allow an account to exit a position while blocking new receipts.
  • Single freeze setter. setFrozenTokens overwrites the frozen amount instead of separate freeze/unfreeze calls.
  • Compatibility. Names follow ERC-3643 conventions (forcedTransfer) to ease multi-standard integration.
Not sure which token standard fits your asset?Share your asset, investor base and jurisdictions — we will recommend a standard, chain and compliance model in a free 30-minute session.
Chat with an expert

When to use ERC-7943

  • You already use ERC-1155 or ERC-721 for an RWA programme and want standard compliance hooks — for example a property portfolio or carbon credit vintages on ERC-1155.
  • You run a platform issuing several token types and want venues and wallets to pre-check transfers the same way for all of them.
  • You need a light footprint — fewer contracts and lower gas than a full ERC-3643 deployment — and your eligibility logic is simple.
  • You are a venue or custodian wanting one integration path for diverse RWA tokens.

When ERC-3643 may still be better

If you need a ready-made identity model (ONCHAINID claims from trusted issuers), modular compliance rules and an established ecosystem of compliance tooling, ERC-3643 gives you more out of the box. The two are complementary: an ERC-3643 token can expose ERC-7943 functions too, although the spec notes ERC-3643’s canTransfer semantics differ slightly.

Implementation tips

  1. Implement checks in the internal update function so mint, burn and every transfer path are covered.
  2. Make canTransfer call canSend and canReceive and check unfrozen balances, as the spec requires.
  3. Restrict forcedTransfer and setFrozenTokens to an agent role on multisig; emit events for every use.
  4. Decide whether forced transfers bypass canReceive (e.g. to a recovery wallet) and document it.
  5. For ERC-721/1155 variants, use re-entrancy guards — receiver hooks run external code.
  6. Advertise support via supportsInterface with the correct interface ID.

Example: adding ERC-7943 to an ERC-20 token

// Illustrative fungible uRWA implementation — not audited.
contract URWAToken is ERC20, AccessControl, IERC7943Fungible {
    bytes32 public constant AGENT_ROLE = keccak256("AGENT_ROLE");
    IEligibility public eligibility;
    mapping(address => uint256) private _frozen;

    function canSend(address a) public view returns (bool) { return eligibility.allowedToSend(a); }
    function canReceive(address a) public view returns (bool) { return eligibility.allowedToReceive(a); }
    function getFrozenTokens(address a) public view returns (uint256) { return _frozen[a]; }

    function canTransfer(address from, address to, uint256 amt) public view returns (bool) {
        if (!canSend(from) || !canReceive(to)) return false;
        return balanceOf(from) >= _frozen[from] + amt; // only unfrozen balance is transferable
    }

    function setFrozenTokens(address a, uint256 amt) external onlyRole(AGENT_ROLE) returns (bool) {
        _frozen[a] = amt; emit Frozen(a, amt); return true;
    }

    function forcedTransfer(address from, address to, uint256 amt) external onlyRole(AGENT_ROLE) returns (bool) {
        require(canReceive(to), "receiver not eligible");
        // reduce frozen amount first if the forced transfer touches frozen tokens
        uint256 free = balanceOf(from) - _frozen[from];
        if (amt > free) { _frozen[from] -= (amt - free); emit Frozen(from, _frozen[from]); }
        _bypass = true; _transfer(from, to, amt); _bypass = false;
        emit ForcedTransfer(from, to, amt);
        return true;
    }

    bool private _bypass;
    function _update(address from, address to, uint256 amt) internal override {
        if (!_bypass && from != address(0) && to != address(0)) require(canTransfer(from, to, amt), "uRWA: not allowed");
        super._update(from, to, amt);
    }
}

(Production implementations would use the custom errors defined by the standard and handle mint/burn eligibility explicitly.)

Why a minimal interface matters for the market

The RWA ecosystem has many token designs: ERC-3643 securities, ERC-1155 portfolios, ERC-721 titles, bespoke fund tokens. Venues, wallets, custodians and DeFi protocols cannot integrate each one bespoke. A shared minimal interface lets them:

  • Pre-check transfers before submitting orders or settlement instructions.
  • Display frozen balances accurately to investors.
  • Recognise forced transfers in indexing and accounting.
  • Detect support through ERC-165 and adapt automatically.

Migration path for existing tokens

  1. Add the ERC-7943 functions through an upgrade (if your token is upgradeable) or a wrapper.
  2. Map existing whitelist/compliance logic into canSend and canReceive.
  3. Map existing freeze features into setFrozenTokens / getFrozenTokens.
  4. Emit the standard events for future actions.
  5. Advertise the interface ID and inform integrators.

Frequently asked questions

No. It is a minimal interface layered on an existing token standard. You still decide how eligibility is determined.

Yes. The multi-token variant is designed for ERC-1155 and ERC-6909, with freezing per token ID and amount.

It borrows ERC-3643’s naming for interoperability but stays framework-agnostic. A platform can use both.

It enforces the result of eligibility checks through canSend/canReceive. KYC itself happens off-chain with a regulated provider.

No. You may use whitelists, claims, verifiable credentials or any other mechanism behind canSend/canReceive.

It can express blacklist-style freezing and seizure in a standard way, but stablecoin regulation may impose additional requirements.

Written by the NUVZ Tokenization Team

NUVZ is the RWA and Web3 engineering brand of ESS ENN Associates (est. 1993). Our team has designed and shipped tokenization platforms for real estate, education loans, solar PPAs, energy, carbon credits, bank deposits and trade documents. About us · Case studies

This article is for general information only and is not legal, tax or investment advice. Token standards evolve — always confirm the current status of an ERC at eips.ethereum.org and take advice from qualified counsel in each jurisdiction before issuing tokens.

Keep reading

Related guides

All insights →

Get Expert Advice on Your Token Design

Questions about this standard or your own tokenization use case? Send us a note. A NUVZ engineer will reply within one business day.

Prefer a call? Pick a 30-minute slot with our team.

Book a 30-min expert call
  • Mutual NDA available before you share details
  • Reply within one business day
  • Your data is used only to answer your enquiry

Protected against spam. We never sell or share your data with third parties for marketing.

Chat with our experts