跳转至主要内容

Custom Types

Boros heavily uses Solidity user-defined value types for gas optimization and type safety. These types use bit-packing to minimize storage costs and provide efficient operations on the EVM.

Core Trading Types​

Trade​

Definition: type Trade is uint256

Bit Packing: signedSize(128) | signedCost(128)

// Creating trades
Trade memory trade = TradeLib.from(signedSize, signedCost);

Side side = trade.side();
int128 size = trade.signedSize();
int128 cost = trade.signedCost();

Account Types​

Account​

Definition: type Account is bytes21

Bit Packing: address(160) | accountId(8)

// Creating accounts
Account mainAcc = AccountLib.from(userAddress, 0); // Main account
Account subAcc = AccountLib.from(userAddress, 1); // Sub-account 1
Account ammAcc = userAddress.toAMM(); // AMM account 255

// Parsing accounts
address root = account.root(); // Extract root address
uint8 accountId = account.accountId(); // Extract account ID

// Special account types
bool isMain = account.isMain(); // accountId == 0
bool isAMM = account.isAMM(); // accountId == 255

MarketAcc​

Definition: type MarketAcc is bytes26

Bit Packing: address(160) | accountId(8) | tokenId(16) | marketId(24)

// Creating market accounts
MarketAcc crossAcc = account.toCross(tokenId); // Cross-margin
MarketAcc isolatedAcc = account.toIsolated(tokenId, marketId); // Isolated

// Parsing market accounts
address root = crossAcc.root();
Account account = crossAcc.account();
TokenId tokenId = crossAcc.tokenId();
MarketId marketId = crossAcc.marketId();

// Cross vs isolated margin
bool isCross = isolatedAcc.isCross();
MarketAcc crossAcc = isolatedAcc.toCross();

Order Book Types​

OrderId​

Definition: type OrderId is uint64

Bit Packing: initialized(1) | reserved(6) | side(1) | encodedTick(16) | orderIndex(40)

// Creating order IDs (done internally by order book)
OrderId orderId = OrderIdLib.from(Side.LONG, tickIndex, orderIndex);

// Parsing order IDs
Side side = orderId.side();
int16 tick = orderId.tickIndex();
uint40 index = orderId.orderIndex();

// Priority comparison (lower unwrapped value = higher priority)
bool higherPriority = orderId1 < orderId2;

Side​

Definition: enum Side { LONG, SHORT }

Side opposite = side.opposite();          // LONG ↔ SHORT
bool topDown = side.sweepTickTopDown(); // LONG: true, SHORT: false
int16 endTick = side.endTick(); // Boundary tick values

TimeInForce​

Definition: enum TimeInForce { GTC, IOC, FOK, ALO, SOFT_ALO }

  • GTC (Good Till Cancel): Standard limit order that remains on the order book until fully filled or manually canceled. With placeSingleOrder, a GTC order can match against existing order book and AMM liquidity; any unfilled remainder stays on the book as a maker order. With bulkOrders, GTC orders are placed directly on the book without AMM matching.
  • IOC (Immediate or Cancel): Executes against available liquidity (order book + AMM) immediately, cancels any unfilled portion. Best for taker orders — guarantees no residual maker orders remain on the book.
  • FOK (Fill or Kill): Must fill entire order size immediately (from order book + AMM) or the transaction reverts. Use when partial fills are unacceptable.
  • ALO (Add Liquidity Only): Also known as Post-Only. Ensures the order is placed as a maker order only — the transaction reverts if it would immediately match against existing orders or the AMM. Ideal for market makers who want to guarantee maker status.
  • SOFT_ALO: Similar to ALO (Post-Only), but instead of reverting, it silently skips any portion that would match and places the rest on the book. Useful for market makers who prefer no-revert behavior.

OrderStatus​

Definition: enum OrderStatus { NOT_EXIST, OPEN, PENDING_SETTLE, PURGED }

  • NOT_EXIST: Order has never been placed or has been cancelled
  • OPEN: Active order in the order book, available for matching against incoming orders
  • PENDING_SETTLE: Order has been filled
  • PURGED: Order was purged because rate is out of bound

Market Types​

MarketStatus​

Definition: enum MarketStatus { PAUSED, CLO, GOOD, ALO }

  • PAUSED (0): Market is fully paused — no trading, no order placement, no cancellation
  • CLO (1): Close-Only mode — only orders that reduce existing position size are allowed. New position opening is prohibited. Activated when open interest approaches risk limits
  • GOOD (2): Normal operating mode — all trading operations are available
  • ALO (3): Post-only mode — orders can only be placed with the ALO or SOFT_ALO TimeInForce and nothing is matched. Orders can still be cancelled

Markets transition between states based on risk conditions (e.g., open interest approaching caps). Query the current status via getMarketConfig().

LiqSettings​

Definition: struct LiqSettings { uint64 base, uint64 slope, uint64 feeRate }

Parameters governing liquidation incentives:

  • base: Base incentive factor for liquidators
  • slope: Scaling factor that increases incentive as health ratio decreases
  • feeRate: Fee rate charged on liquidated positions (goes to protocol treasury)

See Margin — Liquidation Process for the incentive formula.

TokenId​

Definition: type TokenId is uint16

Unique identifier for collateral tokens supported by the protocol.

MarketId​

Definition: type MarketId is uint24

Special Value: The value type(uint24).max (16,777,215) is reserved as MarketIdLib.CROSS to indicate cross-margin mode, where collateral is shared across all markets within the same collateral zone.

// Cross-margin constant
MarketId crossMargin = MarketIdLib.CROSS; // type(uint24).max

// Regular market IDs for isolated margin
MarketId market1 = MarketId.wrap(1); // Isolated margin for market 1
MarketId market2 = MarketId.wrap(2); // Isolated margin for market 2

// Checking margin mode
bool isCross = marketId.isCross(); // true if marketId == CROSS

AMMId​

Definition: type AMMId is uint24

Advanced Types​

FIndex​

Definition: type FIndex is bytes26

Bit Packing: fTime(32) | floatingIndex(112) | feeIndex(64)

FIndex fIndex = FIndexLib.from(fTime, floatingIndex, feeIndex);

// Parsing components
uint32 fTime = fIndex.fTime(); // Funding time
int112 floatingIndex = fIndex.floatingIndex(); // Floating rate index
uint64 feeIndex = fIndex.feeIndex(); // Fee accumulator

// Comparison and checks
bool isZero = fIndex.isZero();
bool same = fIndex1 == fIndex2;

PayFee​

Definition: type PayFee is uint256

Bit Packing: payment(128) | fees(128)

Compact representation of a cash payment paired with its associated fees. Used throughout the settlement and liquidation system to bundle payment amounts with their fee components.

PayFee result = PayFeeLib.from(payment, fees);

(int128 payment, uint128 fees) = result.unpack();
int256 netAmount = result.total(); // payment - fees

VMResult​

Definition: type VMResult is uint256

Bit Packing: value(128) | margin(128)

Compact representation of a position's value paired with its margin requirement. Used by settleAllAndGet() to return position valuation and margin data in a single value.

VMResult result = VMResultLib.from(positionValue, marginRequired);

(int128 value, uint128 margin) = result.unpack();