Skip to main content
flash_position borrows into a lending account, forwards tokens to a receiver contract, and supplies the collateral the receiver sends to the controller. The account keeps the debt, and the strategy charges no flash fee. Use this entrypoint for a custom leveraged-position callback. Read account modes and authority and health-factor requirements first.

Prepare the account and receiver

Pass account_id = 0 to create the account. An existing account requires owner or active delegate authority, and its stored spoke and mode must match the arguments. Supported modes are Multiply, Long, and Short. The debt amount must be positive. Its market must be borrowable on the account’s spoke, belong to an active hub, and have is_flashloanable = true, including when its flash-loan fee is nonzero. This entrypoint still charges zero. Borrow caps, position limits, pool cash, and utilization limits apply. The protocol must be unpaused. The receiver must be a deployed Wasm contract and cannot be the controller or pool. Valid prices are fetched for the account and strategy assets before funding or the callback.

Declare collateral minimums

collaterals lists the markets whose callback receipts become supply. Each amount is a minimum controller receipt in that token’s native units. The controller validates the declarations before the callback:
  • The list is nonempty and has at most max_supply_positions entries.
  • Minimums are nonnegative, with at least one positive minimum.
  • Neither market keys nor underlying token addresses repeat.
  • Each market is listed on the account’s spoke, collateralizable, and allowed for supply.
  • The declared positions fit the account’s position-count limit.
The controller snapshots balances after forwarding the borrowed tokens and measures increases during the callback. It submits each positive collateral delta for supply; the pool then credits its measured receipt. Supply caps and final position counts apply to measured deposits after the callback. Declaration checks do not reserve cap headroom. A controller receipt minimum is not a guarantee of equal final collateral when the subsequent token transfer delivers a different amount.

Declare refund assets

refund_assets lists token addresses whose positive callback balance deltas are paid to caller. Refunds exclude balances already held by the controller before the callback. The recipient is the caller, including when a delegate initiates the transaction. Each refund asset must be listed and active on the account’s spoke under debt.hub_id. The list has at most max_supply_positions entries, contains no duplicates, and cannot overlap any declared collateral token. Invalid list shape raises #16 InvalidPayments; listing checks can also reject a token.
Returned debt tokens do not repay the account. A debt token declared as a refund is paid to the caller; one declared as collateral is supplied. Any undeclared token remains in the controller, which has no sweep or rescue entrypoint. Declare every token the callback can return before submitting the transaction.

Implement the callback

The receiver exports:
fee is zero. amount is the debt principal; amount_received is the receiver’s measured receipt and can differ from the principal. Size callback spending from amount_received. Authenticate the configured trusted controller and validate the expected initiator, account, asset, principal, and request data. Send resulting collateral and declared refunds to that controller. Callback arguments alone do not prove that the operation is authorized. The flash guard covers funding, forwarding, balance snapshots, and the callback. Guarded financial controller operations reject reentry with #400 FlashLoanOngoing. The receiver cannot repay this account through a nested controller call.

Simulate and verify

Build against the controller signature above and simulate the complete call before signing. The published SDK 1.0.228 has no dedicated flash-position builder. A custom builder must preserve this argument order and validate the prepared invocation and authorization entries against your own request. Follow Wallet integration to persist the original network, signed XDR, and hash before submission. Resolve an unknown outcome by that hash on the same network; do not repeat or replace the callback automatically. The final account must retain debt in debt and at least one supply position. Otherwise, the call raises #505 FlashPositionClosed. Finalization refreshes listed collateral LTV, then checks LTV coverage, health factor, and the configured USD collateral floor. Each collateral position with fewer than three decimals must retain at least two base units after floor conversion. Failure reverts the whole transaction. Persist the returned account id and confirm native balances through get_collateral_amount and get_borrow_amount. The position batch tags the debt increase as FlashPos (16) and supplied collateral as Supply (0). FlashPositionEvent reports principal, measured receiver receipt, and fee = 0. There is no dedicated refund preview or refund field in the return value or FlashPositionEvent. Confirm refunds from token transfer events and caller balances. Transaction simulation can estimate execution against its ledger state, but state can change before submission. For standard route-based leverage, use Strategies. For borrowing repaid within a callback, use Flash loans.