# Deployed Contracts

ChainRender is live on three testnets — the **Ethereum Sepolia**, **Robinhood Chain**, and **Circle Arc** testnets.
This page lists the core deployed contracts you integrate against. The **canonical, complete, always-current address list** is
`deployment/additive/addresses.json` (Sepolia) plus the per-chain `chains.json` manifest in the repository — this
page surfaces the key entries for convenience.

> **Always verify against the canonical file.** Deployments evolve (new versions are added alongside old ones —
> nothing is ever removed). The repository's `addresses.json` / `chains.json` are the source of truth; the
> addresses below are the current core set at the time of writing. Verify any address on a block explorer before
> integrating.

## Networks

ChainRender is deployed on three testnets. App identity is the **content hash**, so the *same app* has the *same
hash* on every chain — nothing bridges; only the infrastructure contract addresses differ per chain.

| Chain | Chain ID | Explorer | Gas |
|---|---|---|---|
| **Ethereum Sepolia** | `11155111` | https://sepolia.etherscan.io | ETH |
| **Robinhood Chain Testnet** | `46630` | https://explorer.testnet.chain.robinhood.com | ETH |
| **Circle Arc Testnet** | `5042002` | https://testnet.arcscan.app | **USDC** |

- **Canonical Sepolia addresses:** `deployment/additive/addresses.json`.
- **Canonical per-chain manifest (all chains):** `chains.json`, generated by `scripts/build-chains-manifest.mjs`
  from each chain's `deployment/genesis-addresses.<chainId>.json`. The builder reads it to populate the chain
  selector, so it can never drift from what was actually deployed.

## Core render path (Sepolia)

| Contract | Address | Role |
|---|---|---|
| **ComponentRegistry** | `0x36a443515b96b992ee397dfd9a533de72b70c3c9` | hash → app bytes (content-addressed store) |
| **RenderRouter** (context-aware, current) | `0x3d236f80ef66cd2a173b54b59d9e500d499a9720` | `renderHash` / `renderHashWithContext` — the render entry point; the "ctxfix" router whose on-chain `PresentationContext` matches the viewer |
| **Interpreter (V3 HTML, current)** | `0x8996afa3042ddc4fb2a92d351cdcc4aa6bee77f0` | walks the byte tree → HTML/SVG |

> **Additive history (all stay live):** earlier router/interpreter versions remain callable — `RenderRouter_v106`
> `0x3bb7613e…` (+ interpreter `0x58122fe6…`) and the superseded base `0x0322b911…`. The addresses above are the
> current "ctxfix" stack the live viewer renders through; pin to whichever version your app was built against.

> **Now on all three chains:** `ComponentRegistryFast` is the **canonical component store on every chain** — a
> gas-optimized (MCOPY) twin of `ComponentRegistry` that reads back byte-identically; Sepolia keeps the legacy
> `ComponentRegistry` above for already-seeded apps. `OpcodeInterpreterV3` (a **second render target** that emits a
> self-contained **SVG document** from the same component bytes, alongside the HTML `V3Html`/`V4Html`) is also live
> on all three chains.

## Flagship app + theming (Sepolia, current)

| Contract / id | Address / hash | Role |
|---|---|---|
| **Flagship app** (SwapAppRoot) | `0x83f0c1928e673942f69ce1d85e7637bcc8b688ffeac5725913877c53b42e26d5` | the live swap app (Quote / Venues / Route) |
| **ChartRenderer** | `0x3d016ffdf31a901da08fe651d684a417ab6189ea` | on-chain charting |
| **ChartSlotAdapter** | `0x83f999b1bfff7f5b62e7f06c75d08d414e770624` | binds chart data → an image slot |
| **Light theme id** | `0x69c36880140cc2a8764c66006f943114dfeb53cc3dbb6449787033131a015509` | the tokenized light theme |
| **Dark theme id** | `0x06e66fe5b3c18bc42f90397c0d1ed61802bdb105e61a821a4cab91831a590a56` | the dark theme |

## Proven balances — Milestone 1 (Sepolia)

