# Lotus documentation (full) > Lotus is directional liquidity and yield-bearing orders for Stellar: a Soroban range pool (lotus_pool) where a position only sells its inventory and never trades back, and a yield-bearing receipt (lUSDCb, minted 1:1 by lotus_vault against USDC lent on Blend through DeFindex) that can be quoted on the Stellar DEX. One order, four places to wait. Stellar testnet only, not audited. Generated from the same Markdown as https://lotus-stellar.vercel.app/docs. Index: https://lotus-stellar.vercel.app/llms.txt. Deployment check: https://lotus-stellar.vercel.app/api/health. --- # Overview > Lotus is directional liquidity and yield-bearing orders for Stellar. One order, chosen once, waits in one of four places. Everything runs on Stellar **testnet**; nothing is on mainnet and nothing is audited. ## What Lotus is Lotus is two products that work together: 1. **The Lotus pool** (`lotus_pool`, a Soroban contract): a range pool on a grid of price bins where the liquidity provider chooses a direction. A directional position only sells its inventory and only receives proceeds; nothing trades back. The USDC leg can optionally sit in a DeFindex vault that lends on Blend, so resting liquidity earns while it waits and is recalled just in time by the taker's own swap. 2. **The receipt tokens** (`lotus_vault`, a Soroban contract, plus the classic assets `lUSDCb` and `lUSDC`): USDC deposited into a DeFindex vault comes back as a classic Stellar asset at 1:1. Classic assets can be quoted on the Stellar DEX (SDEX), and an SDEX offer never moves funds out of the account, so a limit order quoted in `lUSDCb` keeps earning Blend interest while it waits in the book. `lUSDC` is the unlent version: an instant buffer for orders close to the price and for working capital. The market today is `LBOND / USDC`. `LBOND` is a **simulated** tokenized bond issued by the Lotus team with `AUTH_REQUIRED`, `AUTH_REVOCABLE` and clawback, to model a regulated real-world asset. ## The problem Depth is idle capital. A resting order earns nothing, and an AMM position forces the holder into round trips they do not want: buy low, get sold back the asset higher, hold whatever the market leaves. The holders who own the inventory and the cash, issuers and treasuries, are the ones who could provide depth and have the least reason to. On Stellar, yield-bearing RWAs already exist (Ondo USDY, Etherfuse Stablebonds). The asset side of a bond pair earns while it sits; the quote side, USDC, does not. Lotus makes the USDC side earn too. That gives large providers a reason to bring depth to Stellar: the same capital keeps its yield while it quotes. And the yield is better risk-adjusted than a generic lending vault's, because the Lotus curator knows the order behind every dollar: near-price capital stays unlent (`lUSDC`), capital that can wait is lent on Blend (`lUSDCb`). See [Concepts](/docs/concepts.md#the-buffer-lusdc). ## One order, four places to wait A liquidity provider creates one **range limit order** (sell LBOND across a price range, or USDC waiting to buy it) and chooses, at creation, where it waits: | | Yield off | Earn yield (USDC leg in DeFindex on Blend) | |---|---|---| | **Lotus pool** | directional position on the idle pool, 1 signature | directional position on the vault-backed pool, 1 signature | | **Stellar DEX** | ladder of offers quoted in USDC, 1 signature | ladder quoted in the receipt `lUSDCb`, 1 signature (sell) or 2 (buy: deposit, then offers) | Each bin of the range becomes one SDEX offer at the same price and size, so the order is the same wherever it waits. The choice is made once, at creation: a live position is never migrated between venues. Details in [Concepts](/docs/concepts.md). ## How the pieces connect ``` Stellar classic layer Soroban layer +---------------------------------------------+ +-------------------------------------+ | SDEX order books | | lotus_pool directional bins | | LBOND / lUSDCb, USDC / lUSDCb, LBOND/USDC | | (optional two-way) | | Classic assets: LBOND, USDC, lUSDCb | | lotus_vault deposit / redeem / | +----------------------^----------------------+ | distribute, admin of | | mints / burns lUSDCb | the lUSDCb SAC | +--------------------------+ DeFindex vault --> Blend lending | +-------------------------------------+ Bot (team accounts): market makers + arbitrageur, quotes and arbitrage across both venues ``` The pool and the SDEX are two venues for the same pair. They are linked on-chain only through shared assets and the DeFindex vault; prices are free to differ and an off-chain arbitrageur closes the gap. ## Status and honest limitations - **Testnet only.** Network passphrase `Test SDF Network ; September 2015`. No mainnet deployment, no audit, no pause, no upgrade path. - **Volume is our own.** Trades on the Lotus markets come from accounts run by the Lotus team (two market makers and an arbitrageur). It is market-maker volume, not user volume. See [Bots and volume](/docs/bots-and-volume.md). - **LBOND is simulated.** Its price follows a simulated US 10-year Treasury model; the only real input is the starting yield. - **Yield is observed, not promised.** Blend testnet supply interest is real, and its rate follows Blend's testnet utilization. Any APR the app shows is labelled "observed on testnet, not a forecast". - **Known weaknesses** of the receipt: yield is distributed by a keeper that mints to current holders, so a just-in-time depositor can capture a share it did not earn. The vault-backed pool does not have this problem (it accounts yield in vault shares). - **Issuer trust.** The LBOND issuer can revoke a trustline, including the pool's; a Bid LP's USDC could then be stuck until re-authorization. - **Footprint race** on the vault-backed pool: a transaction can fail with `ExceededLimit` when the shared vault changes by a stroop between simulation and inclusion; the app re-simulates and resends. The full list is on the [FAQ](/docs/faq.md) and in the repository README. ## Where to go next - [Concepts](/docs/concepts.md): bins, the four strategies, the receipt, the curator rule, locked orders. - [Using the app](/docs/using-the-app.md): `/swap`, `/pools`, `/trade`, `/portfolio`, `/faucet`. - [Contracts](/docs/contracts.md): ABI, errors, events and live testnet addresses. - [Integrate](/docs/integrate.md): SDK, MCP server for AI agents, HTTP endpoints. - For AI agents: [`/llms.txt`](/llms.txt), [`/llms-full.txt`](/llms-full.txt), and [`/api/health`](/api/health) to check that the deployment works. --- # Concepts > The directional range pool and its bins, the four places an order can wait, the receipt token and its redemption at par, the curator rule, and why orders are locked until filled. ## Units All on-chain amounts are `i128` stroops (7 decimals: `1 USDC = 10_000_000`). Pool prices are QUOTE per BASE in fixed point `1e7` (`1.0000000 = 10_000_000`). BASE is `LBOND`, QUOTE is `USDC` (Blend testnet USDC). ## The directional range pool `lotus_pool` keeps liquidity on a grid of **bins**. The price of bin `n` is ``` price_at(n) = round_half_up(1e7 * (1 + bin_step_bps / 10_000) ^ n) ``` with bins from `-200` to `200`. The live instances use `bin_step_bps = 10` (0.1 percent per bin), so bins `-20..20` cover about 0.98 to 1.02. A position covers at most 64 bins, each non-empty bin share must be at least `10_000` stroops, and a swap walks at most `max_bins_per_swap` (100) bins. A position has a **side**: - `Ask`: deposits BASE (LBOND) and sells it as the price rises through its bins; it receives USDC. - `Bid`: deposits QUOTE (USDC) and buys LBOND as the price falls; it receives LBOND. and a **mode**: - `Directional` (the default and the product): inventory only goes down, proceeds only come in, and proceeds are never re-offered. The position never trades back. - `TwoWay` (opt-in, only on pools without a vault): DLMM-style bins that hold both assets, so liquidity crosses back when the price returns, like a classic AMM LP. Directional and two-way liquidity share the same book; at each price, the swap takes directional liquidity first. **Fees**: 10 bps (`fee_bps = 10`), charged on top of the price leg and credited to the bin's LPs. The LP always receives its exact limit price. A buyer pays `ceil(q) + ceil(q * fee_bps / 10000)`, a seller receives `floor(q) - ceil(q * fee_bps / 10000)`, where `q = quantity * bin_price`. **Yield vault (optional, per pool instance)**: a pool instance can hold its whole USDC leg (bid inventory, ask proceeds, fees) as DeFindex vault shares, so it earns Blend interest without a keeper. A buy swap deposits the taker's USDC into the vault; a sell swap withdraws exactly what the taker is owed, just in time. The yield strategy is a property of the instance, so there is one instance per strategy (idle, vault-backed, two-way). ## The four strategies One order, chosen once: | | Yield off | Earn yield | |---|---|---| | **Lotus pool** | `add_position(Directional)` on the idle pool instance. 1 signature. | `add_position(Directional)` on the vault-backed instance (USDC leg in DeFindex on Blend). 1 signature. | | **Stellar DEX** | One classic transaction, one `manageSellOffer` per bin, quoted in USDC. 1 signature. | Offers quoted in the receipt `lUSDCb`. Sell: 1 signature. Buy: `lotus_vault.deposit(USDC)` then the offers, 2 signatures. | - **Ladder mapping.** Each bin becomes one SDEX offer at `price_at(bin)` with the bin's own amount. The SDEX ladder is capped at 50 levels (the pool allows 64), so the order plus up to two trustlines fit in one transaction. - **Why two transactions for a receipt buy.** A Soroban call must be the only operation of its transaction, so the deposit and the offers cannot be atomic. The app has both signed up front and only submits the offers once the deposit has succeeded. If the deposit fails nothing moves; if the offers fail, the user simply holds the receipt, redeemable at par, and can post the offers again. - **Where yield comes from.** Blend testnet supply interest, through a DeFindex vault the Lotus team created and seeded into the Blend strategy. Accrual is real; the rate follows Blend's testnet utilization, so it is an observation, not a forecast. BLND emissions are not counted. ## The receipt: lUSDCb `lUSDCb` is a **classic Stellar asset**. The admin of its Stellar Asset Contract (SAC) is the `lotus_vault` Soroban contract, which mints on deposit and distribution, burns on redeem, and tracks supply. - `deposit(from, amount)`: USDC goes into the DeFindex vault (which lends on Blend); `amount` of the receipt is minted 1:1. - `redeem(from, amount)`: the receipt is burned, the vault is withdrawn from, USDC is returned. **1:1 while fully backed**; pro rata (`amount * vault_value / supply`) if the vault position ever lost value, so the last redeemer is never left holding an unbacked receipt. - `distribute(recipients, amounts)` (keeper only): the keeper submits holders and amounts; each line is capped on-chain at `surplus * balance / supply` and the total cannot exceed the surplus. The keeper can omit a holder or be late; it cannot over-mint or redirect yield. Balances locked in open SDEX offers count, because an offer is a selling liability, not a transfer. **Par redemption keeps the peg.** `deposit` and `redeem` are permissionless and 1:1. If the receipt trades under 1 USDC anyone can buy it and redeem; above 1, anyone can deposit and sell. The `USDC / lUSDCb` book is that peg book. Redemption depends on Blend having liquidity: if Blend is fully utilized, redemption waits and the receipt can trade at a discount. **Why a receipt and a pool.** A Blend position or a DeFindex share is a Soroban token: it cannot sit in an SDEX offer or be a path-payment hop. `lUSDCb` can be the quote of a ladder and the middle leg of a path payment (`USDC -> lUSDCb -> LBOND` in one transaction), so a taker holding only USDC never has to know the receipt exists. Known limitation: **just-in-time yield capture**. Distribution mints to current balances, so someone who deposits right before a distribution and redeems right after captures a share they did not earn. The planned fix is an exchange-rate (share-price) token. ## The buffer: lUSDC `lUSDC` is the same receipt design on a second `lotus_vault` whose DeFindex vault is **never lent**: the USDC stays available, so it comes out instantly and redemptions never wait on Blend. It is made for orders close to the price, about to fill, and for the working capital a market maker keeps at hand. It earns nothing; `lUSDCb` is for orders that can wait. **Why two receipts.** A generic lending vault keeps blind buffers because it never knows when a depositor will withdraw. The Lotus curator does: every dollar sits behind a limit order with a known price, range and distance to the market. Capital behind orders about to fill stays unlent (`lUSDC`); capital behind orders that can wait is lent on Blend (`lUSDCb`). That is more yield for the same liquidity risk, and it lets large providers keep their yield while they post depth on Stellar. Today the split is enforced by the curator rule below; routing every order automatically by its distance to the price is the next step. ## The curator rule Yield is not offered for a **pool Bid** whose range starts within 10 bins (about 1 percent) of the reference price, because every trade would recall that USDC from the vault: little yield, more failure risk. In the app, the "Lotus pool + Blend yield" card is then disabled with "Too close to the price" and a **Change range** button. - Sell orders are never blocked (their yield is on proceeds that wait). - Receipt orders on the SDEX are never blocked (a receipt in an open offer keeps earning). - The rule lives in the app (`PROXIMITY_MIN_BINS = 10`); the contracts do not enforce it. ## Direction rule A sell range sits at or above the reference price of the venue it rests on; a buy range sits at or below it. The app clamps handles and presets and marks a strategy unavailable when its own reference price breaks the rule. The contract does not prevent crossed books (an Ask below a Bid). ## Locked orders In the app, a **directional order is locked until it is fully filled**: you can **Claim** proceeds and fees at any time, but Remove is replaced by "Early redemption, soon". The same holds for SDEX ranges quoted in a Lotus receipt. Two-way LP positions keep Remove. This is a product rule enforced by the UI only. On-chain, the pool contract's `remove_position` works at any time for the owner, and SDEX offers belong to the user's account and can be cancelled by any Stellar client. ## Compliance from the asset `LBOND` is `AUTH_REQUIRED`, `AUTH_REVOCABLE` and clawback-enabled. Makers and takers need a trustline authorized by the issuer, and the pool contract itself is authorized through the LBOND SAC. An unauthorized taker's trade fails at the protocol level with `op_not_authorized`. Compliance comes from the asset, not from pool code; the faucet authorizes testnet trustlines for you. --- # Using the app > A walk through every screen: get test tokens on `/faucet`, swap or place one-price and range orders on `/swap`, build a position across the four strategies on `/pools`, trade the SDEX books on `/trade`, and manage everything on `/portfolio`. Every action is signed in your own wallet. Any wallet supported by Stellar Wallets Kit works (Freighter, xBull, Albedo, Lobstr, Hana, ...). Set the wallet to **testnet**. There are no session keys and no auto-signing. ## /faucet: get started in about a minute 1. **Fund**: if the account does not exist yet, the Friendbot button funds it with test XLM. 2. **Add trustlines**: one classic transaction adds every missing `changeTrust` (LBOND, USDC, the active receipt). Each row shows the code, issuer, `CODE:ISSUER` with copy buttons and an explorer link. 3. **Claim test tokens**: the server authorizes your LBOND trustline (LBOND is `AUTH_REQUIRED`) and sends LBOND, Blend testnet USDC and the active receipt, one transaction per asset, with the hash of each. The amounts are set by the server; `GET /api/faucet` returns them. One claim per address and asset, and a light rate limit per network. A thin "Get test tokens" line appears under the nav on every page while your wallet is not ready. ## /swap: Lite and Pro One page with a **Lite / Pro** switch (`/swap`, `/swap?mode=pro`). - **Swap** (Lite and Pro): against the directional Lotus pool only. Every live directional instance is quoted (`quote_swap`) and the best one is kept. The details box shows the route, pool price, price impact, minimum received (with your slippage setting), pool fee and bins crossed. If the size is larger than the pool depth, it tells you how much would really fill. Execution re-quotes, then calls `swap(min_out)`. - **Limit** (Lite): Sell or Buy, "When 1 LBOND is worth" with market and percentage presets. One price is one bin. Orders have no expiry ("Until filled"). Then choose a strategy and confirm. - **Range** (Pro): the liquidity chart with draggable range handles next to Selling / Buying, start price and range end, presets, the strategy picker, then **Get started**. - DCA is visible but disabled ("Coming soon"). Limit and Range are the same order as `/pools` New position: same data, same strategy picker, same review dialog. ## /pools: New position Three steps, then a review dialog: 1. **Pair and side**: LBOND / USDC, **Sell LBOND** (Ask) or **Buy LBOND with USDC** (Bid). 2. **Price range and deposit**: draggable Start / End handles on a chart of SDEX trades (1H to 1Y) next to a depth histogram of every live pool instance's bins plus the SDEX books, all on the same grid. Presets, min / max fields with one-bin steppers, weight shape (even, front, back) and the deposit. 3. **Choose your strategy**: four cards (Lotus pool, Lotus pool + Blend yield, Stellar DEX, Stellar DEX + Blend yield), each with the expected yield, the number of signatures and, when unavailable, why (direction rule, curator rule, no instance, more than 50 SDEX levels). 4. **Review**: deposit, range, average price, fee or XLM reserve, trustlines added, crossing warning, then **Sign**. The two-transaction case (receipt buy) is handled here, including "Post the offers again" if the second step fails. The expected yield is the Blend USDC supply APR read live from the Blend pool (annualized growth of `b_rate` between two reads); until two reads exist the card shows the last figure measured by the team. Always labelled "observed on testnet, not a forecast". **Your positions** lists pool positions of every instance and your SDEX ladders, grouped per pair and side: status, fill bar, remaining, claimable proceeds and fees, **Claim**, and **View position** (the creating transaction on stellar.expert). Directional orders are locked until filled (see [Concepts](/docs/concepts.md#locked-orders)). Header actions: **Swap on the pool** and **Advanced: two-way position** (`?pool=lbond-usdc-twoway`), the builder for `Mode::TwoWay` LP positions. ## /trade: the SDEX terminal A classic exchange layout for the Stellar DEX books: - **Market bar**: `?market=LBOND-lUSDCb`, `USDC-lUSDCb` (the peg book), `LBOND-USDC`; last price, 24h change, high, low, volume, mid, spread. - **Chart**: candles from Horizon trade aggregations (1m to 1W), or cumulative depth. Empty buckets are drawn as flat grey candles at the previous close with zero volume: no trade is invented. - **Order book and trades**. Clicking a level fills the Limit price. - **Swap**: one `pathPaymentStrictSend` quoted from Horizon (`USDC -> lUSDCb -> LBOND` is one transaction). For LBOND/USDC, a venue comparison shows the Lotus pool quote next to the SDEX path. - **Limit**: one `manageSellOffer`, with a warning when the price crosses the book. - **Bottom panel**: open orders with Cancel, trade history (one row per operation, routed hops merged), balances. Range orders are placed from `/pools`; the order panel links there. ## /portfolio In order: a USDC-equivalent summary; **pool positions** (only instances where you hold one: pair, side, range, fill bar, amount to claim, **Claim** when something is claimable, otherwise "Locked until filled"); **Lotus receipts** per vault (`/portfolio#receipts`) with **Yield earned** (paid by the keeper every ~15 minutes, plus what is accrued) and **Redeem** to USDC; **open orders** on the SDEX; then **balances** (available versus committed to offers). Every address, asset, offer and transaction links to stellar.expert (testnet). ## Common errors | message | meaning | |---|---| | Not authorized by the issuer | your LBOND trustline is not authorized yet: claim from `/faucet` | | No liquidity in the Lotus pool at this size | the pool has no bins on that side; try a smaller size or the SDEX | | The vault state changed while signing, retry | footprint race on the shared DeFindex vault; the app already retried | | Too close to the price | curator rule: move the Bid range at least 10 bins below the price, or pick another strategy | | `op_not_authorized` | protocol-level rejection of an unauthorized LBOND trustline | --- # Contracts > The `lotus_pool` ABI (v1), the `lotus_vault` interface, their errors and events, and the live testnet addresses read from the deployment config at request time. Both contracts are Soroban (Rust, `soroban-sdk`), deployed on Stellar testnet only, not audited. Errors surface as `Error(Contract, #n)`; authorization failures are host `Auth` errors, not contract errors. Amounts are `i128` stroops (7 decimals). ## Live testnet addresses The table below is generated from the deployment files (`deployments/testnet.*.json`) every time this page is served, so it always matches what the app uses. If anything else disagrees with it, these files win. | | value | |---|---| | network | `testnet` | | passphrase | `Test SDF Network ; September 2015` | | Soroban RPC | `https://soroban-testnet.stellar.org` | | Horizon | `https://horizon-testnet.stellar.org` | | active lotus_vault | [`CCCZ6XUDCWTOKZS6AYNECY3QPOFBICGMBBZXM63U4WZQD4EBFYFW2QKG`](https://stellar.expert/explorer/testnet/contract/CCCZ6XUDCWTOKZS6AYNECY3QPOFBICGMBBZXM63U4WZQD4EBFYFW2QKG) | ### Lotus pool instances (lotus_pool) | id | status | contract | USDC leg | two-way | bin step / fee | |---|---|---|---|---|---| | `lbond-usdc-idle` | live | [`CCE2ISQKVWZJAZL6FRW227WDVWXODWUZ75ZQXGPKJWXERRW64NHS4CA3`](https://stellar.expert/explorer/testnet/contract/CCE2ISQKVWZJAZL6FRW227WDVWXODWUZ75ZQXGPKJWXERRW64NHS4CA3) | idle (held by the pool) | yes | 10 bps / 10 bps | | `lbond-usdc-defindex` | live | [`CDNG7T2KSDQ7ZYXHSDAM63RLLVPCQ5V6T5GRTXOOX47EZEMU636ZFPNG`](https://stellar.expert/explorer/testnet/contract/CDNG7T2KSDQ7ZYXHSDAM63RLLVPCQ5V6T5GRTXOOX47EZEMU636ZFPNG) | DeFindex vault [`CDCIDX5FXOENXW4ODR2D7QMRKL4F2NTZYFVZEFF63GTNRVVDXLCQ7EEC`](https://stellar.expert/explorer/testnet/contract/CDCIDX5FXOENXW4ODR2D7QMRKL4F2NTZYFVZEFF63GTNRVVDXLCQ7EEC) | no | 10 bps / 10 bps | | `lbond-usdc-twoway` | live | [`CC264FOWPI5R5FG4276ZIPGJ5OG5AP3IZ4RZNMC2KQNJDA7LQSFQ3SEI`](https://stellar.expert/explorer/testnet/contract/CC264FOWPI5R5FG4276ZIPGJ5OG5AP3IZ4RZNMC2KQNJDA7LQSFQ3SEI) | idle (held by the pool) | yes | 10 bps / 10 bps | Retired instances (hidden from the app's pool views, still listed on /portfolio so owners can claim or remove): `lbond-usdc-idle-v0` [`CDOXTKGMK7MHEIOVXN5OBETMFUQATRQCB5NHFBFKCVUF5OUHQHVTN6CF`](https://stellar.expert/explorer/testnet/contract/CDOXTKGMK7MHEIOVXN5OBETMFUQATRQCB5NHFBFKCVUF5OUHQHVTN6CF). ### Lotus vaults (lotus_vault) and receipts | strategy | status | lotus_vault | receipt (classic asset) | receipt SAC | DeFindex vault | |---|---|---|---|---|---| | `usdc-defindex-idle` | idle | [`CA5JHSNNGRX3QLLNRLOTDCXYGAYVC3ZRHXX6IWXQAD6YLILZ7TL2AHG6`](https://stellar.expert/explorer/testnet/contract/CA5JHSNNGRX3QLLNRLOTDCXYGAYVC3ZRHXX6IWXQAD6YLILZ7TL2AHG6) | [`lUSDC`](https://stellar.expert/explorer/testnet/asset/lUSDC-GBBBCE5XIN3KPPNETITZF4ZEC6NG4MZZ3I2CYIQGGGY4GN4DJO73GDL6) issuer [`GBBBCE5XIN3KPPNETITZF4ZEC6NG4MZZ3I2CYIQGGGY4GN4DJO73GDL6`](https://stellar.expert/explorer/testnet/account/GBBBCE5XIN3KPPNETITZF4ZEC6NG4MZZ3I2CYIQGGGY4GN4DJO73GDL6) | [`CDQ7HJZGK5RGIHAPWVCE7KVJIDOCQFPJI7CIYLRVNF5RKM62OJXL2HAV`](https://stellar.expert/explorer/testnet/contract/CDQ7HJZGK5RGIHAPWVCE7KVJIDOCQFPJI7CIYLRVNF5RKM62OJXL2HAV) | [`CBMVK2JK6NTOT2O4HNQAIQFJY232BHKGLIMXDVQVHIIZKDACXDFZDWHN`](https://stellar.expert/explorer/testnet/contract/CBMVK2JK6NTOT2O4HNQAIQFJY232BHKGLIMXDVQVHIIZKDACXDFZDWHN) | | `usdc-defindex-blend` (active) | live | [`CCCZ6XUDCWTOKZS6AYNECY3QPOFBICGMBBZXM63U4WZQD4EBFYFW2QKG`](https://stellar.expert/explorer/testnet/contract/CCCZ6XUDCWTOKZS6AYNECY3QPOFBICGMBBZXM63U4WZQD4EBFYFW2QKG) | [`lUSDCb`](https://stellar.expert/explorer/testnet/asset/lUSDCb-GC7QBZD2LMPZZ3BT4ZLKPYUR23GJKT47BLYJKMXUY523M7HMUGT64TVO) issuer [`GC7QBZD2LMPZZ3BT4ZLKPYUR23GJKT47BLYJKMXUY523M7HMUGT64TVO`](https://stellar.expert/explorer/testnet/account/GC7QBZD2LMPZZ3BT4ZLKPYUR23GJKT47BLYJKMXUY523M7HMUGT64TVO) | [`CC6YDSEJRF7QH5JL7MVEYEIU3CTMNEHS4XIK5R36DYA5EVUYIP4PAHPG`](https://stellar.expert/explorer/testnet/contract/CC6YDSEJRF7QH5JL7MVEYEIU3CTMNEHS4XIK5R36DYA5EVUYIP4PAHPG) | [`CDCIDX5FXOENXW4ODR2D7QMRKL4F2NTZYFVZEFF63GTNRVVDXLCQ7EEC`](https://stellar.expert/explorer/testnet/contract/CDCIDX5FXOENXW4ODR2D7QMRKL4F2NTZYFVZEFF63GTNRVVDXLCQ7EEC) | Announced, not deployed: `xlm-defindex-blend`. ### Assets and external contracts | | asset / contract | issuer | SAC | |---|---|---|---| | LBOND (simulated bond, AUTH_REQUIRED, clawback) | [`LBOND`](https://stellar.expert/explorer/testnet/asset/LBOND-GCMNI332OEZL2AVBKJVDZ2IPREWMEYRENGFFVEGXS4JVXUWJEIAT5EQF) | [`GCMNI332OEZL2AVBKJVDZ2IPREWMEYRENGFFVEGXS4JVXUWJEIAT5EQF`](https://stellar.expert/explorer/testnet/account/GCMNI332OEZL2AVBKJVDZ2IPREWMEYRENGFFVEGXS4JVXUWJEIAT5EQF) | [`CAVDLKQ2T4XBIQNY2WBUZKWQM6YDQ6NVX2N3HQ3P5Z2SBQ3VNZCBVBKE`](https://stellar.expert/explorer/testnet/contract/CAVDLKQ2T4XBIQNY2WBUZKWQM6YDQ6NVX2N3HQ3P5Z2SBQ3VNZCBVBKE) | | USDC (Blend testnet) | [`USDC`](https://stellar.expert/explorer/testnet/asset/USDC-GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56) | [`GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56`](https://stellar.expert/explorer/testnet/account/GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56) | [`CAQCFVLOBK5GIULPNZRGATJJMIZL5BSP7X5YJVMGCPTUEPFM4AVSRCJU`](https://stellar.expert/explorer/testnet/contract/CAQCFVLOBK5GIULPNZRGATJJMIZL5BSP7X5YJVMGCPTUEPFM4AVSRCJU) | | lUSDCb (active receipt) | [`lUSDCb`](https://stellar.expert/explorer/testnet/asset/lUSDCb-GC7QBZD2LMPZZ3BT4ZLKPYUR23GJKT47BLYJKMXUY523M7HMUGT64TVO) | [`GC7QBZD2LMPZZ3BT4ZLKPYUR23GJKT47BLYJKMXUY523M7HMUGT64TVO`](https://stellar.expert/explorer/testnet/account/GC7QBZD2LMPZZ3BT4ZLKPYUR23GJKT47BLYJKMXUY523M7HMUGT64TVO) | [`CC6YDSEJRF7QH5JL7MVEYEIU3CTMNEHS4XIK5R36DYA5EVUYIP4PAHPG`](https://stellar.expert/explorer/testnet/contract/CC6YDSEJRF7QH5JL7MVEYEIU3CTMNEHS4XIK5R36DYA5EVUYIP4PAHPG) | | DeFindex vault (active) | [`CDCIDX5FXOENXW4ODR2D7QMRKL4F2NTZYFVZEFF63GTNRVVDXLCQ7EEC`](https://stellar.expert/explorer/testnet/contract/CDCIDX5FXOENXW4ODR2D7QMRKL4F2NTZYFVZEFF63GTNRVVDXLCQ7EEC) | | | | Blend pool | [`CCEBVDYM32YNYCVNRXQKDFFPISJJCV557CDZEIRBEE4NCV4KHPQ44HGF`](https://stellar.expert/explorer/testnet/contract/CCEBVDYM32YNYCVNRXQKDFFPISJJCV557CDZEIRBEE4NCV4KHPQ44HGF) | | | Machine-readable: `GET /api/config` returns the same values as JSON. ## lotus_pool (ABI v1) ### Types ```rust enum Side { Ask, Bid } // Ask: sells BASE as price rises. Bid: buys BASE as price falls. enum Mode { Directional, TwoWay } // TwoWay: pools without a vault only struct Config { admin, base, quote, vault: Option
, bin_step_bps: u32, fee_bps: u32, max_bins_per_swap: u32, supports_two_way: bool } struct BinView { side: Side, bin: i32, price: i128, inventory: i128, total_shares: i128, filled: i128 } struct Position { id: u64, owner, side, mode, lo_bin: i32, hi_bin: i32, deposited: i128, inventory: i128, filled: i128, pending_proceeds: i128, pending_fees: i128, vaulted: bool } struct PositionPayout { base: i128, quote: i128 } struct SwapQuote { amount_out: i128, fee: i128, avg_price: i128, bins_crossed: u32, partial: bool } struct Tvl { base: i128, quote_value: i128, vault_shares: i128 } ``` Encoding: `Side` and `Mode` are unit-variant enums, on the wire `ScVal::Vec([Symbol("Ask")])` (stellar CLI: `--side Ask`; spec-based stellar-sdk clients: `{ tag: "Ask", values: undefined }`). Structs are `ScVal::Map` keyed by field name. Field notes: for Ask, `inventory` / `deposited` / `filled` are in BASE, `pending_proceeds` and `pending_fees` in QUOTE. For Bid, `inventory` / `deposited` / `filled` are in QUOTE, `pending_proceeds` is BASE bought, `pending_fees` QUOTE. `SwapQuote.avg_price` includes the fee. A removed position disappears: `get_position(id)` then fails with `NoSuchPosition`. ### Functions ```rust __constructor(admin, base, quote, vault: Option, bin_step_bps: u32, fee_bps: u32) // LP add_position(owner, side: Side, mode: Mode, lo_bin: i32, hi_bin: i32, amount: i128, weights: Vec