Vaults and positions
A vault is one shared position. Every depositor sits in the same eMode category at the same target loan-to-value, which is what lets the vault hand out a simple share token. A position gives that up in exchange for control.
Under the hood, each position is a clone created by the
LeveragePositionFactory on the Sonic hub, with its own account in the SODAX money market. The leverage itself comes from an intent: the position borrows, and a solver on SODAX trades the borrowed asset into more collateral. You set the floor on what that trade must return, so a bad fill cannot go through.
Both products live on sodax.leverageYield, and new Sodax() already knows the factory address. No extra configuration is needed.
1. Size the leverage from a quote, not from oracle prices
This is the one step not to shortcut. A position’s leverage is bought through a solver, and the two legs do not trade at exactly their oracle ratio. If you size the borrow from oracle prices alone, the position can land above the pool’s maximum LTV. The intent is accepted, then the fill is rejected. The SDK ships two helpers that do this properly:sizeLeverageBorrow for the first estimate and projectLeverageLeg for the real numbers once you have a quote.
exceedsMaxLtvis a hard gate. If it is true, do not post the intent.usableMaxLeverageis the real ceiling at this price. It is slightly below the textbook1 / (1 - ltv), because the trade costs something. Use it to cap your leverage slider.exposureLeverageis what the open position will report, which is a little above the leverage the user asked for. Show this number, not the input.minCollateralOutis the floor to post with the intent. Everything in the projection is computed at that floor, so if the floor is safe, every possible fill is.
feeBps and the projection understates LTV whenever a partner fee is configured, so a position near the limit can pass exceedsMaxLtv and still fail at fill. If you pass a partnerFee override to the open call, pass the same override to getEffectivePositionFee.
The collateral and borrow reserves, with their prices and risk parameters, come from the money market data you already read for lending (collateralReserve and borrowReserve above). If the user picks an eMode category, use that category’s LTV and liquidation threshold instead of the reserve’s base values.
2. Open the position
openLeveragePosition funds the position, creates it and posts the leverage intent in one call, then reports the intent to solvers so it gets filled. The deposit needs one token approval first, and the SDK knows which spender that network uses:
- Resolving means the intent is live, not that the leverage has arrived. The solver fills it right after. Track it with the pending state in the next section.
side: 'debt'opens from the borrow asset instead. A user holding only the debt token (a stablecoin, for example) can end up in a leveraged collateral position without ever buying the collateral. PasscollateralandtotalInputinstead ofborrowTokenandborrowAmount, and size it withside: 'debt'in the request.
3. Track it
Positions are owned by the user’s hub wallet, andlistPositionsForUser resolves that from the address the user connected with.
getPositionAccountis the live snapshot: collateral, debt, maximum LTV and health factor. Itsltvis the most the account may borrow against, so compute the position’s current LTV fromtotalDebtBase / totalCollateralBase. A health factor below 1 means the position can be liquidated, so this is the number to warn users about.getPositionPendingStatetells you whether an operation is in flight (isLive) or finished and waiting to be cleaned up (needsSettle). A position accepts one operation at a time.getPositionCollateralBalancegives the exact collateral amount. Use it, not the USD figures, whenever an amount goes into a transaction such as a full close.
4. Adjust and close
Every change to a position runs as the owner’s hub wallet. You build the call, then hand it to one of two methods depending on whether it posts an intent:
The split is enforced by the compiler: the builders return branded types, and each method only accepts its own kind. Sending a leverage change down the path that does not notify solvers is a type error, not a silent expiry.
runLeveragePositionOperation:
- Into the collateral. Decrease leverage by enough collateral to cover the debt plus a small margin, since interest keeps accruing until the fill and any dust debt left behind blocks a full withdrawal. Wait for the fill, check that
totalDebtBaseis zero, then withdraw the rest to any address. - Into the debt token. Decrease leverage with the collateral balance in one operation, net of the position’s fee: read
feeBpsfromgetPositionInfoand sellbalance * 10_000 / (10_000 + feeBps), because the fee is given up on top of the input and the whole balance cannot settle when it is nonzero. The debt is repaid and the remaining equity, now in the debt token, is swept to the owner bybuildSettlePosition.
In React
@sodax/dapp-kit wraps every call above in a hook, and its write hooks refresh the position reads after each action.
useLeveragePositionPending, useSubmitLeveragePositionIntent and useRunLeveragePositionOperation.
Funding from other networks
Positions live on the Sonic hub, but the user does not have to. SetsrcChainKey to another supported network and the same calls deposit from there, create the position and post the intent in one relayed message. A refund for an intent that never fills goes back to the network and address the user funded from.
Opening and operating positions from a network other than Sonic is marked experimental in SDK 2.2.0. It is fully exercised on Sonic. Verify a non-Sonic origin against your own deployment before putting user funds through it. Bitcoin is not supported as a funding source for positions yet, and the SDK refuses it with a validation error.
Where to go next
- Leverage positions reference: every method, the fee rules and the sizing details.
- Integrate leverage yield: the vault side, if a pooled share token suits your product better.
- Demo source: a complete create, adjust and close UI built on the hooks above.
- SODAX skills: give your AI coding agent the leverage-yield guidance, including the sizing rules.