Skip to main content
Use this guide to let your users deposit into and withdraw from SODAX leverage-yield vaults. It covers the order of the steps and the rules that matter. Signatures, types and working code live in the references and source it links to, and those are what to copy from.

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.
Read vaults at runtime rather than hard-coding them. sodax.leverageYield.listVaults() returns the registry bundled with your SDK version, and GET /vaults returns the live list.

Risks

Leverage multiplies the spread in both directions. Show these risks to users before they deposit.
  • 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 up Sodax and a wallet provider as in Configure the SDK and Wallet providers. Then follow the same sequence in both directions:
  1. 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.
  2. Apply your slippage to the quoted amount to get minOutputAmount.
  3. Build the payload with deposit() or withdraw(). These only build it and never broadcast.
  4. Approve, on a deposit only. Use the swap-domain sodax.swaps.isAllowanceValid and sodax.swaps.approve on the payload’s params. A withdraw needs no approval.
  5. Execute with vaultSwap({ ...built, walletProvider }). It signs, broadcasts and drives the intent to completion.
  6. Track it with getDetailedStatus({ srcChainKey, srcTxHash }), using the source transaction hash from the vaultSwap result.
The complete deposit and withdraw examples, including the approval call’s type parameters, are in Flows. Copy from there. Quoting and Partner fee cover fee precedence and how to keep the quote and the intent consistent. 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 under https://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

  1. Building is not executing. deposit() and withdraw() return a payload. Nothing happens on-chain until vaultSwap() runs, or until you broadcast and call /submit-tx.
  2. 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 the minOutputAmount it gives can exceed what the vault intent delivers, and the intent never fills.
  3. Keep the partner fee consistent, and quote the gross amount. Pass the same partnerFee to the quote and the builder, or leave it out of both. The quote deducts the fee itself, so don’t net the amount first.
  4. swaps.partnerFee never applies to vaults. Configure leverageYield.partnerFee, or the global fee. A withdraw fee is taken in lsoda* shares.
  5. Only deposits need approval, and it’s the swap-domain one. sodax.leverageYield.approve and isAllowanceValid are for calling the vault directly on Sonic, and neither flow uses them. When /approve returns a resetTx, mine it before tx. useLeverageYieldApiApproveAndBroadcast handles that order for you.
  6. Withdraw from the address that deposited. The hub wallet is derived from the network and address the user deposited from. getShareBalanceForUser takes that spoke address. getShareBalance and /share-balance take the hub wallet address, which sodax.hubProvider.getUserHubWalletAddress resolves.
  7. Size a withdraw in shares. inputAmount is lsoda* shares, so read it from the share balance. getMaxWithdraw* and /max-withdraw return the ERC-4626 maxWithdraw, which is in the underlying asset’s units.
  8. The headline APR is the effective APR. Use getEffectiveApr or /apr/effective. getApr counts lending rates only and leaves out the staking yield. The units of each APR field are listed in Types.
  9. Know the submit-tx body. relayData takes the create response’s relayData.payload string, and operation is required. Wait for the source-network receipt before you submit. Terminal success is solved.
  10. Track by the source transaction. Use getDetailedStatus / useLeverageYieldDetailedStatus rather than the backend record alone, because the client-side fallback can finish a swap the backend record still shows as open.
  11. Branch on result.ok, and discriminate on error.code. Methods that return a Result never throw, and error messages aren’t stable. A quote error can be the solver’s own response. Error Handling lists the codes and guards.
  12. Keep API keys on the server. A key in a browser bundle is public. See API key good practices.
  13. 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:

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.