Skip to main content
Supply and borrow go through the controller. The controller resolves the account, loads spoke configuration, checks oracle policy, moves tokens, and calls the central pool. Pool state is keyed by HubAssetKey. Read first: Accounts and risk, Markets, and Health factor.

Supply

supply(
  caller: Address,
  account_id: u64,
  spoke_id: u32,
  assets: Vec<(HubAssetKey, i128)>,
) -> u64
Passing account_id = 0 creates a new account owned by caller and bound to spoke_id. Existing accounts keep their stored spoke; the supplied spoke_id must match that account.

Preconditions

  • caller authorizes the call and token transfers.
  • Each HubAssetKey is listed in the pool.
  • The account’s spoke lists the hub asset.
  • The spoke asset is collateralizable and not blocked for increases.
  • Supply caps and position limits leave enough headroom.

Example

stellar contract invoke \
  --id <CONTROLLER> \
  --source-account <CALLER> \
  --network testnet \
  -- supply \
  --caller <CALLER> \
  --account_id 0 \
  --spoke_id 1 \
  --assets '[[{"hub_id":1,"asset":"<USDC>"}, "10000000000"]]'

Common Errors

ErrorCauseFix
#104 NotCollateralSpoke asset cannot be used as collateral.Use a collateralizable asset or another spoke.
#311 SpokeSupplyCapReachedSpoke supply cap exceeded.Supply less or wait for cap headroom.
#109 PositionLimitExceededAccount already holds max supply positions.Consolidate positions or wait for a limit change.
#315 SpokeAssetPausedSpoke asset is paused.Wait for governance to unpause or use another asset.
#316 SpokeAssetFrozenPosition increase is frozen.Exit-only actions may still be available.

Borrow

borrow(
  caller: Address,
  account_id: u64,
  borrows: Vec<(HubAssetKey, i128)>,
  to: Option<Address>,
)
Borrow records debt on account_id. Tokens go to to when set, otherwise to caller.

Preconditions

  • caller owns the account or is authorized for it.
  • Each borrowed hub asset is listed by the account’s spoke and borrowable.
  • Borrow caps, liquidity, and utilization caps leave enough headroom.
  • Post-borrow LTV and health factor pass.
  • Strict oracle policy passes for every priced asset.

Example

stellar contract invoke \
  --id <CONTROLLER> \
  --source-account <CALLER> \
  --network testnet \
  -- borrow \
  --caller <CALLER> \
  --account_id 42 \
  --borrows '[[{"hub_id":1,"asset":"<XLM>"}, "2000000000"]]' \
  --to null

Common Errors

ErrorCauseFix
#107 AssetNotBorrowableSpoke asset is not borrowable.Borrow an allowed asset.
#312 SpokeBorrowCapReachedSpoke borrow cap exceeded.Borrow less or wait for cap headroom.
#100 InsufficientCollateralLTV gate fails.Add collateral or borrow less.
#102 HealthFactorTooLowPost-borrow health factor is below one.Reduce borrow or add collateral.
#112 InsufficientLiquidityPool cash is below requested amount.Borrow less or wait for liquidity.
#126 MinBorrowCollateralNotMetDebt remains but collateral is below the configured floor.Add collateral or reduce debt.
#127 UtilizationAboveMaxPost-borrow utilization is too high.Borrow less or wait for more supply.

Verification

Successful supply or borrow emits controller position and market-state events. Read back state through controller views such as get_account_positions, collateral_amount_for_hub_asset, borrow_amount_for_hub_asset, and health_factor.

Next

Withdraw and repay

Exit collateral and repay debt.

Flash loans

Borrow and repay inside one callback.