A confidential, automated RWA hub for institutions: bonds tokenized on ADI Chain, negotiated in Canton data rooms the rest of the market cannot see, paid on a Hedera schedule with no keeper, and reviewed by an AI on 0G that never signs.
π Finalist β ADI Foundation, Open Project Submission ($287) Β· ETHDenver 2026
Video demo Β· Specification Β· Bounty compliance Β· Demo guide
Institutions that tokenize bonds on a public chain show their positions to the whole market, pay coupons from a cron job on a server, and run risk analysis in spreadsheets that never see the ledger. Metaphor gives each of those jobs to the chain built for it, behind a single dashboard: issuance and access control on ADI Chain, confidential negotiation on Canton, coupon payments scheduled by the Hedera network itself, and risk analysis on 0G Compute with a human approving every recommendation. Four chains, one interface.
π Finalist on the ADI Foundation bounty at ETHDenver 2026, Denver, February 2026. One of the flagship Ethereum events of the year, with 186 projects submitted to its BUIDLathon. Three students from DeVinci Blockchain built Metaphor there for the New France Village track and four sponsor bounties at once (ADI Foundation, Canton Network, Hedera and 0G Labs), and it was named a finalist on ADI Foundation's $25,000 Open Project Submission bounty.
- How it works
- Four chains, one interface
- Architecture
- Deployed contracts
- What's live vs. simulated
- Getting started
- Tests
- Tech stack
- Repository structure
- Team
- License
The life of a tokenized bond, from issuance to coupon:
- Issue on ADI Chain. An issuer mints an ERC-20 through
RWATokenFactory, with the ISIN, coupon rate, maturity and issuer written on chain. A transfer only settles when both wallets are whitelisted, and a token can be fractionalized into sub-tokens. - Hold it in a vault.
VaultManagergroups tokens into vaults (create, deposit, withdraw, allocate) behind four on-chain roles, Admin, Issuer, Investor and Auditor, and an emergency pause. - Negotiate on Canton. The data room is a Daml contract. The owner sees everything,
counterparties see the composition and propose trades, an auditor holds a separate
AuditRightwith aggregate figures only, and for everyone else the contract does not exist. - Pay the coupons on Hedera.
CouponSchedulerregisters the bond, derives its payment dates and schedules each coupon from Solidity through the Schedule Service precompile at0x16b: the network itself calls the payment on its date, with no keeper and no cron job. A payment is all or nothing: without enough liquidity it is marked failed, never paid in part. The issuer then distributes the coupon pro rata to holders throughYieldDistributor, from a snapshot. - Review the risk on 0G. The AI engine sends the vault to 0G Compute and gets back a risk report validated against a schema: a global score, an analysis per position, stress tests and recommendations. Each recommendation waits for a human approval, and the AI has no signing authority.
Institutions come in as tenants: InstitutionRegistry gives each one its own isolated set of
contracts (access control, token factory, vault manager), and registering an institution takes two
admin approvals. Signing in is a wallet signature (EIP-191) exchanged for a 24-hour JWT whose roles are
read on chain.
| Layer | Where | What runs there |
|---|---|---|
| Issuance and access | ADI Chain (99999), also on Sepolia | InstiVaultAccessControl (four roles, whitelist) Β· RWAToken Β· RWATokenFactory Β· VaultManager Β· InstitutionRegistry (white-label tenants, two approvals) Β· InstitutionDeployer |
| Confidentiality | Canton (Daml) | nine templates in three modules: ConfidentialVault (vault, invitation, access right, trade request, settlement), PrivateTrade (multi-round offers, agreement), AuditRight (invitation, aggregate-only view) |
| Automation | Hedera Testnet | CouponScheduler (payment dates, scheduling through IHRC755 and IHRC1215) Β· YieldDistributor (snapshot, pro-rata claims) |
| Intelligence | 0G Compute | ai-engine: risk analyzer, strategy simulator and stress tests, reports validated with Zod, a deterministic mock as fallback |
On Canton the visibility is enforced by the ledger, not hidden by the interface:
Owner (signatory) full access: manage parties, trade, settle
Counterparty (observer) sees the vault composition, proposes trades
Auditor separate AuditRight contract, aggregate data only
Everyone else nothing: the contract does not exist for them
Three things the build had to get right:
- The Hedera sender. Inside the EVM,
msg.senderis the ECDSA alias of the account, not the long-zero address returned byAccountId.toSolidityAddress(). Every script derives the owner from the public key; with the long-zero form,onlyOwneralways reverts. - Scheduling from Solidity. The coupons are scheduled by calling the
0x16bprecompile directly from the contract, a pattern with no example in the Hedera documentation at the time. - The contract size limit.
InstitutionRegistryoutgrew the EIP-170 bytecode limit, so deploying a tenant's contracts moved to the externalInstitutionDeployer.
Next.js dashboard (:3000)
RainbowKit Β· wagmi Β· viem Β· 10 pages
β
β EIP-191 sign-in, JWT bearer
βΌ
Express API (:3001)
on-chain roles Β· RBAC Β· aggregated v1 API
ββββββββββββββββββ¬ββββββββ΄ββββββββ¬βββββββββββββββββ
ethers.js ethers.js JSON API 0G broker
β β β β
ADI Chain Hedera Canton 0G Compute
(99999) Testnet Daml inference
6 contracts 2 contracts 9 templates risk reports
The backend is the only component that talks to the four networks: ethers.js for ADI Chain and for
Hedera's JSON-RPC relay, the JSON API for the Daml ledger, and the 0G serving broker for inference. Its
aggregated v1 API feeds the dashboard and falls back to demo data when a network is unreachable.
ADI Chain testnet (chain 99999, explorer) and Ethereum Sepolia (chain 11155111):
| Contract | ADI Chain | Sepolia |
|---|---|---|
InstiVaultAccessControl |
0x8e7d4e14β¦dd656d |
0x6ccfbc2cβ¦f05043 |
RWATokenFactory |
0x0ed29f8cβ¦5d7d65 |
0xe6c7ccccβ¦36921b |
VaultManager |
0x6b6449bdβ¦c1534f |
0xa162023bβ¦6b8044 |
InstitutionRegistry |
0xab3cbc56β¦3b1daf |
0x442ec1e3β¦031002 |
InstitutionDeployer |
0x6804fc93β¦66179b |
0x531d24caβ¦1bb274 |
Hedera Testnet:
| Contract | Hedera ID | EVM address |
|---|---|---|
CouponScheduler |
0.0.7996912 |
0xβ¦007a05f0 |
YieldDistributor |
0.0.7996914 |
0xβ¦007a05f2 |
The twelve contracts were still deployed on 16 September 2026. The Daml package runs on a local Canton
sandbox, set up as described in packages/contracts-canton.
- On chain: the ADI contracts on ADI Chain testnet and Sepolia, and
CouponSchedulerandYieldDistributoron Hedera Testnet, whereCouponSchedulerholds five registered bonds with their coupon dates computed on chain. - Canton: the Daml contracts pass 28 Daml Script tests and run on a local sandbox. The deployment on Canton's Devnet L1 asked for by the bounty was not done.
- 0G: the engine calls 0G Compute when a provider is configured, and otherwise returns a
deterministic mock report (
ZG_USE_MOCK=truein.env.example). - Dashboard: the aggregated API reads the contracts and falls back to demo data when a network is unreachable or empty, so parts of the dashboard can show demo figures.
- No hosted deployment: the product is shown in the video demo and runs locally with the steps below.
Prerequisites: Node 20+, pnpm 9+ and Foundry. The Canton package also needs Java 17+ and DPM with the
Daml SDK 3.4.11, see packages/contracts-canton.
git clone --recurse-submodules https://github.com/DVB-ANS/Metaphor.git
cd Metaphor
pnpm install
cp .env.example .env # RPC endpoints, keys and deployed addresses, for every package
set -a && source .env && set +a
pnpm dev:backend # Express API on http://localhost:3001
pnpm dev:frontend # Next.js on http://localhost:3000With DEV_MODE=true, POST /api/auth/dev-login returns a JWT holding the four roles, the quickest way
to open every page locally.
To deploy your own contracts, from the same shell:
# ADI Chain, or Sepolia with ADI_RPC_URL pointing at a Sepolia RPC
cd packages/contracts-adi
forge script script/Deploy.s.sol --rpc-url "$ADI_RPC_URL" --broadcast # signs with ADI_PRIVATE_KEY
cd ../..
# Hedera Testnet, with HEDERA_OPERATOR_ID and HEDERA_OPERATOR_KEY
pnpm --filter contracts-hedera run deploy
pnpm --filter contracts-hedera run register-bond
pnpm --filter contracts-hedera run schedule
# Canton, on a local sandbox (ledger API on 6865, JSON API on 7575)
pnpm build:canton
pnpm --filter contracts-canton run sandbox| Package | Framework | Tests |
|---|---|---|
contracts-adi |
Forge | 111 |
contracts-hedera |
Forge | 74 |
contracts-canton |
Daml Script | 28 |
ai-engine |
Vitest | 21 |
pnpm test # the four suites
pnpm test:adi # or one at a time: test:hedera, test:canton, test:aiThe Forge and Vitest suites were run again on 16 September 2026, 206 tests passing; the Daml suite needs DPM.
| Layer | Technology |
|---|---|
| ADI contracts | Solidity 0.8.24, Foundry, OpenZeppelin 5.5 |
| Hedera contracts | Solidity 0.8.24, Foundry, the Schedule Service system contract (IHRC755, IHRC1215), Hedera SDK |
| Canton contracts | Daml, SDK 3.4.11, DPM |
| AI engine | 0G Compute (@0glabs/0g-serving-broker), OpenAI-compatible client, Zod |
| Backend | Express 4, ethers 6, jsonwebtoken, TypeScript (ESM) |
| Frontend | Next.js 16, React 19, Tailwind CSS 4, shadcn/ui, RainbowKit, wagmi, viem, Recharts, GSAP, Motion |
| Tooling | pnpm workspaces, Forge, Vitest, Prettier |
packages/
contracts-adi/ Foundry: roles, RWA tokens, vaults, white-label registry (ADI Chain, Sepolia)
contracts-hedera/ Foundry and Hedera SDK: coupon scheduling, yield distribution, deploy scripts
contracts-canton/ Daml: confidential vaults, private trades, audit rights, sandbox scripts
ai-engine/ 0G Compute client, risk analyzer, strategy simulator, prompts, mock
backend/ Express API: wallet sign-in, RBAC, per-chain routes, aggregated v1 API
frontend/ Next.js dashboard, 10 pages
docs/
SPEC.md specification: features, data flows, API endpoints, constraints
BOUNTY_COMPLIANCE.md every bounty requirement, with its evidence
DEMO_GUIDE.md the demo walkthrough, with the commands that check each step on chain
Three students from DeVinci Blockchain, Paris, at ETHDenver 2026.
| Role | ||
|---|---|---|
| Sofiane Ben Taleb | frontend and backend | GitHub Β· LinkedIn |
| NoΓ© Wales | Solidity contracts on ADI Chain and Hedera, backend integration | GitHub Β· LinkedIn |
| Armand SΓ©chon | Daml contracts on Canton, AI engine on 0G | GitHub Β· LinkedIn |
MIT Β© 2026 Sofiane Ben Taleb, NoΓ© Wales and Armand SΓ©chon. The Hedera system-contract
interfaces vendored in packages/contracts-hedera/contracts/hedera-deps/ keep their Apache-2.0
license.