What it is
A leverage-yield vault loops a liquid staking token (LST). It supplies the LST as collateral, borrows a correlated asset against it, and swaps the borrowed asset back into more LST. It repeats this until the position reaches the vault’s target loan-to-value. Users earn the spread between the supply side (lending rate plus staking yield) and the borrow rate, multiplied by the leverage. The loop and the multiplier are explained in How the leverage-yield vault works, and the APR formula in Effective APR. Three facts shape the integration:- A position is an ERC-4626 share token (
lsoda*) on the Sonic hub. The vault address is also the share-token address. - Deposit and withdraw are intent-based swaps. A deposit swaps any supported token into shares, and a withdraw swaps shares back into any token. A solver fills both, so there is no vault-specific call on the user’s network.
- Shares land in the user’s hub wallet, not on the network they paid from. A later withdraw spends them from there.
sodax.leverageYield.listVaults() returns the registry bundled with your SDK version, and GET /vaults returns the live list.
Risks
- APR can go negative. When the borrow rate rises above the supply side, every loop loses money. The SDK returns net APR as a signed value, so a UI can show that.
- Depeg and liquidation risk. The position carries real debt. If the LST depegs or moves against the borrowed asset, the health factor falls.
getPosition()returns the live health factor, LTV, collateral and debt so you can warn users early. - The APR is a steady-state estimate. It assumes today’s rates hold and the vault stays at its target LTV. Realised returns move with rates and with how often the vault rebalances.
Choose a path
SDK path (default)
Set upSodax and a wallet provider as in Configure the SDK and Wallet providers. Then follow the same sequence in both directions:
- Quote with
sodax.leverageYield.getQuote. The vault is the destination token on a deposit and the source token on a withdraw, and it is always on Sonic. - Apply your slippage to the quoted amount to get
minOutputAmount. - Build the payload with
deposit()orwithdraw(). These only build it and never broadcast. - Approve, on a deposit only. Use the swap-domain
sodax.swaps.isAllowanceValidandsodax.swaps.approveon the payload’sparams. A withdraw needs no approval. - Execute with
vaultSwap({ ...built, walletProvider }). It signs, broadcasts and drives the intent to completion. - Track it with
getDetailedStatus({ srcChainKey, srcTxHash }), using the source transaction hash from thevaultSwapresult.
vaultSwap() hands the broadcast transaction to the backend first and finishes the relay client-side if that doesn’t complete. Completion paths and timeout documents both paths and the timeout budget. getDetailedStatus is a one-off read, so poll it yourself or use the React hook. Its routing and error branches are documented under getDetailedStatus.
For plain @sodax/sdk without React, the Node leverage-yield script runs each step as a CLI subcommand, and the SDK leverage-yield knowledge file documents every sodax.leverageYield call shape.
dapp-kit hooks
Each SDK step has a matching@sodax/dapp-kit hook. Mutations expose mutateAsyncSafe, which returns a Result instead of throwing.
For parameters and polling behaviour, read each hook’s source; Leverage Yield Hooks links most of them. The dapp-kit leverage yield recipe has component-level deposit, withdraw and stats snippets. The demo’s leverage-yield page wires the full flow.
API path
Every route lives underhttps://api.sodax.com/v1/leverage-yield. Amounts are decimal strings in the token’s smallest unit, and networks are SODAX chain keys. The endpoint catalog lists each route.
Steps 6 and 7 are the same submit-tx machine as swaps, so follow the Swaps bot flow for the status lifecycle and failure handling. Send your API key from your server on every
POST, as described in API keys.
In TypeScript, sodax.api.leverageYield and the useLeverageYieldApi* hooks wrap these routes. The leverage-yield API knowledge file documents their call shapes. The demo app’s leverage-yield API page wires the API flow: its API card runs steps 1–6 end to end, and its order status panel runs step 7.
Gotchas
- Building is not executing.
deposit()andwithdraw()return a payload. Nothing happens on-chain untilvaultSwap()runs, or until you broadcast and call/submit-tx. - Quote with the leverage-yield quote. Use
sodax.leverageYield.getQuote,useLeverageYieldQuote, or/quote/deposit|withdraw, never the swap quote (sodax.swaps.getQuote,useQuote). The swap quote deducts the swap fee, so theminOutputAmountit gives can exceed what the vault intent delivers, and the intent never fills. - Keep the partner fee consistent, and quote the gross amount. Pass the same
partnerFeeto the quote and the builder, or leave it out of both. The quote deducts the fee itself, so don’t net the amount first. swaps.partnerFeenever applies to vaults. ConfigureleverageYield.partnerFee, or the globalfee. A withdraw fee is taken inlsoda*shares.- Only deposits need approval, and it’s the swap-domain one.
sodax.leverageYield.approveandisAllowanceValidare for calling the vault directly on Sonic, and neither flow uses them. When/approvereturns aresetTx, mine it beforetx.useLeverageYieldApiApproveAndBroadcasthandles that order for you. - Withdraw from the address that deposited. The hub wallet is derived from the network and address the user deposited from.
getShareBalanceForUsertakes that spoke address.getShareBalanceand/share-balancetake the hub wallet address, whichsodax.hubProvider.getUserHubWalletAddressresolves. - Size a withdraw in shares.
inputAmountislsoda*shares, so read it from the share balance.getMaxWithdraw*and/max-withdrawreturn the ERC-4626maxWithdraw, which is in the underlying asset’s units. - The headline APR is the effective APR. Use
getEffectiveApror/apr/effective.getAprcounts lending rates only and leaves out the staking yield. The units of each APR field are listed in Types. - Know the
submit-txbody.relayDatatakes the create response’srelayData.payloadstring, andoperationis required. Wait for the source-network receipt before you submit. Terminal success issolved. - Track by the source transaction. Use
getDetailedStatus/useLeverageYieldDetailedStatusrather than the backend record alone, because the client-side fallback can finish a swap the backend record still shows as open. - Branch on
result.ok, and discriminate onerror.code. Methods that return aResultnever throw, and error messages aren’t stable. A quote error can be the solver’s own response. Error Handling lists the codes and guards. - Keep API keys on the server. A key in a browser bundle is public. See API key good practices.
- A vault is not a leverage position. Leverage positions (
openLeveragePosition,useLeveragePosition*) share the service but are a separate product. See Leverage Positions.
Build it with an AI agent
Install the@sodax/skills bundle, and your agent loads the leverage-yield skills on its own. Add the Builders MCP for live vault data and quotes. Then describe the task plainly, for example “Add a deposit into a leverage-yield vault from Arbitrum with @sodax/dapp-kit”. Check what the agent produces against the Gotchas.
To point an agent at a skill directly, or to read one yourself:
Related
Leverage Yield (SDK)
Every
sodax.leverageYield method, error code and type.Effective APR
How the headline APR is derived, with a worked example.
Leverage yield API
Every
/v1/leverage-yield/* route.AI Integration Guide
Ship v2-correct SODAX code from your coding agent.