The proof stack behind [Proven Balances](../concepts/cross-chain-balances.md): it proves token balances against
Sepolia's own state root and renders them with block, age and grade. All six are **source-verified on Etherscan**.
Deployment record: `deployments/xchain-m1-11155111.json`.

| Contract | Address | Role |
|---|---|---|
| **CanonicalTokenFactory** | [`0x8d65a1128d410641ca86a4fa96a0e0015c579806`](https://sepolia.etherscan.io/address/0x8d65a1128d410641CA86a4fA96a0e0015c579806#code) | ownerless factory for home tokens; its `recordOf[token]` is what verifiers prove |
| **SameChainRootSource** | [`0xf8cdb83a52d275925b7305a3e596d8920b30bf1e`](https://sepolia.etherscan.io/address/0xF8Cdb83A52d275925B7305a3E596d8920b30bf1E#code) | Sepolia block hashes via `BLOCKHASH` + the EIP-2935 history contract (code hash pinned) — Grade A ceiling |
| **XchainBalanceCache** | [`0xfac774e199684ac13c002168c1a7a96adfdc9c72`](https://sepolia.etherscan.io/address/0xfac774e199684Ac13C002168c1A7A96aDfdC9c72#code) | verifies record + balance proofs (permissionless `registerToken` / `refresh`); per-source entries |
| **XchainBalanceResolver** | [`0x795864a65debca3d50945439aac90d043109e77e`](https://sepolia.etherscan.io/address/0x795864a65dEbca3d50945439AaC90D043109E77E#code) | resolver kind `xchain-balance` — the free render (host label "Sepolia") |
| **ScopeDisclosureResolver** | [`0xb42f3b2b14270b3bd0190a17776274908ae511b0`](https://sepolia.etherscan.io/address/0xB42F3b2b14270b3Bd0190A17776274908ae511B0#code) | resolver kind `scope-disclosure` — renders what a contract's grade does not establish |
| **CRPD demo token** | [`0xf69528c009406237565c12fcd6e5c9f207bd5504`](https://sepolia.etherscan.io/address/0xf69528C009406237565C12fCd6E5C9f207Bd5504#code) | a CanonicalToken made by the factory, used for the live demo render |

> **Testnet-disposable.** These contracts may be redeployed in a later milestone (for example a CreateX redeploy of
> the factory, once tokens need the same address on several chains). Milestone 2 reuses them unchanged. Always take
> addresses from the deployment record.

## Proven balances — Milestone 2 (Sepolia → Robinhood Chain Testnet)

Sepolia balances proven **on Robinhood** ([Proven Balances](../concepts/cross-chain-balances.md), *On another
chain*). Deployed and accepted end to end on 2026-10-06; all five are **source-verified** (Etherscan for the sender,
Robinhood's Blockscout explorer for the rest). Deployment record:
`deployments/xchain-m2-46630.json`.

| Chain | Contract | Address | Role |
|---|---|---|---|
| Sepolia | **ArbRootSender** | [`0xce1a5adf4228ce63ce00d0bbf68f9fb8deba06fc`](https://sepolia.etherscan.io/address/0xCe1A5aDf4228CE63CE00d0bbf68f9fB8dEbA06Fc#code) | sends a recent Sepolia block hash (from the M1 SameChainRootSource, code hash pinned) to Robinhood as a retryable ticket; ownerless, holds nothing, caller pays |
| Robinhood | **ArbParentRootSource** | [`0xd8e53abe4b6e23d3fcebe200d32eba305162ff9c`](https://explorer.testnet.chain.robinhood.com/address/0xd8E53aBe4b6E23D3FcEbE200d32EBA305162Ff9c#code) | accepts Sepolia block hashes only from the sender's alias `0xdf2b5adf…180d`; append-only — Grade A ceiling, relative to Robinhood |
| Robinhood | **XchainBalanceCache** | [`0x492729b97f6c02d4ffba942d59ca2c082b50a328`](https://explorer.testnet.chain.robinhood.com/address/0x492729b97F6c02d4FFBa942d59cA2c082b50a328#code) | the unchanged M1 cache, home = Sepolia; its only root source is ArbParentRootSource |
| Robinhood | **XchainBalanceResolverV2** | [`0xbf5d12536428996e36dda117f9ce3691b481fffe`](https://explorer.testnet.chain.robinhood.com/address/0xBf5d12536428996e36Dda117f9cE3691b481fFfE#code) | resolver kind `xchain-balance` — host label "Robinhood Testnet", facet `instant upgrades, 1-of-2 Safe, as of 2026-10` |
| Robinhood | **ScopeDisclosureResolver** | [`0x49a1497328470aa0ca9a3ecb796eb6d2b868e636`](https://explorer.testnet.chain.robinhood.com/address/0x49a1497328470aa0ca9a3ECB796eb6d2b868E636#code) | resolver kind `scope-disclosure` on Robinhood |

The sender and receiver were deployed through CreateX (CREATE3) so each could name the other in its constructor.
Proven token on Robinhood: the Sepolia **CRPD** (`0xf69528c0…5504`), registered in the Robinhood cache.

## Proven balances — Milestone 3, snapshot mode (existing tokens, Sepolia → Robinhood)

Balances of tokens ChainRender **did not create**, from the token's own `balanceOf` run on Sepolia
([Proven Balances](../concepts/cross-chain-balances.md), *Tokens ChainRender didn't create*). Deployed, accepted
and source-verified on 2026-10-06. The Robinhood cache reuses the Milestone 2 **ArbParentRootSource** as its only
root source. Deployment record: `deployments/xchain-m3-46630.json`.

| Chain | Contract | Address | Role |
|---|---|---|---|
| Sepolia | **BalanceSnapshotter** | [`0x3493390302c9f8d0f1c3a0861960b77f33d63c74`](https://sepolia.etherscan.io/address/0x3493390302c9f8D0f1C3A0861960B77f33D63c74#code) | runs a token's `balanceOf` / `decimals` (and once `name` / `symbol`) with exactly 100,000 gas and commits the answers in its own storage; ownerless, permissionless |
| Robinhood | **SnapshotBalanceCache** | [`0x3ad98f060cbbc2952f2b7c30afc36a51d1cf055c`](https://explorer.testnet.chain.robinhood.com/address/0x3Ad98f060CBBc2952f2b7c30aFC36A51d1Cf055C#code) | proves the snapshotter's commitments (code hash `0x7c349593…f9ad` pinned) against delivered Sepolia roots |
| Robinhood | **SnapshotBalanceResolver** | [`0x8f1dd932c36423d5f60eebfe60c85c8cf2ff9713`](https://explorer.testnet.chain.robinhood.com/address/0x8f1dd932c36423d5F60eebFe60C85C8cF2Ff9713#code) | resolver kind `xchain-snapshot-balance` — host label "Robinhood Testnet", facet `instant upgrades, 1-of-2 Safe, as of 2026-10` |

Tokens proven on Robinhood: Sepolia **WETH9** (`0xfff99767…6b14`) and **USDC** (`0x1c7d4b19…7238`).

## Proven balances — Milestone 3, storage-layout mode (existing tokens, Sepolia → Robinhood)

Storage proofs of tokens ChainRender **did not create**, under content-addressed adoption claims
([Proven Balances](../concepts/cross-chain-balances.md), *without a transaction per value*). Grade C by construction.
Deployed, accepted and source-verified on 2026-10-07 (Etherscan; Robinhood's Blockscout explorer). Deployment record:
`deployments/xchain-m3b-46630.json`.

The three **adapters** are at the **same address with the same code on both chains** (CreateX CREATE3, a salt not bound
to a chain): a claim names them by address + code hash, so one claim works everywhere.

| Chain | Contract | Address | Role |
|---|---|---|---|
| both | **PlainPinning** | [`0x1ea8799342a963550f5b2ae1a75d98f7137afd9d`](https://sepolia.etherscan.io/address/0x1ea8799342A963550f5b2AE1A75D98F7137Afd9D#code) | pinning rule `plain/v1` — no reachable delegation, a `balanceOf` selector; code hash `0x7f6b3f58…5efb` |
| both | **SlotProxyPinning** | [`0xb020a310236b79362a3f9a2c574a50b4a0d6df16`](https://sepolia.etherscan.io/address/0xB020A310236b79362a3F9A2c574A50b4a0D6DF16#code) | pinning rule `slot-proxy/v1` — one constant implementation slot, implementation pinned by code hash; code hash `0xfec635be…27be` |
| both | **MappingWordLayout** | [`0x0115636a12904a6fc66929ec65d95c3e543fc116`](https://sepolia.etherscan.io/address/0x0115636a12904A6FC66929EC65d95c3E543fc116#code) | balance layout `mapping-word/v1` — one mapping word, low *n* bits; code hash `0xeef84dd2…5aaf` |
| Sepolia | **TokenAdoptionRegistry** | [`0x4fd6ed93f62d9b152db074ee5f1524ae102fe477`](https://sepolia.etherscan.io/address/0x4FD6eD93F62D9b152DB074ee5F1524Ae102Fe477#code) | adopt (structural checks, witness) and confirm (same-chain proof via the M1 SameChainRootSource); ownerless, permissionless |
| Sepolia | **AdoptedBalanceCache** | [`0xffdb6688ba039d8a2ee414c86a950e64ad49336f`](https://sepolia.etherscan.io/address/0xffdB6688Ba039D8A2eE414c86A950E64ad49336f#code) | registers confirmed claims and proves balances under them; root source = the M1 SameChainRootSource |
| Sepolia | **AdoptedBalanceResolver** | [`0x3a7ac5c7287622bf310ad6f5f64d695b53006b7f`](https://sepolia.etherscan.io/address/0x3a7aC5C7287622BF310AD6F5f64d695B53006b7f#code) | resolver kind `xchain-adopted-balance` — host label "Sepolia" |
| Robinhood | **AdoptedBalanceCache** | [`0xfc843824a5243878ed4dbb3a7c235ef50934c553`](https://explorer.testnet.chain.robinhood.com/address/0xfc843824A5243878ED4DBb3A7C235Ef50934C553#code) | the same cache code; root source = the M2 ArbParentRootSource; registry code hash `0x18098bcf…90bc` pinned |
| Robinhood | **AdoptedBalanceResolver** | [`0xf84c3f01c1d89af96328a45e984caf52ac7611d9`](https://explorer.testnet.chain.robinhood.com/address/0xf84C3F01C1D89aF96328a45E984CAf52Ac7611d9#code) | resolver kind `xchain-adopted-balance` — host label "Robinhood Testnet", facet `instant upgrades, 1-of-2 Safe, as of 2026-10` |

Adapters on Robinhood: [PlainPinning](https://explorer.testnet.chain.robinhood.com/address/0x1ea8799342A963550f5b2AE1A75D98F7137Afd9D#code),
[SlotProxyPinning](https://explorer.testnet.chain.robinhood.com/address/0xB020A310236b79362a3F9A2c574A50b4a0D6DF16#code),
[MappingWordLayout](https://explorer.testnet.chain.robinhood.com/address/0x0115636a12904A6FC66929EC65d95c3E543fc116#code).

Adopted on Sepolia and registered on both chains: **WETH9** (`0xfff99767…6b14`) under claim
`0xfae8aac6088f9c8b1b4a5d255388ffe92c0c1f2167da8c9fadb40f635d6cc4e5` (`plain/v1` + `mapping-word/v1`, Solidity order,
slot 3, 256 bits; evidence `0x319df1e6…2657`, pinned on IPFS as
[`bafkreidkcv46nvu7oayhvegbdiengoconle67ct6ovt7ecnxlnhl3bwkkm`](https://ipfs.filebase.io/ipfs/bafkreidkcv46nvu7oayhvegbdiengoconle67ct6ovt7ecnxlnhl3bwkkm)). Sepolia **USDC** is refused (`Delegates`), and is shown via snapshot mode.

## Cross-chain swap — Milestone 4 (Sepolia ↔ Robinhood, no bridge)

A hash-timelock swap whose second lock checks the first by storage proof
([Proven Balances](../concepts/cross-chain-balances.md), *Swapping across chains without a bridge*). Deployed, accepted
and source-verified on 2026-10-07 (Etherscan; Robinhood's Blockscout explorer). Deployment record:
`deployments/xchain-m4-46630.json`. The swap is Grade C at most; proven lock states are Grade A relative to Robinhood,
always with its facet.

| Chain | Contract | Address | Role |
|---|---|---|---|
| both | **HashTimelockSwap** | [`0x0cc5c1e149843b9daa5878cc34917233b49806eb`](https://sepolia.etherscan.io/address/0x0cC5C1e149843b9DaA5878CC34917233B49806eb#code) | the swap locks; same address and code on both chains (CreateX CREATE3, salt label `cr.m4.htlc1`, not chain-bound); code hash `0x81c87966…8466`; ownerless |
| Robinhood | **CanonicalTokenFactory** | [`0x416a27cb0f3dd05110777b403379e4b27cda34f5`](https://explorer.testnet.chain.robinhood.com/address/0x416a27CB0F3DD05110777B403379E4b27cda34F5#code) | the Milestone 1 factory, unchanged; tokens made here have Robinhood as home |
| Robinhood | **SwapLockProofCache** | [`0x52157c234ed40a54352064cf7d0cd79269e208ff`](https://explorer.testnet.chain.robinhood.com/address/0x52157c234ed40a54352064cf7d0cd79269e208ff#code) | proves Sepolia lock states (root source = the M2 ArbParentRootSource) and guards the second lock; MIN_GAP 352,800 s, MIN_WINDOW 737,460 s (from Robinhood's `maxTimeVariation`); proven token definitions from the M2 XchainBalanceCache |
| Robinhood | **SwapLockResolver** | [`0x690816d4cae09a124b663ed016cbc002cf637f19`](https://explorer.testnet.chain.robinhood.com/address/0x690816d4cae09a124b663ed016cbc002cf637f19#code) | resolver kind `swap-lock` — home label "Sepolia", host label "Robinhood Testnet", facet `instant upgrades, 1-of-2 Safe, as of 2026-10` |

HashTimelockSwap on Robinhood: [explorer](https://explorer.testnet.chain.robinhood.com/address/0x0cC5C1e149843b9DaA5878CC34917233B49806eb#code).
Acceptance tokens: **CRSA** on Sepolia (`0xed28bd4c…8fa8`) and **CRSB** on Robinhood (`0x5ba180d3…d5a4`).

## How to use these

- **Render the flagship:** `RenderRouter.renderHash(0x83f0c192…)` — a free `eth_call`.
- **Render with a theme/size:** `RenderRouter.renderHashWithContext(appHash, ctx)`.
- **Check a component exists:** `ComponentRegistry.exists(hash)`.

For the full deployment — every resolver, registry, and renderer (Sepolia is ~130 contracts) — read
`deployment/additive/addresses.json`. New capability is deployed *additively* (new contracts alongside the live
base, never replacing it), so the file grows over time and old addresses keep working.

## Robinhood Chain Testnet (46630)

ChainRender runs the **same core render path** on the Robinhood Chain Testnet (chain `46630`), deployed at
**Robinhood-specific addresses**. Because app identity is the content hash, an app deployed to both chains carries
the **same hash** on each — only the infrastructure contract addresses differ. (The on-chain library hashes below
are byte-identical to Sepolia: same bytes, same hash.)

**Network:** chain id `46630` · explorer https://explorer.testnet.chain.robinhood.com · gas token ETH · free
testnet gas via the site's Robinhood faucet toggle (Official / QuickNode / Chainstack / Chainlink).

### Core render path (Robinhood)

| Contract | Address | Role |
|---|---|---|
| **ComponentRegistryFast** | `0x6e49b1dfd05248df06041ad17973de59d9e76c2b` | hash → app bytes (content-addressed store) |
| **RenderRouter** | `0xbfa38b3bcc0fbb32facffc497bbc38af4b587382` | `renderHash` / `renderHashWithContext` — the render entry point |
| **OpcodeInterpreterV3Html** | `0x79518757d3717c371961b7f8870e1416b39c9c72` | walks the byte tree → HTML/SVG (V4 HTML also live: `0xa4349577…`) |
| **SourceStoreFast** | `0x9dd09d934f84165845c35eca6af4309d6aa08455` | SSTORE2-backed source / chunk store |

### Key registries, renderers & theming (Robinhood)

| Contract | Address |
|---|---|
| **CompositionRegistry** | `0xab628eb22bb731dccb75d981d186b03ac30bbd2e` |
| **SceneComponentRegistry** | `0x73a84585c058ca9405de94213033668a86032410` |
| **DependencyRegistry** (on-chain libraries) | `0xae75db71dc78109f29b7946f65b3983a81e17686` |
| **ThemeTokens** | `0xcb33a04817a40deb1753b982e109a25672ca368a` |
| **ChartRenderer** | `0xfa9f5df6419eab3b180c18909d06f70a197c01a1` |
| **TrustGrade** | `0x7317cf8dea1a987943143d05c59fcc9369a34f45` |
| **SubnameStakeRegistrarV2** | `0x627e120abd54cef75f7b4340c9674a7245017f91` |
| **Web3Serve** | `0x574b2372f6bf61892b44c5ce9aecb9acd4ed4649` |

The full set — 109 contracts (every resolver, registry, renderer, verifier) — is in
`deployment/genesis-addresses.46630.json`, surfaced through the generated `chains.json`. Verify any address on the
[Robinhood explorer](https://explorer.testnet.chain.robinhood.com) before integrating.

### On-chain libraries (Robinhood, DependencyRegistry `0xae75db71…`)

Content-addressed, so these `libHash` values are **byte-identical to Sepolia**:

| Library | libHash | Size / parts |
|---|---|---|
| **three** (r160 UMD) | `0x59786fe6aa0043e6630f8b6771a9e8c7ff5dfd5b25cfbffa720d59c04fc3a741` | 166,990 B / 3 |
| **icons** (500 Lucide) | `0x1357bb6e8d2d5cfd83f947d83a5a0d06f8078c91923eb4a197bc4e10539e5180` | 20,995 B / 1 |
| **p5** (2.3.2) | `0x0daa59ef280a524b8b95f5e9eb13924a678f52291c8bbb01b29f8dcee9b52db9` | 285,882 B / 4 |
| **three** (0.185.1) | `0x52a5452c0375b4125b988364a21c566924e0e74b1a56e2aede1579a1552ad51d` | 86,915 B / 2 |

## Circle Arc Testnet (5042002)

ChainRender runs the **same core render path** on the **Circle Arc Testnet** (chain `5042002`), deployed at
Arc-specific addresses. As with Robinhood, app identity is the content hash — the *same app* carries the *same
hash* on Arc as on Sepolia/Robinhood; only the infrastructure addresses differ. (Arc's core addresses in fact came
out **identical to Robinhood's**: the same deployer deploying the same contracts in the same order yields the same
`CREATE` addresses — the chains remain fully independent deployments.)

**Network:** chain id `5042002` · explorer https://testnet.arcscan.app · gas token **USDC** · testnet USDC via the
site's Arc faucet toggle (Circle / Chainlink / thirdweb).

> **USDC gas — the one Arc quirk.** Arc's **native gas token is USDC**, and Arc exposes USDC *twice*: as the
> **native gas asset it uses 18 decimals** (standard wei-style — gas math and native balances behave like any
> ETH-style chain), while the **USDC ERC-20 token uses 6 decimals** at the fixed address
> `0x3600000000000000000000000000000000000000`. Don't conflate the two — read a USDC *token* amount at 6 decimals
> and the *native* balance at 18. Rendering itself is unaffected (view calls are chain-agnostic).

### Core render path (Arc)

| Contract | Address | Role |
|---|---|---|
| **ComponentRegistryFast** | `0x6e49b1dfd05248df06041ad17973de59d9e76c2b` | hash → app bytes (content-addressed store) |
| **RenderRouter** | `0xbfa38b3bcc0fbb32facffc497bbc38af4b587382` | `renderHash` / `renderHashWithContext` — the render entry point |
| **OpcodeInterpreterV3Html** | `0x79518757d3717c371961b7f8870e1416b39c9c72` | walks the byte tree → HTML/SVG (V4 HTML also live: `0xa4349577…`) |
| **SourceStoreFast** | `0x9dd09d934f84165845c35eca6af4309d6aa08455` | SSTORE2-backed source / chunk store |

### Key registries, renderers & theming (Arc)

| Contract | Address |
|---|---|
| **CompositionRegistry** | `0xab628eb22bb731dccb75d981d186b03ac30bbd2e` |
| **SceneComponentRegistry** | `0x73a84585c058ca9405de94213033668a86032410` |
| **DependencyRegistry** (on-chain libraries) | `0xae75db71dc78109f29b7946f65b3983a81e17686` |
| **ThemeTokens** | `0xcb33a04817a40deb1753b982e109a25672ca368a` |
| **ChartRenderer** | `0xfa9f5df6419eab3b180c18909d06f70a197c01a1` |
| **TrustGrade** | `0x7317cf8dea1a987943143d05c59fcc9369a34f45` |
| **SubnameStakeRegistrarV2** | `0x627e120abd54cef75f7b4340c9674a7245017f91` |
| **Web3Serve** | `0x574b2372f6bf61892b44c5ce9aecb9acd4ed4649` |

The full set — 109 contracts — is in `deployment/genesis-addresses.5042002.json`, surfaced through the generated
`chains.json`. The on-chain library hashes are **byte-identical to Sepolia/Robinhood** (content-addressed). Verify
any address on the [Arc explorer](https://testnet.arcscan.app) before integrating.

## The additive deployment discipline

ChainRender never redeploys the world to add a feature. New contracts (a new resolver, a new registry, a new
interpreter version) are deployed against the live base and their addresses merged into the address file, leaving
everything existing untouched. This is why:
- **Old apps never break** — the contracts they reference are immutable and stay live.
- **The address file is append-only** — entries are added, never removed.
- **You can pin to a specific version** — an app references exactly the contract addresses it was built against.

## Verifying a deployment

Every ChainRender contract is **ownerless and immutable** (no admin, no upgrade key). To verify:
1. Read the contract's bytecode on a block explorer — confirm it matches the compiled artifact.
2. Confirm there's no owner/admin function.
3. Render an app through it against multiple RPCs — byte-identical output confirms honest behavior.

See **[Contracts → Verifying an App](../contracts/verifying.md)**.

## Related
- **[Contracts → Architecture](./architecture.md)** · **[Contracts → Reading On-Chain](./reading.md)** ·
  **[Contracts → Registries](./registries.md)**


## On-chain libraries (DependencyRegistry)

Fetched by name (newest-wins), gzip-compressed, decompressed natively in the browser -- no CDN.

| Library | Content id (libHash) | Notes |
|---|---|---|
| **p5** (UMD) | *(see DependencyRegistry)* | plain-script load, sets `window.p5` |
| **three** (r160 UMD) | `0x59786fe6aa0043e6630f8b6771a9e8c7ff5dfd5b25cfbffa720d59c04fc3a741` | plain-script load, sets `window.THREE`; r160 is the last UMD build |
| **icons** (500 Lucide) | `0x1357bb6e8d2d5cfd83f947d83a5a0d06f8078c91923eb4a197bc4e10539e5180` | SVG sprite, one chunk, theme-adaptive |

## DeFi resolvers

All caller-supplied-address, view-only, ownerless, fail-closed (a reverting/missing target renders `"unavailable"`),
and now deployed on **all three chains**. See **[DeFi Capabilities](../concepts/defi-capabilities.md)** for detail.

| Contract | Kind | Purpose |
|---|---|---|
| **ChainlinkFeedResolver** | `price` | Chainlink aggregator price/round data |
| **UniswapV3PriceResolver** | `uniV3Price` | live V3 pool price (slot0) |
| **UniswapV4PriceResolver** | `uniV4Price` | live V4 pool price (StateView.getSlot0) |
| **AaveReserveResolver** | `aaveSupplyApy` | Aave reserve / supply-APY read |
| **CurvePoolResolver** | `curvePool` | Curve StableSwap `get_dy` / composition |
| **UniswapV3PositionResolver** | `uniV3Position` | a V3 LP position (positions(tokenId)) |
| **AavePositionResolver** | `aavePosition` | an Aave user account (health factor, debt) |
| **UniswapQuoteResolver** | `uniQuote` | pre-trade quote (QuoterV2, staticcall) |
| **ApprovalStateResolver** | `approvalState` | ERC-20 allowance / approval state |
| **PortfolioResolver** | `portfolio` | sums many reads into one aggregated total |
| **CallResolver** | `staticread` | generic view reader (any hook/contract view fn) |
| **MultiCallResolver** | `multiread` | batch several reads side-by-side |

## RWA resolvers

Real-world-asset **display + verification** resolvers — on-chain reads rendered honestly, never enforcement or
custody. Deployed on all three chains. Full detail (kinds, trust grades, the honest boundary) in
**[RWA Capabilities](../concepts/rwa-capabilities.md)**.

| Contract | Kinds | Purpose |
|---|---|---|
| **ProofOfReserveResolver** | `por-reserves` · `por-supply` · `por-coverage` | reserves vs `totalSupply()` coverage ratio (Grade A, computed on-chain) |
| **Erc3643PermissionAdapter** | `erc3643-verified/-frozen/-status/-can-transfer` | ERC-3643 compliance **display** (graded ≤C — mutable authority) |
| **CredentialStatusRegistry** | *(registry)* | ownerless issuer-scoped attest / renew / revoke + expiry |
| **CredentialLifecycleResolver** | `cred-status` · `cred-valid` | credential status bound to an expected issuer |
| **VaultResolver** | `vault4626` · `vault7540` | ERC-4626 NAV / totals + ERC-7540 redemption queue (Grade A; trust = the vault's own accounting) |

*(Addresses are per-deployment and additive; `deployment/additive/addresses.json` (Sepolia) and each chain's
`genesis-addresses.<chainId>.json` — surfaced through `chains.json` — are the authoritative live set.)*

## CoW / intent-DeFi resolvers (Sepolia)

Intent-based DeFi — CoW Protocol conditional/programmatic orders, rendered + verified trustlessly. These are deployed
on **Ethereum Sepolia** (where CoW's **ComposableCoW** is deployed); they are **portable** to any chain where
ComposableCoW exists, because its address is a caller argument, not a hardcoded constant. They are not part of the
all-three-chains resolver set above. Full detail in **[Intent DeFi & CoW Protocol](../concepts/intent-defi-cow.md)**.

| Contract | Kind | Sepolia address | Role |
|---|---|---|---|
| **CowTwapResolver** | `cowTwap` | `0xF949E6fB52Df34Dcc86F674E51327567cD964395` | TWAP schedule from the order definition + `block.timestamp` (Grade A) |
| **CowConditionalOrderResolver** | `cowOrder` | `0x752AcEd4a7D7bD9Bd604c3d7adD38373Eed3b6c1` | live tradeability via STATICCALL to the real ComposableCoW (Grade A, fail-closed to `not active`) |
| **CowIntentVerifyResolver** | `cowIntent` | `0xCaa6E85510f6FDDA54Be92AaEb95e6779bdc1AB2` | on-chain `keccak256(fullAppData) == order.appData` → `verified` / `app-data mismatch` (Grade A) |
| ComposableCoW (CoW Protocol, external) | — | `0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74` | CoW's conditional-order framework (deterministic across chains) |

## ENS multichain resolver (Sepolia)

| Contract | Kinds | Sepolia address | Role |
|---|---|---|---|
| **EnsMultichainResolver** | `ensApp` · `ensNameChain` | `0x02a2c2E1E7fd8Aed8BF4dF7d9695c26F172C247f` | `chainrender.app` text manifest + ENSIP-19 chain-aware verified reverse (Grade A); ENS registry supplied at construction |

> Addresses above are the current Sepolia set at the time of writing and come from this deployment's additive run —
> **verify against `deployment/additive/addresses.json`** (the authoritative live set) before integrating. See
> **[ENS Names & Integration](../guides/ens-integration.md)** for the ENS reads and **[RWA Capabilities](../concepts/rwa-capabilities.md)** for the vault.

