@somnia-chain/markets-sdk / index / PerpLeverage
Interface: PerpLeverage
Defined in: packages/sdk/src/perp/margin.ts:502
How levered an account is — measured at one position, and across the whole cross-margin account.
Every ratio is bps of 1x: 10_000 is 1.00x, 25_000 is 2.5x, 200_000 is
20x. That is the protocol's own unit for every margin figure, so these compose with
PerpRiskParams without a rescale.
Properties
asOfBlock
asOfBlock:
bigint
Defined in: packages/sdk/src/perp/margin.ts:504
The block every read was pinned to.
size
size:
bigint
Defined in: packages/sdk/src/perp/margin.ts:506
SIGNED position size in this market, raw base units (positive = long, 0 = flat).
markPrice
markPrice:
bigint
Defined in: packages/sdk/src/perp/margin.ts:508
Mark price the notionals were measured at, raw quote units per whole base.
positionNotional
positionNotional:
bigint
Defined in: packages/sdk/src/perp/margin.ts:510
This position's notional: |size| × mark / oneBase, raw collateral units.
accountNotional
accountNotional:
bigint
Defined in: packages/sdk/src/perp/margin.ts:520
Σ notional across EVERY market the account holds a position in, this one included, raw collateral units.
Costs two extra reads per OTHER active market — the MarginBank exposes no
aggregate notional view, and imReq cannot be inverted back into notional
because each market applies its own OI-scaled IMF. So this grows with the
account's footprint; a single-market account pays nothing extra.
equity
equity:
bigint
Defined in: packages/sdk/src/perp/margin.ts:522
Account equity = collateral + Σ unrealized PnL − Σ pending funding (signed).
positionLeverageBps
positionLeverageBps:
bigint|null
Defined in: packages/sdk/src/perp/margin.ts:532
This position's notional over account equity, bps — "this position is Nx my equity".
null when equity is ≤ 0, where the ratio has no meaning: an account with no
equity left is not running infinite leverage, it is insolvent, and rendering an
enormous number would say the wrong thing. Read MarginStatus for that
state instead.
accountLeverageBps
accountLeverageBps:
bigint|null
Defined in: packages/sdk/src/perp/margin.ts:541
Total notional over account equity, bps.
The figure that actually governs risk here. Margin is cross, so every
position draws on the same collateral: a second position at the same notional
doubles the account's leverage without changing the first one's
positionLeverageBps. null on non-positive equity, as above.
marketMaxLeverageBps
marketMaxLeverageBps:
bigint
Defined in: packages/sdk/src/perp/margin.ts:552
The most leverage THIS MARKET will open a position at, bps —
10000² / effectiveImfBps, using the OI-scaled IMF actually in force rather than
the static initialMarginBps.
A ceiling on new size, not a measurement of the position: it does not move when the position or the equity does. It DOES move when market-wide open interest does, which is why it is read per call rather than derived from PerpRiskParams.initialMarginBps.
accountMaxLeverageX
accountMaxLeverageX:
number
Defined in: packages/sdk/src/perp/margin.ts:563
The account's OWN per-market cap as an integer multiplier, 0 when unset — what
trader.setPerpLeverage writes, read back.
A cap STRICTER than the market's effective IMF adds margin on top of the base
requirement; that surcharge is quoted by
PerpOrderMarginPreview.leverageSurcharge. Being a setting rather than a
measurement, it can sit far above the position's actual
positionLeverageBps.
protocolMaxLeverageX
protocolMaxLeverageX:
number
Defined in: packages/sdk/src/perp/margin.ts:565
Protocol-wide ceiling that clamps the above, integer multiplier.
creditFloor
creditFloor:
bigint
Defined in: packages/sdk/src/perp/margin.ts:572
The account's non-withdrawable credit-voucher floor, raw collateral units. 0n for
an ordinary account, and the switch that arms the two fields below.
Self-clearing: the confinement lifts on its own once the floor reaches zero.
voucherLeverageCapX
voucherLeverageCapX:
number
Defined in: packages/sdk/src/perp/margin.ts:612
The protocol's voucher leverage cap, integer multiplier — what a voucher-holding
account is confined to when it INCREASES a position. 0 means unset, which is a
hard block rather than "no cap" (see voucherMarketAllowed).
Reported, not applied to protocolMaxLeverageX, because it does not bound the
position this call measures. MarginBank._meetsIM gates the whole voucher branch on
additionalSize > 0, so it never touches a reduce or a close — a voucher holder can
always close out, or place a stop, even on a market since removed from the
allowlist. Folding it into the protocol ceiling would report a constraint on a
reduce-only action that the chain does not apply.
What it bounds is a NEW increase, and the composition is not a plain minimum:
// voucher inactive (creditFloor == 0n)
// accountMaxLeverageX == 0 -> no leverage-derived requirement at all;
// marketMaxLeverageBps is what binds
// otherwise -> min(accountMaxLeverageX, protocolMaxLeverageX)
//
// voucher active and allowed
// the cap REPLACES an unset or looser account setting, then the
// protocol ceiling clamps the result:
const confined =
accountMaxLeverageX !== 0 && accountMaxLeverageX <= voucherLeverageCapX
? accountMaxLeverageX // a STRICTER user setting still wins
: voucherLeverageCapX;
const bindingX = Math.min(confined, protocolMaxLeverageX);
The load-bearing half is the first branch: a voucher turns an unset account cap
into an enforced one. On an ordinary account accountMaxLeverageX === 0 means "no
cap set"; on a voucher account increasing a position it means "confined to
voucherLeverageCapX".
For whether a specific order passes, use
SomniaMarketsClient.previewPerpOrderMargin — it applies all of this and
reports voucherBlocked alongside the margin numbers.
voucherMarketAllowed
voucherMarketAllowed:
boolean
Defined in: packages/sdk/src/perp/margin.ts:624
Whether THIS market is on the voucher allowlist.
Only consequential while creditFloor is positive, and then it is a hard
placement revert rather than an arithmetic clamp: an increase on a non-allowlisted
market reverts VoucherMarketNotAllowed, and an unset
voucherLeverageCapX reverts VoucherLeverageCapNotSet — a deliberate fail
safe, so an unconfigured cap never silently grants full leverage. Neither outcome is
expressible as a leverage number, which is the other reason these are reported
rather than folded in.