Skip to main content

Trading Contract

The trading contract is the core perpetual futures engine. It manages position lifecycle, PnL settlement, fee distribution, funding rate accrual, liquidation, and auto-deleveraging.

Public Interface

User Actions

All user actions require authentication from the position owner.

FunctionStatus RequiredDescription
place_limitActivePlace a limit order (pending fill)
open_marketActiveOpen a position at market price
close_positionNot FrozenClose a filled position
cancel_positionNot FrozenCancel a pending limit order, or refund a filled position on a deleted market
modify_collateralNot FrozenAdd or remove collateral
set_triggersNot FrozenSet stop-loss and take-profit prices

Keeper Actions

All keeper actions are permissionless. Any address can call them and earn fees.

FunctionDescription
executeBatch process: fills, SL/TP triggers, liquidations
apply_fundingUpdate funding rates (hourly)
update_statusCircuit breaker / ADL (requires threshold conditions)

Admin Actions

All admin actions require the contract owner (#[only_owner]).

FunctionDescription
set_configUpdate global trading configuration
set_marketAdd or update a market
del_marketRemove a market (existing positions can be refunded via cancel_position)
set_statusSet contract status (cannot set OnIce, use update_status instead)
upgradeUpgrade contract WASM
transfer_ownershipTransfer admin rights (OZ Ownable)

Read-Only

FunctionDescription
get_configCurrent TradingConfig
get_market_configMarketConfig for a market ID
get_market_dataMarketData for a market ID
get_marketsAll registered market IDs
get_positionPosition by ID
get_user_positionsAll position IDs for an address
get_statusCurrent contract status
get_treasuryTreasury contract address
get_vaultVault contract address
get_price_verifierPrice verifier contract address
get_tokenCollateral token address

Data Structures

TradingConfig

Global fee, rate, and limit parameters set by the admin.

FieldTypeDescription
caller_ratei128 (SCALAR_7)Keeper's share of trading fees (0 to 50%)
min_notionali128 (token decimals)Minimum notional size per position
max_notionali128 (token decimals)Maximum notional size per position
fee_domi128 (SCALAR_7)Trading fee rate for the dominant side (heavier open interest)
fee_non_domi128 (SCALAR_7)Trading fee rate for the minority side
max_utili128 (SCALAR_7)Global utilization cap: total_notional / vault_balance
r_fundingi128 (SCALAR_18)Base hourly funding rate (all markets)
r_basei128 (SCALAR_18)Base hourly borrowing rate (all markets)
r_vari128 (SCALAR_18)Vault-level variable borrowing rate at full vault utilization

caller_rate in [0, MAX_CALLER_RATE] (50%). fee_dom >= fee_non_dom >= 0, both <= MAX_FEE_RATE (1%). r_base, r_funding in [0, MAX_RATE_HOURLY]. r_var in [0, MAX_R_VAR]. min_notional > 0, max_notional > min_notional, max_util > 0.

MarketConfig

Per-market parameters set by the admin via set_market.

FieldTypeDescription
feed_idu32Price feed identifier (immutable after market creation)
enabledboolWhether this market accepts new positions
max_utili128 (SCALAR_7)Per-market utilization cap
r_var_marketi128 (SCALAR_18)Per-market variable borrowing rate at full market utilization
margini128 (SCALAR_7)Initial margin ratio. Max leverage = 1 / margin
liq_feei128 (SCALAR_7)Liquidation fee/threshold. Position liquidatable when equity < notional * liq_fee
impacti128 (SCALAR_7)Price impact fee divisor: fee = notional / impact

margin > liq_fee > 0. margin <= MAX_MARGIN (50%). liq_fee <= MAX_LIQ_FEE (25%). r_var_market in [0, MAX_R_VAR_MARKET]. impact >= MIN_IMPACT (10x). max_util > 0.

MarketData

Per-market mutable state, updated on every position action.

FieldTypeDescription
l_notionali128Sum of all long notional sizes (token decimals)
s_notionali128Sum of all short notional sizes (token decimals)
l_fund_idxi128 (SCALAR_18)Cumulative long funding index
s_fund_idxi128 (SCALAR_18)Cumulative short funding index
l_borr_idxi128 (SCALAR_18)Cumulative long borrowing index
s_borr_idxi128 (SCALAR_18)Cumulative short borrowing index
l_entry_wti128sum(notional_i / entry_price_i) for longs
s_entry_wti128sum(notional_i / entry_price_i) for shorts
fund_ratei128 (SCALAR_18)Current signed funding rate (positive = longs pay)
last_updateu64Timestamp of last accrual (seconds)
l_adl_idxi128 (SCALAR_18)Long ADL reduction factor (starts at SCALAR_18)
s_adl_idxi128 (SCALAR_18)Short ADL reduction factor (starts at SCALAR_18)

The entry_wt fields enable aggregate PnL computation without iterating all positions. They are used by the circuit breaker and ADL system. The borr_idx fields track cumulative borrowing costs per unit of notional, accrued alongside funding.

Position

FieldTypeDescription
userAddressPosition owner
filledboolfalse = pending limit order, true = active position
market_idu32Market identifier (maps to MarketConfig with feed_id)
longboolDirection
sli128Stop-loss trigger price (0 = disabled)
tpi128Take-profit trigger price (0 = disabled)
entry_pricei128Fill price (price decimals)
coli128Current collateral (token decimals)
notionali128Notional value, may be reduced by ADL (token decimals)
fund_idxi128 (SCALAR_18)Funding index snapshot at fill
borr_idxi128 (SCALAR_18)Borrowing index snapshot at fill
adl_idxi128 (SCALAR_18)ADL index snapshot at fill (starts at SCALAR_18)
created_atu64Timestamp of creation or fill (seconds)

Contract Status System

Active (0)      : Normal operation, all actions allowed
OnIce (1) : Permissionless circuit breaker; no new positions
AdminOnIce (2) : Admin-set pause; same restrictions as OnIce
Frozen (3) : Full freeze; all operations blocked
StatusOpen positionManage positionKeeper executeApply funding
ActiveYesYesYesYes
OnIceNoYesYesYes
AdminOnIceNoYesYesYes
FrozenNoNoNoNo

Admin can set Active, AdminOnIce, or Frozen directly. OnIce can only be set by the permissionless update_status function when utilization thresholds are met.

Constants

ConstantValueDescription
SCALAR_710,000,0007-decimal fixed-point base (rates, fees, ratios)
SCALAR_1810^1818-decimal fixed-point base (funding, borrowing, ADL indices)
MAX_ENTRIES50Maximum markets or positions per user
UTIL_ONICE9,500,00095%. Triggers OnIce when net PnL >= 95% of vault
UTIL_ACTIVE9,000,00090%. Restores Active when PnL drops below 90%
ONE_HOUR_SECONDS3600Funding/borrowing update minimum interval
MIN_OPEN_TIME30Minimum seconds before user-initiated close
MAX_CALLER_RATE5,000,00050% max keeper fee share
MAX_FEE_RATE100,0001% max base fee rate
MAX_RATE_HOURLY100,000,000,000,0000.01%/hr max for r_base, r_funding (~88% APR)
MAX_R_VAR100,000,000,000,0000.01%/hr max vault variable rate
MAX_R_VAR_MARKET100,000,000,000,0000.01%/hr max per-market variable rate
MAX_UTIL100,000,0001000% max utilization cap (10x SCALAR_7)
MIN_IMPACT100,000,000Impact divisor floor (caps impact fee at 10%)
MAX_MARGIN5,000,00050% max initial margin (2x min leverage)
MAX_LIQ_FEE2,500,00025% max liquidation fee/threshold