XOXNO Stellar Lending uses one central liquidity pool yet supports many different risk profiles and asset classes. The mechanism is hubs for market isolation and spokes for per-account risk configuration.
This design appears in the protocol README, SCF_BUILD_ARCHITECTURE.md, and the mainnet configs. It is the reason the same USDC can appear with different caps in different spokes, and why RWA assets live on their own hub.
One pool, many keys: HubAssetKey
The pool stores all accounting under HubAssetKey { hub_id: u32, asset: Address }.
From SCF_BUILD_ARCHITECTURE.md:
- Markets are addressed by HubAssetKey.
- The same token on different hubs shares no indexes, revenue, cash, debt, or bad-debt socialization.
Hubs.json today maps:
- 1 → "Core"
- 2 → "RWA"
markets.json and spokes.json reference these ids. When the controller and pool operate on a key, every read and write stays scoped to that (hub, asset) pair. A direct token donation cannot increase borrowable liquidity for any key; only real supply does.
Spokes: risk and caps per configuration
A spoke is a risk profile an account binds to. Each spoke in spokes.json declares the assets it supports together with:
- can_be_collateral / can_be_borrowed
- ltv, liquidation_threshold, liquidation_bonus, liquidation_fees
- supply_cap, borrow_cap
Example from mainnet spokes.json (numbers are raw token units):
Main spoke (id 1) for USDC on hub 1:
- ltv: 7600
- liquidation_threshold: 8000
- supply_cap: 280000000000000
- borrow_cap: 210000000000000
Etherfuse spoke (id 2) lists the same USDC (still hub 1) with its own caps:
- supply_cap: 84000000000000
- borrow_cap: 63000000000000
Spiko, Centrifuge, and Forex spokes repeat the pattern with different numbers. RWA assets such as USDY, USTRY, CETES, and the Spiko T-bill tokens appear only on hub 2 with borrow_cap "0" and can_be_borrowed false in the current config.
Because the spoke is chosen per account, two users can supply the same asset under completely different risk rules without changing the underlying pool math.
Liquidity isolation without pool fragmentation
Isolation works at two layers:
- Hub layer (HubAssetKey) — accounting, interest indexes, revenue, and bad-debt socialization stay separate per (hub, asset).
- Spoke layer — borrow limits, liquidation thresholds, and caps are loaded from the account’s spoke for every risk check.
Cross-asset positions on one account still see the full picture through the controller. Health factor sums weighted collateral across all hubs the account uses, using the thresholds from its active spoke.
ADR 0001 explains the central-pool choice: separate pool contracts per asset would fragment multi-asset flows; key-based isolation inside one pool keeps batching and cross-asset health while preserving separation.
Per-spoke liquidation curves (ADR 0012)
Different spokes can also carry their own liquidation curve:
- liquidation_target_hf_wad (default 1.02)
- hf_for_max_bonus_wad
- liquidation_bonus_factor_bps
The curve sizes repayment and interpolates the bonus based on how far underwater the position is. An RWA spoke can use gentler parameters than a volatile-collateral spoke. The change is timelocked governance.
INVARIANTS.md records the bounds that keep the curve safe for every spoke.
Configs as the source of truth
All of the above lives in the repo under configs/mainnet/:
- hubs.json — hub id to label
- spokes.json — per-spoke asset risk and caps
- markets.json — baseline asset config plus oracle and rate parameters
- blend.json — approved Blend V2 pools for migration
These files are the concrete data the protocol and keeper use. They show how the system can list different configs in each spoke and keep liquidity isolated by hub without deploying extra pool contracts.
Using the design today
The live experience remains the Core hub markets. Visit the lending markets to supply USDC or XLM against the shared pool.
To understand how the same architecture supports the growing set of tokenized assets, see the article on RWAs on Stellar. For the comparison to other designs on the network, read the XOXNO vs Blend V2 piece.
All numbers and structures above are taken directly from the inspected rs-lending-xlm repository files at the time of writing. Actual on-chain state and governance decisions determine what is active.