Cover photo

Part 3 Tutorial: Tokenizing Using ERC-3643

In Part 1, we built a token that understands identity and compliance. In Part 2, we connected that system to the real world through oracles and offchain integrations.

At that point, we have something that works. But working is not the same as surviving.

So in this part, I'm gonna talk about what's missing what else you need to actually tokenize a local asset.

Security Fixes You Need to Know About

While building this, I found (and fixed) several critical issues that would have ruined your day in production:

1. Bank Run Prevention

finalizeRedemption() could credit withdrawals without checking if the contract has sufficient USDC.

The attack:

  1. Oracle finalizes 100 redemptions for $1M total

  2. Contract only has $100k USDC

  3. First 10 users withdraw successfully

  4. Next 90 users get transfer failed

  5. Their tokens are already burned

  6. They're rugged

fix:

// CRITICAL: Verify contract has sufficient USDC before crediting
uint256 contractBalance = i_usdc.balanceOf(address(this));
require(contractBalance >= usdcAmount, "insufficient contract balance");

2. Double-Redemption Prevention

The attack:

  1. User requests redemption (tokens burned)

  2. Oracle is slow, 8 days pass

  3. User cancels, gets tokens back

  4. Oracle finalizes redemption (still works!)

  5. User withdraws USDC

  6. User has BOTH tokens AND USDC

  7. Protocol is drained

fix:

// Check request hasn't expired (prevent double-redemption via cancel)
if (isRequestExpired(requestId)) {
    revert RedemptionManager__RequestExpired();
}

3. Decimal Precision

I call this the slow rug. But not really, it's just taking invisible conversion fees from your users.

The theft:

  1. Say, user has 1.999999999999999999 USDC (18 decimals) = $2

  2. Converts to 1.999999 USDC (6 decimals) = $1.999999

  3. Lost: $0.000001

  4. Over 1M redemptions: $1,000 stolen from users

fix:

// Round up instead of truncate to favor users (never underpay)
return (amount + 1e12 - 1) / 1e12;

Protocol absorbs the negligible rounding cost (<$0.000001 per withdrawal) instead of users. This is okay. I did a little research on this and figured this also is how traditional accounting systems work.

There are many more, but these are the common mistakes that might get missed by yer static analyzers.

What This Code Is Missing

While we may have done tackled the whole RWA architecture by now, there are still plenty of considerations that you need to take in mind before you run this in prod.

  1. Multisig Governance

This thing still runs on a single admin/agent keys. Get at least a 3-of-5 Gnosis Safe for all privileged operations.

  1. Circuit Breakers

Having circuit breakers require you to have a monitoring infrastructure and complex state management, but you need it. There must be a way to auto-pause the market on anomalies eg. >10% price moves, high redemption volume, etc.

  1. Real KYC/AML Integration

I have oversimplified the AMLA module on Part 1 to make it easily digestible. In reality, you need real-time sanctions screening, claim verification, chain analytics... and these require you to have licensed provider APIs and ongoing compliance.

  1. Custody Integration for Proof of Reserves

This actually requires legal agreements and enterprise accounts. We only have mock oracles in this tutorial.

  1. Brokerage API Integration

We have used manual oracles for simplicity, but it will be comedy if you try this in real life environments. Your brokerage first needs to have an API, and it must be accessible to you and support your stack.

If you want to launch this in production, you need:

  • 12-15 months of development, with prerequisites

  • 5-10 person team (engineers, compliance, operations)

  • A huge budget (modernity is expensive)

How to: Philippine RWA Tokenization

If you're looking to implement this with Philippine-based assets (PSE stocks, Pagibig bonds, real estate tokens), the regulatory landscape is still on its way. But structurally, here's what you need on the tech side:

  1. Brokerage API: for securities like in our tutorial, API from PSE-compatible brokers (COL Financial, BPI Trade, etc.), connect to the oracles.

  2. KYC Provider: I highly recommend we have a self-custodial DID system that is gated by National ID. This is another long topic! But if not, a traditional KYC system will work. Connect it to the IdentityRegistry contract.

  3. Custody: Local qualified custodian

  4. Regulatory registration and all legal matters (Sorry, can't help you on this one)

But architecture-wise and code-wise, things remain. Swap the API endpoints, update the KYC provider, get local legal counsel. The smart contracts don't care if you're tokenizing AAPL or Jollibee stock. 🍗

The Part Where I Tell You Not To Use This

This code is excellent for learning.
It shows you how identity plugs into tokens, why compliance can’t be an afterthought, how redemption actually works, and where oracles fit into the system.

But this code is NOT ready for production. It’s missing the parts that actually make a system survive.

So, what you can do now:

  1. Clone the repo and run the tests

  2. Modify the contracts for your use case

  3. Experiment with different compliance modules

  4. Understand the architecture before adding infrastructure

What you should NOT do with this tutorial:

  • Launch with real assets (seriously, don't)

  • Handle real user funds (I will find you)

  • Claim production-readiness (you will get sued)

  • Deploy to mainnet without modifications (you will get rekt)

If you're building a production RWA protocol and need help with architecture, security, compliance, or just plain need advice, reach out. I've been studying its patterns for a while, and I know where the bodies are buried.

Resources:

Danki's Full Tutorial code: Github Repo

ERC-3643 Standard: Docs

Chainlink Oracle: Docs

Patrick Collin's RWA Tutorial (Special thanks): Github Repo