Skip to main content
Protocol configuration is owner-gated on the controller. In production, governance owns the controller and schedules configuration changes through timelock.

Authority

The current controller does not depend on keeper, revenue, or oracle operational roles for maintenance calls.

Hub and pool setup

  1. Create the hub (CreateHub).
  2. Deploy the central pool once (DeployPool(wasm_hash)) and the position NFT (DeployPositionNft). The hash is an argument — there is no pool-template registration step.
  3. Create the market on that pool (CreateLiquidityPool).
  4. Configure the asset’s oracle on the price aggregator (ConfigureAssetOracle).
  5. List the asset on each spoke that may use it (AddAssetToSpoke).
Pool rows are keyed by HubAssetKey { hub_id, asset }. There is no token allow-list gating market creation.

Spokes

Spokes define account risk policy. Accounts bind to a spoke id >= 1. Spoke asset configuration includes:
  • collateral and borrow flags;
  • the three halt flags: paused (blocks every verb), frozen (blocks entry, allows exit), no_seize (blocks only liquidation seizure);
  • LTV, liquidation threshold, liquidation bonus, liquidation fee;
  • spoke-level supply and borrow caps, in raw asset units. Zero means no new exposure, not “unlimited”.
The spoke itself also carries the liquidation curve — liquidation_target_hf_wad, hf_for_max_bonus_wad, and liquidation_bonus_factor_bps — set with SetSpokeLiquidationCurve. Spokes do not set or override oracles. Pricing is protocol-level on the price aggregator, keyed by PriceKey::Token(asset). Governance uses owner-gated controller calls to add spokes (AddSpoke), mark them deprecated (RemoveSpoke), and add, edit, or remove SpokeAsset(spoke_id, HubAssetKey) rows. A listing with non-zero usage cannot be removed (#309 SpokeAssetInUse).

Pool params

Pool params include the interest-rate curve, reserve factor, flash-loan settings, asset address, and decimals. Updates accrue interest under the old params before applying the new params. Validation checks:
  • slope chain is monotonic;
  • max borrow rate stays within the configured safety bound;
  • utilization breakpoints are ordered;
  • reserve factor is below 100%.

Oracle config

Oracle config lives on the price aggregator, keyed by PriceKey::Token(address) or PriceKey::Ref(symbol). All spokes share it; there is no per-spoke override. An AssetOracle declares one or two price sources, the tolerance band between them, an independence policy, staleness and decimal bounds, and a sanity band. Validation runs at proposal time and checks all of it: source count, provider shape, decimals, staleness bounds, feed resolution, TWAP record counts, tolerance reciprocity, sanity bounds, composition depth, and cycles. It also rejects a configuration whose sources are all unsmoothed spot market feeds (#38 SpotOnlyNotProductionSafe). At least one leg must be smoothed or fundamental. Adjusting only the sanity band or only the tolerance has dedicated calls (set_sanity_band, set_tolerance); the guardian fast path on the sanity band may only tighten.

Pause readiness

Before unpause:
  • central pool is deployed;
  • target markets have pool rows and oracle config;
  • required spokes list the launched hub assets;
  • swap-aggregator, price-aggregator, and accumulator addresses are set;
  • the position NFT is deployed and recorded;
  • position limits and the minimum-borrow floor are set;
  • keeper config lists the same launched HubAssetKey markets.

Next

Deployment

Build, deploy, and bring-up sequence.

Security model

Trust boundaries, authorization, and upgrade model.