The Lab

Nº 02 05 · 2026 7 min read

Tokenizing a real-world asset is the fun part. ERC-3643, ONCHAINID, and the boring machinery that decides whether a transfer is even allowed to happen.

Tokenizing a real-world asset is a two-line story in every pitch deck: mint a token, back it with the asset, done. The token is trivial. An ERC-20 is a hundred lines you could write in your sleep.

The part that’s actually hard — the part that determines whether the thing is a compliant security or a lawsuit — is the layer that sits in front of every transfer and decides whether that transfer is even permitted. That’s what ERC-3643 (the T-REX standard) is really about, and it’s the least glamorous, most important code in the whole system.

I learned this building a security-token platform for fractional ownership of a real, regulated reserve. Here’s the mental model that finally made it click.

An ERC-20 asks “can I move?” and always says yes

A normal token transfer is unconditional. transfer(to, amount) succeeds if you have the balance. That’s a feature for money and a catastrophe for a security, where who can hold the token is a legal question with real answers: accredited investors only, no sanctioned addresses, jurisdiction limits, lockup periods.

ERC-3643 inverts the default. Every transfer is gated by a question:

function transfer(address to, uint256 amount) public override returns (bool) {
    require(identityRegistry.isVerified(to),        "receiver not verified");
    require(compliance.canTransfer(msg.sender, to, amount), "compliance blocked");
    return super.transfer(to, amount);
}

Two gates, and neither one is about balances. The first asks: does this address belong to a verified identity? The second asks: do the rules of this specific token allow this specific transfer right now? Both can say no. A security token that can’t say no isn’t a security token.

A permissionless token asks nothing before it moves. A compliant one refuses by default and grants access deliberately. That inversion is the entire point.

Identity is a passport, not an allowlist

The naive version of “who can hold this” is an allowlist mapping. It falls apart the instant you have a second token, because now the same investor needs re-verifying everywhere, and revocation means editing N contracts.

ONCHAINID models it the way the real world does: each investor has one on-chain identity contract — a passport — and regulated claims get stamped into it by trusted issuers. “KYC-passed,” issued by a licensed KYC provider. “Accredited investor,” issued by whoever is legally allowed to attest that. The token doesn’t store who’s allowed; it asks the identity registry whether the receiver’s passport carries the stamps this token requires.

// The token trusts CLAIM TOPICS, not addresses.
// Topic 1 = KYC, Topic 2 = accreditation, issued by trusted claim issuers.
uint256[] memory required = identityRegistry.requiredClaimTopics();

The elegance is in the indirection. Revoke an investor’s KYC claim once, on their identity, and they’re instantly untradeable across every token that trusts that claim topic. One stamp, global effect. That’s an actual regulatory requirement — “freeze this holder” — expressed as data, not as a redeployment.

Compliance is modular for a reason

The second gate, canTransfer, is where the token-specific rules live: max holders, per-investor caps, country restrictions, transfer cooldowns. The instinct is to hard-code these into the token. The standard’s insistence on making them pluggable modules felt like over-engineering until the rules changed.

Because they always change. A fund reclassifies. A jurisdiction opens or closes. Regulators add a holding-period rule mid-flight. With compliance baked into the token, every rule change is a migration of the asset itself. With modules, it’s adding or removing a small contract from the compliance suite while the token — and everyone’s balances — sit untouched.

// Rules are contracts you bind and unbind, not immutable token logic.
compliance.addModule(maxHoldersModule);
compliance.addModule(countryRestrictModule);
// A rule sunsets? Unbind it. The token never redeploys.

The NAV oracle: where on-chain meets a spreadsheet

None of the above helps with the question every investor actually asks: what is my fraction worth? For a real asset, that value lives off-chain — an audited reserve, a periodic valuation, a number a human signs off on.

So the last piece is an oracle that pushes net asset value on-chain on a schedule, and the discipline is entirely in the trust boundary: who’s allowed to write the number, how stale is too stale, what happens to redemptions when the feed goes quiet. The smart-contract code is easy. Deciding whose signature counts as truth is the hard, human part — the same trust question that ONCHAINID answers for identity, just pointed at price instead.

The takeaway

The token was the smallest file in the repository. The compliance suite, the identity registry, the claim issuers, the NAV oracle — that’s the actual product, and it’s the part that maps one-to-one onto real regulation. If you’re evaluating an RWA project, don’t look at the token. Look at what it asks before it lets a transfer through. That question is the whole business.