Perp Contract
このコンテンツはまだ日本語訳がありません。
- Events are not covered in this guide.
- Borrowing logic is described thoroughly here in the Perp: Borrowing Module specification.
- Fees logic is described thoroughly in ./fees/README.md.
- Price impact logic is described thoroughly in Perp: Price Impact Module.
- After-hours leverage controls are described in Perp: After-Hours Leverage.
Table of Contents
Section titled “Table of Contents”- Developer Documentation: Perpetual Futures Contract
Overview
Section titled “Overview”This contract implements perpetual futures trading features in CosmWasm. It allows:
- Opening and closing of leveraged positions (long/short).
- Limit and stop orders for trade entry.
- Dynamic stop-loss (SL) and take-profit (TP) updates.
- Partial position modifications (increase or decrease collateral/leverage).
- Scheduled-market after-hours leverage controls for live positions carried through a market close.
- Automatic borrowing fee accrual (see Borrowing Reference).
- Dynamic fee calculations (see Fees Reference).
- Price impact adjustments based on open interest (see Price Impact Reference).
Repository Layout
Section titled “Repository Layout”Key files and folders relevant to this contract:
./contract.rs- High-level instantiation, migration, and execution entry points.
- Handles top-level dispatch for
ExecuteMsg::Admin { .. }.
./msgs.rs- Defines public
ExecuteMsgmessages for external users. - Defines admin messages (
AdminExecuteMsg) for privileged ops.
- Defines public
./trade.rs,./update_position_size.rs,./exec_update_leverage.rs- Main trade management logic: open/close trades, partial close, update SL/TP, leverage updates, and after-hours risk normalization.
./borrowing/- Reference here.
- Borrowing data structures, open-interest tracking, and fee accrual.
./fees/- Reference here.
- Fee calculations, tier logic, distribution of fees to vaults.
./price_impact/- Reference here.
- Logic to handle large trades moving the market price (slippage).
./trading/state.rs,./trading/utils.rs- Core state definitions for trades (like
Trade,TradeInfo,TradingActivated). - Helper methods for trade validation, order type checks, slippage logic, and exposure-limiting.
- Core state definitions for trades (like
You will see references to modules such as:
borrowing,fees,price_impact,pairs,trading- each in its own folder.keys.rs- containing typed indexes (e.g.,MarketIndex,TokenIndex, etc.).entry.rs- collects logic for certain “entry-level” operations like opening/closing trades.
Key Concepts
Section titled “Key Concepts”Trade Lifecycle
Section titled “Trade Lifecycle”- Open
- Create a
Tradestruct with details on leverage, collateral, direction (long/short). - Fees are charged on open.
- Create a
- Position Live
- Accrues borrowing fees over time (borrowed from
borrowingmodule). - Market can move: position PnL is conceptual, realized only on close.
- Accrues borrowing fees over time (borrowed from
- Close
- Reverse the open interest effect, finalize fees, distribute collateral to user or vault if loss.
- Stop/Limit/TP/SL
- The contract allows storing limit orders or setting stop-loss/take-profit boundaries.
- Typically triggered by an off-chain or keeper system calling
TriggerTrade.
Contract Entry Points
Section titled “Contract Entry Points”instantiate
Initializes ownership, oracle references, default settings forOI_WINDOWS_SETTINGS.execute
Dispatches user calls toExecuteMsg. Distinguishes between normal user ops vs. admin messages.migrate
For contract upgrade logic.
Index Types
Section titled “Index Types”./keys.rs defines typed indexes used throughout storage:
MarketIndex(u16): Unique ID for a trading market/pair.GroupIndex(u16): Group of markets for borrowing fee grouping.TokenIndex(u16): Represents a collateral token.UserTradeIndex(u64): Uniquely identifies a trade for a given user.TradeInfoIndex(u64): Additional info index for the same trade (like creation block, slippage settings, etc.).
These typed indexes help ensure type safety and consistent 2-byte or 8-byte key usage in storage.
Inter-Contract Interactions
Section titled “Inter-Contract Interactions”Key interactions are:
- Oracle (
oracle_address)- Queried for
GetExchangeRateto determine the price of base vs. quote assets. - Also used for collateral price in USD.
- Queried for
- Vault (
VAULT_ADDRESSES)- Receives or sends collateral during partial close, liquidation, or exit.
- Manages user margin deposits (collateral).
No direct “execute calls” are done to other modules like borrowing/fees; these modules are integrated inside this contract’s logic. However, certain distributions are done via BankMsg::Send or calling the vault’s ExecuteMsg::ReceiveAssets.
Messages (ExecuteMsg and AdminExecuteMsg)
Section titled “Messages (ExecuteMsg and AdminExecuteMsg)”User commands are in ./msgs.rs. Notable fields (you can see the file for all arguments):
OpenTrade { market_index: MarketIndex, leverage: Decimal, long: bool, ... }
Opens a brand new position with specific parameters.CloseTrade { trade_index: UserTradeIndex }
Closes a currently open trade at market price.UpdateOpenLimitOrder { trade_index, price, tp, sl, slippage_p }
Edits the price or SL/TP for a limit order that hasn’t become a live position yet.TriggerTrade { trader: String, trade_index: UserTradeIndex, order_type: PendingOrderType }
Activates a limit/stop/TP/SL/liq order if conditions are met. The contract can also route this into after-hours leverage normalization for eligible carried positions.UpdateLeverage { trade_index, new_leverage }
Adjusts leverage on an existing position (increasing or decreasing collateral).IncreasePositionSize/DecreasePositionSize
Allows partial modifications in position size or adding/removing collateral.
Admin operations (AdminExecuteMsg) revolve around:
- Setting markets (
SetMarkets) - Updating Oracle or Vault addresses
- Configuring fees or borrowing groups
- Configuring after-hours leverage controls through
UpdateAfterHours - Withdrawing protocol funds
- Pausing/trading activation toggles
These admin messages reference logic from:
Trade Flow in Detail
Section titled “Trade Flow in Detail”Open a Trade
Section titled “Open a Trade”-
User calls
ExecuteMsg::OpenTradewith parameters like:OpenTrade {market_index: MarketIndex(0),leverage: Decimal::from_str("5.0")?,long: true,collateral_index: TokenIndex(1),trade_type: TradeType::Trade,open_price: Decimal::from_str("1000")?,tp: Some(...),sl: Some(...),slippage_p: Decimal::from_str("0.03")?,} -
Funds must be included in the message for the specified
collateral_index. -
The contract:
- Fetches the user’s deposit from
info.funds. - Validates leverage, min collateral, exposure limits, slippage, etc.
- Charges open fees (see Fees module).
- Applies borrowing logic to keep track of open interest (see Borrowing module).
- Stores the new trade in
TRADES[(User, UserTradeIndex)].
- Fetches the user’s deposit from
Close a Trade
Section titled “Close a Trade”- User calls
CloseTrade { trade_index }to close an open position. - The contract:
- Updates the position’s final fees (borrowing + close fees).
- Returns leftover collateral or collects more from user if losing more than stored.
- Removes open interest from Borrowing storage.
- Deletes or marks the trade as closed in
TRADES.
Modify a Trade (Stop/Limit/SL/TP/Leverage)
Section titled “Modify a Trade (Stop/Limit/SL/TP/Leverage)”Several helper messages exist to alter the trade during its lifetime:
TriggerTrade { order_type: PendingOrderType }
Usually invoked by keepers. This makes a limit/stop order active, triggers SL/TP or liquidation closure, or normalizes after-hours leverage when the contract determines that risk action is needed.UpdateOpenLimitOrder
Edits a not-yet-triggered limit or stop order’s parameters (price, SL, TP, etc.).UpdateTp/UpdateSl
Adjust the take-profit or stop-loss boundaries for an already open “live” trade.UpdateLeverage { new_leverage }
Increases or decreases the position’s leverage.
If you reduce leverage, you must send additional collateral.
If you increase leverage, the system returns collateral to you.
Under the hood, these modifications recalculate fees, re-check liquidation price, update Borrowing open interest if necessary, and more.
For scheduled markets with after-hours controls, leverage updates, SL/TP updates, and position-size increases first materialize any required after-hours normalization. See Perp: After-Hours Leverage.
Additional Modules
Section titled “Additional Modules”Below are references to the specialized submodules for advanced logic:
Borrowing Reference
Section titled “Borrowing Reference”See ./borrowing/README.md for how:
- Borrowing fees accumulate over time.
- The system enforces maximum open interest (OI) constraints on a Group or Pair basis.
- Each trade references a BorrowingPairGroup for historical group changes.
Fees Reference
Section titled “Fees Reference”See ./fees/README.md for how:
- Fees are computed on open, close, partial close, trigger orders, and liquidation.
- Fees are distributed among governance, trigger reward, and vault.
- Fee tiers reduce fees for high-volume traders.
Price Impact Reference
Section titled “Price Impact Reference”See ./price_impact/README.md for how:
PAIR_DEPTHSsets the “1% market depth” for each pair (above/below).- Large trades face an execution price penalty or improvement.
- Time-windowed open interest approach is used to smooth out short-term spikes.
Further Notes
Section titled “Further Notes”- Contract Ownership:
Updated via nibiru-ownable’sUpdateOwnershipadmin message. - Validation:
Full validations across multiple modules ensure no negative exposure or insufficient collateral. - Extensibility:
Additional messages or fee logic can be integrated by referencing the same approach for typed storage, slippage checks, and Borrowing/Fees hooks.
That covers the core perpetual futures logic in this repository. For further details on borrowing, fees, or price impact calculations, please reference their dedicated READMEs in ./borrowing, ./fees, and ./price_impact.