> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ix.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> The smart contracts behind IX RWA and how they fit together.

IX RWA is a set of upgradeable smart contracts on **Base**. A single ERC-4626 index vault (**IX-CORE**) sits on top of per-asset **cohort vaults**; a NAV oracle prices the index, an asset registry keeps identity verifiable on-chain, an attestor registry gates every NAV move behind recorded proof-of-reserve, and a smoothing reserve buffers yield and redemptions.

## Contract topology

```mermaid theme={null}
flowchart TD
    U[Investor wallets] -->|deposit USDC / redeem at NAV| V[IX-CORE vault · ERC-4626]
    V -->|mint/redeem shares| U
    subgraph Pricing[NAV pricing seam]
      ORA[LiveDataNAVOracle · INAVOracle] -->|hardwareValueUSD| V
      ATT[AttestorRegistry · PoR gate] -->|setCohortValue| ORA
    end
    REG[AssetRegistry] -.->|cohortHasActiveAsset| ORA
    FEED[Off-chain EconomicsFeeder] -->|attest value + evidenceHash| ATT
    FEED -->|notifyRevenue| V
    RES[SmoothingReserve] -->|coverShortfall| V
    MC[MerkleClaim] -->|one-time BNB migration at NAV| U
    V --> TRE[Treasury · fees]
```

## Valuation, exactly

IX-CORE's price is fully mechanical — two terms, both readable on-chain:

```text theme={null}
totalAssets() = USDC.balanceOf(vault)        ← cash + accrued revenue (trustless)
              + navOracle.hardwareValueUSD()  ← off-chain hardware value (INAVOracle seam)

NAV-per-share = totalAssets() / totalSupply()
```

Depositing revenue raises the **cash term** (yield up); depreciation lowers the **oracle term** (NAV/share down). Units are USDC 6-decimals throughout. This is the mechanism that replaced BNB-era Merkle distributions — see [Revenue & distributions](/protocol/revenue-and-distributions).

## Components

