SV3 logo

Perps leverage

Pure collateral-first leverage bounds and quotes for physical longs and offset shorts.

These helpers contain the reusable product math behind a USDC input and leverage control. All amounts are bigint values. They do not format strings, access a wallet, or call RPC.

Import

import {
  getLongLeverageBounds,
  getPerpLeverageBounds,
  getShortLeverageBounds,
  quoteLongByLeverage,
  quotePerpByLeverage,
  quoteShortByLeverage,
} from "@repo/contract-client/math";

Long bounds and quote

const account = await sv3.market.getAccountContext(market, owner);
const contribution = parseUsdc("100");
const bounds = getLongLeverageBounds(account, contribution);

const quote = quoteLongByLeverage(account, {
  userContributionRaw: contribution,
  leverageBps: 20_000n,
});

getLongLeverageBounds searches the complete 1×–3.3× product range against the actual expansion quote. It includes the post-buy collateral capacity, liquid reserve, market/protocol debt headroom, and market/protocol gross-backing headroom.

LongLeverageQuote includes:

FieldMeaning
userContributionRawUSDC supplied by the user
positionSizeRawUser USDC plus net debt used for the curve purchase
avmAcquiredPhysical AVM minted and pledged
grossDebtIncreaseRawDebt recorded by FloorMarket
netDebtProceedsRawDebt contribution after the 3% origination fee
tradeFees / borrowFeesSeparate fee breakdowns
averageEntryPriceWadFee-inclusive average entry for this increase
grossBackingIncreaseRawNet increase checked against Directory caps
floorEquityRawFloor value of the resulting collateral minus resulting debt
priceImpact / provenanceCurve impact and pinned-state identity

Short bounds and quote

const perp = await sv3.perp.getContext(market);
const margin = parseUsdc("100");
const bounds = getShortLeverageBounds(perp, margin);

const quote = quoteShortByLeverage(perp, {
  marginRaw: margin,
  leverageBps: 20_000n,
});

PerpMarketContext is required because a safe short quote needs more than the FloorMarket curve snapshot. It includes live fee and margin policies, active and surrendered offset, per-position and aggregate caps, market/protocol escrow totals, and Directory backing headroom.

ShortLeverageQuote includes:

FieldMeaning
marginRawIsolated USDC margin
positionSizeRawConservative premium restoration exposure
sizeAvmExact offset size sent to the contract
releasedPremiumRawPosition escrow released from FloorMarket
openFeeRaw0.125% fee on released premium
totalWalletDebitRawMargin plus open fee
entryPremiumWadReleased premium per AVM
initialMarginRequiredRawIMR requirement at entry
maintenanceMarginRequiredRawMMR requirement at entry
liquidationBufferRawBuffer included in health
equityRaw / flaggableEntry health under current policies

Generic helpers

Use getPerpLeverageBounds and quotePerpByLeverage when the side is selected at runtime. Their input and result are discriminated by side.

Constraint codes

bounds.limitingConstraint is one of:

product-cap
floor-capacity
liquid-reserve
debt-cap
gross-backing-cap
position-size-cap
market-offset-cap
market-share-cap
market-escrow-cap
protocol-escrow-cap
minimum-curve-supply

Do not infer a limit from an error string. Display the returned maximum and map this stable code into consumer-specific copy. If a quote requests more than that maximum, the SDK throws LeverageLimitError with the same side, maxLeverageBps, and limitingConstraint fields.

Legacy exact-size helpers

quoteOpenShort and quoteOpenShortByLeverage(snapshot, ...) remain available for low-level calculations and compatibility. A MarketSnapshot alone cannot know aggregate perp escrow or offset headroom. New trading integrations should use quoteShortByLeverage(PerpMarketContext, ...).