Skip to content

0x03sol/SANCTUM

SANCTUM

An agent-native RWA market on Ritual Chain. Sovereign agents acquire tokenized real-world assets through a sealed-bid dark pool, then autonomously underwrite and settle parametric cover on those positions — with an on-chain reputation ledger that prices counterparty trust from history.

Chain Solidity Tests License


Why SANCTUM

On-chain RWA trading leaks alpha to the mempool: a bid sits in plain sight and gets front-run before it fills. Parametric cover, meanwhile, still depends on human committees, keeper bots, and off-chain oracles to price and pay claims. SANCTUM removes both human bottlenecks at once:

  • Sealed-bid dark pool — a bid is committed as keccak256(price, salt), so the price never touches the mempool and cannot be front-run. It is revealed only at fill time.
  • Enshrined cancel-priority — the pool declares its function ordering to the block builder, so a cancel ordered in the same block as an adverse fill executes first. A trader can always pull a bid before it is taken.
  • Autonomous underwriting — an on-chain agent fetches the asset price, evaluates a pure-arithmetic drawdown trigger, and settles claims from its own capital pool with no operator and no keeper.
  • Reputation as the moat — every fill, premium, claim, and default accrues to an agent's address, forming a verifiable track record that compounds over time.

Architecture

Three contracts, each with a single responsibility, wired with least-privilege access control.

Contract Role Ritual primitives used
AegisRegistry Agent identity + reputation ledger (fills, premiums, payouts, settlements, defaults → deterministic score) pure EVM
SilentBidPool Sealed-bid dark pool: commit / cancel / reveal-and-fill, with single-contract cancel-priority ISequencingRights (single-contract ACE)
SentinelUnderwriter Autonomous parametric underwriter: rolling-window drawdown trigger, pooled payouts, on-chain settlement report HTTP 0x0801 + JQ 0x0803 (price feed), LLM 0x0802 (settlement narrative), Scheduler (self-waking)

A shared PrecompileConsumer base decodes Ritual's short-running async (SPC) envelope and guards two-phase callbacks with msg.sender == AsyncDelivery.

The loop

seal bid ──▶ post clearing price ──▶ reveal & fill ──▶ Aegis records the fill
   │                                                          ▲
   └── cancel (higher priority, beats a same-block fill)      │
                                                              │
buy cover ──▶ price window updates ──▶ 30% drawdown trigger ──▶ settle ──▶ Aegis records the payout

Deployed contracts (Ritual testnet, chain 1979)

Contract Address Explorer
AegisRegistry 0x38a9fCb26F3349910c6B3E84bdA146dDF5c08249 view
SilentBidPool 0x3a605E5ceAb9870783bd33e8102d79E177Ad82b9 view
SentinelUnderwriter 0xB914a815B711A52Eb908796Ad29bf7C0D358BbaC view

On-chain proof

A complete trade-to-settlement lifecycle, executed on the live testnet. Every step is a real transaction:

Step Transaction
Fund underwriter pool 0xe3b2e9ab…f7e64
Buy parametric cover 0xe90bddd8…1748d
Seal a bid (price hidden) 0xb7869732…1cdc88
Post clearing price 0x723c34c7…708bce0
Reveal & fill bid 0x22f2499d…3a06206
Settle claim 0xa250d2c9…f9f59e6b
File settlement report 0x97fe12ed…d0f81c4
Live HTTP + JQ price fetch (precompile) 0xf63e66f4…349516a
Live LLM settlement inference (precompile) 0x51b2d52c…410e8b0

The last two transactions are the headline. In one the SentinelUnderwriter called Ritual's HTTP precompile (0x0801) to fetch the live ETH/USD price from CoinGecko, parsed it with the JQ precompile (0x0803), and wrote it to state. In the other it called the LLM precompile (0x0802) to run a GLM-4.7 inference inside the TEE for the settlement narrative. Both ran entirely on-chain, in one transaction each, with no oracle and no keeper.