| Contract                                   | Responsibility                                                                                                                                                                                                                                                                                                                             |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **IX-CORE vault** (`IXCoreVault`)          | ERC-4626 accumulating index token. Mints/redeems shares at NAV; revenue accrues into NAV-per-share; holds the redemption queue. See [Ownership & IX-CORE](/protocol/ownership-and-ixd).                                                                                                                                                    |
| **Cohort vaults**                          | One per SPV/batch; the construction unit. New assets become a cohort and enter IX-CORE by a rules-based weight. On testnet a cohort is a registry grouping, promotable to a standalone sub-vault later without changing the read surface.                                                                                                  |
| **NAV Oracle** (`LiveDataNAVOracle`)       | Publishes per-cohort hardware value behind an `INAVOracle` seam. On testnet it is fed by the off-chain **EconomicsFeeder** from **live Vast.ai market rates + real hardware cost/depreciation/resale** — settled in test tokens, never hand-typed. Byte-identical to the mainnet oracle; only the feed source and settlement token change. |
| **Attestor Registry** (`AttestorRegistry`) | The **proof-of-reserve gate**. Assigned the oracle's updater role so that, once the direct-EOA write is revoked (a pre-mainnet lockdown step), NAV can move only via a recorded attestation (attestor + `evidenceHash` + time). See [Security model](/security/security-model).                                                            |
| **Asset Registry** (`AssetRegistry`)       | The construction ledger: assets grouped into cohorts, each with cost basis, operator, lifecycle status, and a hashed hardware identity (machine + GPU serials). Drives which cohorts count toward NAV.                                                                                                                                     |
| **Smoothing Reserve** (`SmoothingReserve`) | A USDC buffer that smooths yield and funds the redemption queue. Custody only; its balance is public.                                                                                                                                                                                                                                      |
| **Merkle Claim** (`MerkleClaim`)           | One-time migration airdrop converting former BNB holders into IX-CORE at NAV. See [Revenue & distributions](/protocol/revenue-and-distributions#why-accrual-instead-of-merkle-claims).                                                                                                                                                     |
| **Treasury**                               | Receives protocol fees and reserve flows.                                                                                                                                                                                                                                                                                                  |

## Roles & permissions

Every privileged action is a named role, not an ambient owner. Roles are granted at deploy and move to a multisig / governance setup at the audited Phase-2 redeploy. See [Governance](/security/governance).

| Role                     | Held by (testnet)                                                      | Can                                                                                   |
| ------------------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `DEFAULT_ADMIN_ROLE`     | Protocol admin                                                         | Set fee params, fee recipient, reserve/oracle pointers, register/retire assets, pause |
| `ORACLE_UPDATER_ROLE`    | AttestorRegistry (intended sole updater; EOA path revoked pre-mainnet) | Push cohort values into the NAV oracle                                                |
| `ATTESTOR_ROLE`          | EconomicsFeeder (testnet) → real attestors (mainnet)                   | Submit an attested reserve value + evidence hash                                      |
| `REVENUE_DEPOSITOR_ROLE` | EconomicsFeeder                                                        | Call `notifyRevenue` to accrue revenue into NAV                                       |
| `KEEPER_ROLE`            | Keeper / feeder                                                        | Process the redemption queue; quarantine assets on a bad/stale feed                   |
| `SPENDER_ROLE`           | Vault + keeper                                                         | Pull from the smoothing reserve to cover a shortfall                                  |
| `UPGRADER_ROLE`          | Protocol admin                                                         | Authorize UUPS implementation upgrades                                                |

## Redemption path

A liquid share token sits on top of illiquid hardware, so exits are designed so they can't bank-run the reserve:

```mermaid theme={null}
flowchart TD
    R[redeem / withdraw] --> C{owed ≤ availableCash?}
    C -->|yes| PAY[Pay instantly · exit fee skimmed]
    C -->|no| Q[Burn now, queue request · FIFO]
    Q --> PROC[KEEPER processQueue n]
    Q --> CLM[User claim reqId]
    PROC --> FUND{balance + reserve ≥ owed?}
    CLM --> FUND
    FUND -->|yes| OUT[USDC to receiver]
    FUND -->|no| WAIT[Stays queued · FIFO fairness]
```

`availableCash = balance − reserveFloor` keeps a buffer reachable only by the queue processor, never an instant sell. On the queued path the exit fee stays in the vault as extra buffer for remaining holders.

## Observability

The protocol emits an event for every state change, so the indexer and transparency surfaces reconstruct state from the chain rather than from client input:

| Event                                                          | Emitted when                                  |
| -------------------------------------------------------------- | --------------------------------------------- |
| `Deposit` / `Withdraw`                                         | Shares minted / redeemed (ERC-4626)           |
| `RevenueAccrued(cohortId, amount)`                             | Revenue deposited into the vault              |
| `RedemptionQueued` / `RedemptionFulfilled`                     | A redemption is queued / paid                 |
| `FeesTaken(mgmtFeeShares)`                                     | Streaming management fee minted               |
| `CohortValueSet(cohortId, old, new, at)`                       | Oracle hardware value updated                 |
| `ReserveAttested(cohortId, value, evidenceHash, attestor, at)` | Proof-of-reserve attestation recorded         |
| `AssetIdentitySet` / `AssetStatusChanged`                      | Hardware identity anchored / lifecycle change |

## Upgradeability

Core contracts are deployed behind **UUPS proxies**, so implementations can be upgraded without changing addresses or migrating balances. Upgrade authority (`UPGRADER_ROLE`) is held by the protocol admin today and moves to a multi-signature / governance setup at the audited Phase-2 redeploy. Each contract reserves a storage `__gap` so state can be extended across upgrades without collisions.

<Note>
  Config is **chain-agnostic** — chain id, RPC, and token addresses are parameters, so a second chain later is a deploy, not a rewrite.
</Note>

## The source-of-truth principle

Ownership and positions are reconstructed from **verified on-chain events** by an event indexer, not from client input:

```mermaid theme={null}
flowchart LR
    TX[On-chain deposit/redeem tx] --> EV[Transfer / Deposit event]
    EV -->|indexed and verified| BE[Chain-as-truth holder state]
    BE --> RPT[NAV, holdings, and reporting]
```

This is the invariant the protocol holds before real value moves on mainnet — see the [roadmap](/why-ix-rwa#roadmap).
