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
- User calls
supply(caller, account_id, spoke_id, assets). account_id = 0creates an account bound tospoke_id.- Controller authenticates caller and checks spoke asset configuration.
- Controller transfers tokens to pool.
- Pool syncs the hub-asset row, mints scaled supply shares, enforces caps.
- Controller writes
SupplyPositions(account_id)and emits position events.
Borrow
- User calls
borrow(caller, account_id, borrows, to). - Controller authenticates owner/delegate and loads account state.
- Controller resolves strict oracle prices, checks spoke borrow flags, caps, LTV, and health factor.
- Pool syncs the hub-asset row, mints scaled debt shares, checks
cashand utilization, then transfers tokens totoorcaller. - Controller writes
BorrowPositions(account_id)and emits position events.
Withdraw
- User calls
withdraw(caller, account_id, withdrawals, to). - Amount
0means close that hub-asset supply position. - If the account has debt, controller applies strict risk checks after the withdrawal. Debt-free withdrawals use the de-risking path.
- Pool burns supply shares and transfers tokens.
Repay
- Any payer calls
repay(caller, account_id, payments). - Controller transfers payment tokens to pool.
- Pool burns debt shares and refunds overpayment.
- Controller updates debt positions.
Liquidation
- Liquidator calls
liquidate(liquidator, account_id, debt_payments). - Controller resolves strict liquidation prices and requires health factor below one.
- Debt payments repay pool debt.
- Collateral is withdrawn from pool to liquidator, with protocol fee applied.
- Eligible residual bad debt can be cleaned and socialized through the supply index floor.
Flash Loan
- User calls
flash_loan(caller, asset, amount, receiver, data). - Controller validates
asset: HubAssetKey, fee, and flash-loan availability. - Pool snapshots balance, transfers the amount, invokes receiver callback, pulls repayment, and verifies final balance.
- Fee is recorded as protocol revenue.

