to, or to caller when no
recipient is set. The caller must own the account’s position NFT or hold an
active delegate grant.
An account with debt must still pass its
LTV and health-factor gates after the
withdrawal. Repay debt first when a larger
withdrawal would fail those checks.
Choose the amount
Each withdrawal is(HubAssetKey, amount) in token base units. The list must
be nonempty and amounts cannot be negative. 0 requests the full position
after interest accrues. A positive amount below the half-up displayed balance
requests a partial withdrawal. An amount at or above that balance also closes
the asset’s position and pays its floor-valued claim.
Duplicate market entries are summed in first-appearance order. Any zero entry
for a market makes its total a full withdrawal, including when other entries
for that market are positive.
Check withdrawal conditions
- Each requested market has a supply position in the account.
- The pool has enough cash and the withdrawal passes the market’s utilization limit.
- If debt remains, LTV coverage and health factor pass, and LTV-weighted collateral meets the minimum-borrow floor.
- If debt remains, each collateral position below 3 decimals holds at least two token base units.
- Valid prices are available for indebted account valuation. Debt-free withdrawal skips valuation.
- The listing is not paused. Frozen or missing listings permit withdrawal of existing collateral. Global protocol pause permits withdrawal.
- The recipient is neither the controller nor the pool.
Build and authorize the call
market. The RPC
must use the selected network. Sign only the returned prepared XDR. Follow the
wallet transaction lifecycle
for signing, submission, confirmation, and uncertain outcomes. Use
buildStellarWithdrawBatchTx for several supply markets.
caller authorizes the controller call. The pool pays the recipient directly;
no caller token-transfer authorization is needed. An optional recipient changes
the payout destination only.
Verify the withdrawal
The return value contains actual payouts for each aggregated market. Readget_collateral_amount(account_id, hub_asset) to confirm the remaining balance.
For accounts with debt, also read get_health_factor(account_id).
The controller emits UpdatePositionBatchEvent at
["position", "batch_update"], with Withdraw legs. The pool emits
PoolMarketStateBatchEvent at ["market", "batch_state_update"].
Withdrawing the final position from a debt-free account removes the account and
burns its NFT. get_account_attributes(account_id) then raises
#13 AccountNotInMarket. Clear the stored id only after a successful
account_exists(account_id) read returns false. An RPC, restoration, or
ownership lookup error does not prove account deletion.
After confirmed deletion, pass account_id = 0 to create the next account.
See account lifecycle.
Common errors
For contract-owned accounts, see Vault integrations.

