LiquidityPool is a single contract that holds pooled liquidity and accounting
for every listed market, keyed by HubAssetKey. The same token on two hubs is
two independent markets. The controller owns the pool and authorizes every
mutating call.
Signatures omit the Soroban-injected Env argument. Construction uses
__constructor(admin: Address) to set the owner.
Types are in Data types. Pool events are in
Events.
Lifecycle
create_market validates params and initializes the market with indexes at
RAY and zero balances. It raises #2 AssetAlreadySupported if the market already
exists. update_params accrues at the old rate before replacing the model.
Accounting calls
supply, borrow, withdraw, and repay return one mutation per input entry.
Each entry identifies its market with a full HubAssetKey.
Flash loan
amount, and checks the exact
pool balance decrease. It calls
receiver.execute_flash_loan(initiator, asset, amount, fee, pool, data) and checks
that the callback did not change the pool balance. It then pulls amount + fee
with transfer_from and checks final_balance = pre_balance + fee.
The receiver must be a deployed Wasm contract (#412). It must approve the pool
for principal plus fee. An allowance or balance mismatch fails with #402. Token
transfer failures can instead return the token contract’s error. The pool books
the fee as revenue and returns it.
Views
Views require no authorization. Market loads renew TTL. Balance and rate views use stored indexes;get_bulk_indexes projects accrual to the current ledger
time without committing accounting state. A mutation can accrue again before
settlement.
Direct token donations are excluded from
get_reserves. For the balance checks
used during settlement, see
Token and accounting assumptions.
Maintenance and revenue
update_indexes accrues interest to ledger time without moving tokens.
claim_revenue syncs the indexes, reconstructs the revenue claim, caps the
payout at available cash, burns enough revenue shares (ceil-rounded), and
transfers the payout. It always pays its owner, the controller, which forwards the proceeds
to the configured accumulator.
Accounting checks
Pool paths apply local accounting checks. Which checks run depends on the operation:- Rejects invalid amounts (
#14); full withdrawal usesi128::MAX. - Panics
#30 PoolNotInitializedif the market’sParams/Statekeys are absent. - Checks available cash (
#112). Debt mints also preserve the liquidation buffer. Ordinary withdrawals do not apply that buffer. - Debt mints and ordinary withdrawals check max utilization (
#127). Liquidation withdrawals and empty closes skip that check. - Rejects a positive movement that would change zero shares (
#47,#49,#50,#51,#52). - Applies operation-specific solvency checks (
#123). Backing checks compare floored supply claims with cash plus ceiling-rounded debt. Withdrawals also reject zero supply with remaining debt. - Validates the rate model on
create_marketandupdate_params. - Verifies flash-loan repayment with a pre/post balance check.
Next
Controller ABI
The public entrypoints that call this interface.
Storage
The
HubAssetKey-keyed PoolKey layout, durability, and TTL.
