Skip to main content
Build, deploy, and bring up the protocol: governance first, then the controller, then the single central pool, then each market through timelocked proposals, then unpause. The operator surface is the repo Makefile (wrapping the stellar CLI) plus configs/script.sh. The same sequence applies to testnet and mainnet; substitute testnet or mainnet for <network> below.

Source of truth

FilePurpose
configs/networks.jsonPer-network RPC, passphrase, governance, controller, pool, aggregator, timelock delay, and WASM hashes.
configs/mainnet_markets.jsonMainnet market definitions (asset, rate model, risk config).
configs/testnet_markets.jsonTestnet market definitions.
configs/spokes.jsonSpoke definitions and per-asset spoke memberships per network.
configs/blend_pools.jsonApproved Blend pool addresses for migration.
MakefileBuild, deploy, configure, market setup, and inspection targets.

Prerequisites

  • The stellar CLI and jq.
  • A Rust toolchain matching rust-toolchain.toml.
  • A funded signing identity (default deployer), or SIGNER=ledger for a ledger-backed signer.

Build artifacts

make build              # stellar contract build — all contracts
make deploy-artifacts   # optimize + stage stripped WASM under artifacts/wasm/deploy/
make deploy-artifacts produces governance.wasm, controller.wasm, and pool.wasm for upload.

Deploy and bring-up order

The order is load-bearing. Governance deploys first. The controller starts paused at construction with governance as owner. The pool deploys once for the whole protocol. Each asset registers on that shared pool through timelocked proposals. make setup-<network> runs the full sequence. The steps below show what each phase does.
1

Deploy governance

Uploads pool, controller, and governance WASM, then deploys governance with __constructor(admin, min_delay). Governance grants PROPOSER, EXECUTOR, CANCELLER, and ORACLE to the admin. Writes governance id and timelock delay to configs/networks.json.
make deploy-<network>
2

Deploy the controller

Governance calls deploy_controller(controller_wasm_hash) immediately (one-time, owner-gated). The controller constructor sets governance as owner, grants ORACLE to governance, and pauses the contract.
# bundled in make deploy-<network>
stellar contract invoke --id <governance> --network <network> \
  -- deploy_controller --wasm-hash <controller_wasm_hash>
3

Set pool template and deploy the central pool

Schedule and execute pool template registration, then pool deployment. Each step is timelocked in production.
# propose_set_pool_template → execute
# propose_deploy_pool → execute   // once; repeat reverts #5 PoolAlreadyDeployed
configure-controller bundles template, pool deploy, aggregator, accumulator, and ORACLE role grant.
4

Register each market on the shared pool

Per asset, governance schedules:
  1. propose_approve_token
  2. propose_create_liquidity_pool
  3. propose_configure_market_oracle
  4. propose_edit_asset_config
Each proposal executes after the timelock delay. create_liquidity_pool registers the hub asset on the existing central pool. Price reads work only after AssetOracle(asset) is configured.
make setupAll NETWORK=<network>   # driven by configs/script.sh
create_liquidity_pool reverts with #30 PoolNotInitialized if deploy_pool has not run, #35 TokenNotApproved if the token was not approved, and #2 AssetAlreadySupported if already listed.
5

Configure spokes and Blend pools

Spokes are configured from configs/spokes.json:
propose AdminOperation::AddSpoke execute
propose AdminOperation::AddAssetToSpoke per hub asset execute
Blend migration pools are approved from configs/blend_pools.json:
propose_approve_blend_pool execute
6

Unpause

Turn the protocol live only after the pool is deployed and every market is Active.
stellar contract invoke --id <governance> --network <network> \
  -- unpause
Unpause is immediate through the governance owner. It forwards to the paused controller.
make setup-<network> chains: deploy-<network>configure-controller → market, spoke, and Blend setup → unpause. Run individual targets only for partial deploys or recovery.

Verification gates

Mainnet launch requires the acceptance matrix in the architecture reference: workspace tests, integration harness, fuzz targets, Certora profiles, external audit closure, 14-day testnet soak, and pause drill. Initial launch caps (ADR 0009): USD 250,000 total TVL, USD 100,000 total borrow, USD 100,000 per-market supply, USD 50,000 per-market borrow.

Upgrades

TargetPathEffect
make <network> upgradePoolTemplatepropose_set_pool_template → executeUpload and register new pool WASM template.
make <network> upgradePoolspropose_upgrade_pool → executeUpgrade the single central pool in place.
make <network> upgradeControllerpropose_upgrade_controller → executeUpgrade controller WASM (auto-pauses first).
make <network> upgradeAlltemplate → controller → pool → unpauseFull upgrade then re-enable.
Governance self-upgrade uses propose_governance_upgradeexecute_governance_upgrade.

Smoke tests

make <network> deployFlashReceiver
make <network> fundFlashReceiver
make <network> testFlashReceiver
Confirm market state with make <network> getAllMarkets and make <network> getAllIndexes.

Next

Governance

Timelock roles and the propose/execute lifecycle.

Configuration

Validation rules for risk, oracle, and spoke parameters.

Addresses

Deployed contract addresses per network.