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

# Stellar lending data flow

> How requests move through controller, pool, oracle, aggregator, and token contracts.

The controller mediates lending flows. The pool is controller-owned and stores
accounting by `HubAssetKey`. External contracts are treated as untrusted at the
boundary where their output enters protocol logic.

## Trust Boundaries

| Edge                     | Trusted                                | Validated                                                                                                            |
| ------------------------ | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Caller -> controller     | Nothing by default.                    | Auth, account owner/delegate, pause state, reentry guard, positive amounts, spoke listing, caps, LTV, health factor. |
| Controller -> pool       | Controller is pool owner.              | Pool checks owner, reserves, caps, utilization, and per-market accounting invariants.                                |
| Controller -> oracle     | No provider output is trusted blindly. | Staleness, future timestamp, decimals, sanity bounds, tolerance, and source availability.                            |
| Controller -> aggregator | Route output is untrusted.             | Controller snapshots balances and verifies input/output deltas.                                                      |
| Pool -> token            | Token transfer semantics.              | Pool uses internal `cash` for borrowable liquidity and reserve checks.                                               |
| Pool -> receiver         | Receiver is arbitrary code.            | Pool snapshots balance and verifies repayment after callback.                                                        |

## Supply

1. User calls `supply(caller, account_id, spoke_id, assets)`.
2. `account_id = 0` creates an account bound to `spoke_id`.
3. Controller authenticates caller and checks spoke asset configuration.
4. Controller transfers tokens to pool.
5. Pool syncs the hub-asset row, mints scaled supply shares, enforces caps.
6. Controller writes `SupplyPositions(account_id)` and emits position events.

## Borrow

1. User calls `borrow(caller, account_id, borrows, to)`.
2. Controller authenticates owner/delegate and loads account state.
3. Controller resolves strict oracle prices, checks spoke borrow flags, caps, LTV,
   and health factor.
4. Pool syncs the hub-asset row, mints scaled debt shares, checks `cash` and
   utilization, then transfers tokens to `to` or `caller`.
5. Controller writes `BorrowPositions(account_id)` and emits position events.

## Withdraw

1. User calls `withdraw(caller, account_id, withdrawals, to)`.
2. Amount `0` means close that hub-asset supply position.
3. If the account has debt, controller applies strict risk checks after the
   withdrawal. Debt-free withdrawals use the de-risking path.
4. Pool burns supply shares and transfers tokens.

## Repay

1. Any payer calls `repay(caller, account_id, payments)`.
2. Controller transfers payment tokens to pool.
3. Pool burns debt shares and refunds overpayment.
4. Controller updates debt positions.

## Liquidation

1. Liquidator calls `liquidate(liquidator, account_id, debt_payments)`.
2. Controller resolves strict liquidation prices and requires health factor below
   one.
3. Debt payments repay pool debt.
4. Collateral is withdrawn from pool to liquidator, with protocol fee applied.
5. Eligible residual bad debt can be cleaned and socialized through the supply
   index floor.

## Flash Loan

1. User calls `flash_loan(caller, asset, amount, receiver, data)`.
2. Controller validates `asset: HubAssetKey`, fee, and flash-loan availability.
3. Pool snapshots balance, transfers the amount, invokes receiver callback, pulls
   repayment, and verifies final balance.
4. Fee is recorded as protocol revenue.

## Strategy Routes

Strategy entrypoints use aggregator route bytes. Controller validates balance
deltas and final account risk. Slippage control lives in the route payload unless
a controller-side minimum-output field is added in a future version.