The LLM call persists its conversation history to a HuggingFace dataset as the agent's data-availability layer: lopkwqugre231/sanctum-convos.

Live metrics (read directly from the contracts)

Metric Value
Sealed bids filled 1
Parametric policies underwritten 1
Drawdown trigger fired at 36.23% (threshold 30%)
Claims settled 1 — payout released from the pool
Registered agents 1
Agent reputation score 1055 (base 1000 + honored settlement + fill)
Foundry tests 49 passing
Deployment cost ~0.0046 RITUAL
Full lifecycle cost ~0.0011 RITUAL (gas only)

Tech stack

Contracts — Solidity 0.8.28, Foundry (forge + cast), Ritual precompiles (ISequencingRights, HTTP 0x0801, JQ 0x0803, LLM 0x0802, Scheduler), RitualWallet for prepaid precompile fees.

Frontend — Next.js 14 (App Router) · TypeScript · wagmi v2 + viem v2 · Tailwind CSS. A single-page trading terminal in an editorial "newsprint" design system, with a nine-state async-transaction state machine, live useWatchContractEvent feeds, polled reads, and a canvas price tape.

Chain — Ritual Chain (ID 1979), RPC https://rpc.ritualfoundation.org, explorer https://explorer.ritualfoundation.org, faucet https://faucet.ritualfoundation.org.


Repository layout

.
├── contracts/                 # Foundry project
│   ├── src/
│   │   ├── AegisRegistry.sol
│   │   ├── SilentBidPool.sol
│   │   ├── SentinelUnderwriter.sol
│   │   ├── interfaces/IRitual.sol
│   │   └── utils/PrecompileConsumer.sol
│   ├── test/                  # 49 Foundry tests
│   ├── script/Deploy.s.sol
│   └── foundry.toml
└── web/                       # Next.js frontend (Vercel-ready)
    ├── app/
    ├── components/
    ├── hooks/
    └── lib/

Build & test

Contracts

cd contracts
forge install foundry-rs/forge-std   # if lib/ is empty after clone
forge test                           # 49 tests
forge script script/Deploy.s.sol:Deploy --rpc-url https://rpc.ritualfoundation.org --broadcast

Deploy.s.sol reads PRIVATE_KEY from the environment; never commit it.

Frontend

cd web
npm install
npm run dev      # development
npm run build    # production

Configure web/.env.local:

NEXT_PUBLIC_RITUAL_RPC_URL=https://rpc.ritualfoundation.org
NEXT_PUBLIC_AEGIS_REGISTRY=0x38a9fCb26F3349910c6B3E84bdA146dDF5c08249
NEXT_PUBLIC_SILENTBID_POOL=0x3a605E5ceAb9870783bd33e8102d79E177Ad82b9
NEXT_PUBLIC_SENTINEL_UNDERWRITER=0xB914a815B711A52Eb908796Ad29bf7C0D358BbaC

Deploy the frontend (Vercel)

The frontend is a standard Next.js app and deploys on Vercel with no extra configuration.

  1. Import the repository on Vercel and set the Root Directory to web.
  2. Add the four NEXT_PUBLIC_* environment variables above.
  3. Deploy. Build command next build, output handled automatically.

A web/vercel.json pins the Next.js framework and build command.


Security

  • No secrets are committed. PRIVATE_KEY, .env, wallet keystores, and Foundry broadcast//cache/ artifacts are git-ignored.
  • Async callbacks verify msg.sender == AsyncDelivery and are idempotent.
  • Reputation writes are gated to authorized market contracts; settlement re-checks its trigger (TOCTOU-safe).
  • All values shown are Ritual testnet RITUAL, which has no real-world value.

License

BSD-3-Clause-Clear. See LICENSE.

About

Agent-native RWA market on Ritual Chain: a sealed-bid dark pool, an autonomous parametric underwriter, and an on-chain reputation ledger.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors