Ferrium Documentation
Permissionless on-chain programs for derivatives trading. Composable by anyone — frontends, protocols, agents. No whitelists, no API keys.
Quick Start
Place your first trade in under 5 minutes.
API Reference
Full SDK docs for every protocol component.
Protocol Deep Dive
Architecture, margin, liquidation, oracles.
Quick Start
Get up and running with the Ferrium SDK in minutes. This guide walks you through connecting a wallet, depositing margin, and placing your first trade.
Installation
npm install @ferrium/sdk
Or with yarn:
yarn add @ferrium/sdk
Connect & Authenticate
Ferrium is non-custodial. Authentication is wallet-based — no API keys, no accounts. Sign a message to prove ownership, and the SDK handles the rest.
import { FerriumClient } from "@ferrium/sdk" // Connect to Ferros mainnet const client = await FerriumClient.connect({ network: "mainnet", wallet: signer, // any ethers-compatible signer }) // That's it. No API key. No registration. console.log(client.address) // your wallet address
Your First Trade
Deposit margin and open a BTC perpetual position in four lines:
// 1. Deposit USDC as margin await client.margin.deposit("USDC", 10_000) // 2. Open a long BTC-PERP position at 5x leverage const order = await client.perps.marketOrder({ market: "BTC-PERP", side: "long", size: 0.5, // 0.5 BTC leverage: 5, }) console.log(order.fillPrice) // filled in <1ms via edge channel console.log(order.txHash) // settled on-chain in ~500ms
network: "testnet" with free testnet USDC. No real funds needed to experiment.
Client Setup
The FerriumClient is the entry point for all protocol interactions. It manages wallet connections, network state, and exposes sub-modules for each protocol component.
import { FerriumClient } from "@ferrium/sdk" const client = await FerriumClient.connect({ network: "mainnet", // "mainnet" | "testnet" | "devnet" wallet: signer, // ethers Signer or Wallet rpcUrl: "https://...", // optional custom RPC }) // Sub-modules client.margin // MarginVault operations client.perps // Perpetual futures client.options // Options engine (incl. 0DTE) client.events // Prediction / event markets client.delegate // Agent delegation & scoping
Configuration Options
| Parameter | Type | Description |
|---|---|---|
| network* | string | Target network. "mainnet", "testnet", or "devnet". |
| wallet* | Signer | Any ethers-compatible signer. Used to sign transactions and authenticate. |
| rpcUrl | string | Custom RPC endpoint. Defaults to the public Ferros gateway. |
| edgeChannel | boolean | Enable edge channel matching for sub-ms execution. Default: true. |
MarginVault
The MarginVault is your unified margin account. One deposit backs all your positions across perps, options, and event markets. Cross-product offsets are calculated automatically — a long ETH put reduces your ETH perp margin requirement.
deposit
Deposit collateral into your margin vault.
const tx = await client.margin.deposit("USDC", 25_000) // tx.hash — on-chain transaction hash // tx.confirmed — resolves when settled (~500ms)
| Parameter | Type | Description |
|---|---|---|
| asset* | string | Collateral token symbol. Currently "USDC". |
| amount* | number | Amount to deposit in token units. |
withdraw
Withdraw available (non-locked) margin. Fails if withdrawal would cause liquidation.
await client.margin.withdraw("USDC", 5_000)
getBalance
Returns your current margin state including total equity, used margin, available margin, and unrealized PnL.
const balance = await client.margin.getBalance() // { // totalEquity: 25340.50, // usedMargin: 8200.00, // availableMargin: 17140.50, // unrealizedPnl: 340.50, // marginRatio: 0.324, // crossOffset: 1800.00 // saved by portfolio margin // }
forceExit
Emergency withdrawal to the settlement layer. Closes all open positions at market and returns funds. Available at any time, permissionlessly — no approval needed.
// Nuclear option — closes everything, returns all funds await client.margin.forceExit()
forceExit() closes all positions at current market prices. This may result in losses versus limit-closing positions individually. Use only in emergencies.
PositionManager
The PositionManager handles perpetual futures across all supported markets. Orders are matched via edge channels in under 1ms, then settled on-chain in ~500ms through Ferros DAG consensus.
marketOrder
Execute a market order, filled instantly at the best available price.
const order = await client.perps.marketOrder({ market: "BTC-PERP", side: "long", // "long" | "short" size: 1.0, // in base asset units leverage: 10, // 1-50x reduceOnly: false, // optional, default false }) // order.fillPrice — execution price // order.fillSize — actual size filled // order.fee — trading fee in USDC // order.txHash — on-chain settlement hash // order.latencyMs — edge channel match time
| Parameter | Type | Description |
|---|---|---|
| market* | string | Market symbol: "BTC-PERP", "ETH-PERP", "US500-PERP", "XAU-PERP", "WTI-PERP", "XAG-PERP" |
| side* | string | "long" or "short" |
| size* | number | Position size in base asset units. |
| leverage | number | Leverage multiplier (1–50). Default: account default. |
| reduceOnly | boolean | If true, order can only reduce an existing position. |
limitOrder
Place a limit order on the CLOB orderbook. Rests until filled or cancelled.
const order = await client.perps.limitOrder({ market: "ETH-PERP", side: "long", size: 10, price: 3200.00, // limit price in USDC leverage: 5, postOnly: true, // reject if would immediately fill }) // order.orderId — use to cancel or check status // order.status — "open" | "partial" | "filled" | "cancelled"
getPositions
Fetch all open positions across all markets.
const positions = await client.perps.getPositions() // [ // { // market: "BTC-PERP", // side: "long", // size: 0.5, // entryPrice: 87420.00, // markPrice: 88100.00, // unrealizedPnl: 340.00, // leverage: 5, // liquidationPrice: 72850.00, // marginUsed: 8742.00, // } // ]
closePosition
// Close entire BTC-PERP position at market await client.perps.closePosition("BTC-PERP")
Available Markets
| Market | Asset Class | Max Leverage |
|---|---|---|
| BTC-PERP | Crypto | 50x |
| ETH-PERP | Crypto | 50x |
| US500-PERP | Equity Index | 20x |
| XAU-PERP | Commodity | 20x |
| WTI-PERP | Commodity | 20x |
| XAG-PERP | Commodity | 20x |
OptionsEngine
European-style options with Black-Scholes pricing. Includes 0DTE hourly expiries — the first time this exists on-chain. Options are portfolio-margined against your perp positions for maximum capital efficiency.
buyOption
const option = await client.options.buyOption({ underlying: "BTC", type: "call", // "call" | "put" strike: 90_000, // strike price in USDC expiry: "0dte", // "0dte" | "1h" | "4h" | "1d" | "1w" | ISO date quantity: 5, // number of contracts }) // option.premium — total premium paid // option.greeks — { delta, gamma, theta, vega, rho } // option.expiryTime — exact expiry timestamp // option.contractId — unique on-chain identifier
| Parameter | Type | Description |
|---|---|---|
| underlying* | string | "BTC", "ETH", "US500", "XAU" |
| type* | string | "call" or "put" |
| strike* | number | Strike price in USDC. |
| expiry* | string | Expiry shorthand ("0dte", "1h", "4h", "1d", "1w") or ISO 8601 date. |
| quantity* | number | Number of option contracts. |
sellOption
Write (sell) an option. Margin is locked based on Black-Scholes valuation and portfolio offsets.
const written = await client.options.sellOption({ underlying: "US500", type: "put", strike: 5200, expiry: "0dte", quantity: 10, }) // written.premiumReceived — premium collected // written.marginLocked — margin reserved for this position
getChain
Fetch the full options chain for an underlying asset. Returns all available strikes and expiries with real-time Greeks.
const chain = await client.options.getChain("BTC", { expiry: "0dte", // filter by expiry }) // chain.calls — array of { strike, bid, ask, delta, gamma, theta, oi, volume } // chain.puts — same structure // chain.expiry — exact expiry time // chain.iv — implied volatility surface
"0dte" = next hourly expiry, "1h" = one hour out, "4h" = four hours out.
EventMarket
Binary prediction markets resolved by oracle price feeds — no human judgment. "Will BTC hit $100k by Friday?" is resolved automatically from the same feeds that price your perps.
buyShares
const position = await client.events.buyShares({ market: "BTC-100K-FRI", outcome: "yes", // "yes" | "no" shares: 100, // number of shares maxPrice: 0.65, // max price per share ($0.01-$1.00) }) // position.avgPrice — average fill price per share // position.cost — total cost in USDC // position.payout — $1.00/share if correct, $0 if wrong
listMarkets
const markets = await client.events.listMarkets({ status: "active", // "active" | "resolved" | "all" category: "price", // "price" | "volatility" | "funding" }) // [ // { // id: "BTC-100K-FRI", // question: "Will BTC be above $100,000 by Friday 16:00 UTC?", // yesPrice: 0.62, // noPrice: 0.38, // volume: 284_000, // expiresAt: "2026-04-11T16:00:00Z", // oracle: "pyth:BTC/USD", // } // ]
Market Categories
| Category | Examples | Resolution |
|---|---|---|
| price | "BTC > $100k by Friday" | Oracle price at expiry |
| volatility | "BTC 24h vol > 5%" | Realized vol calculation |
| funding | "BTC funding positive for 7 days" | Funding rate aggregation |
Agent Delegation
Grant scoped, on-chain trading permissions to AI agents, bots, or other wallets. Delegation is enforced at the protocol level — not via API keys. An agent can trade but can never withdraw your funds.
grantScope
Create a delegation scope that defines exactly what an agent is allowed to do.
const scope = await client.delegate.grantScope({ agent: "0xAgentWallet...", budget: 10_000, // max notional in USDC maxLeverage: 5, markets: ["BTC-PERP", "ETH-PERP", "US500-PERP"], instruments: ["perps", "options"], // allowed instrument types canWithdraw: false, // always false for agents expiresAt: "2026-04-12T00:00:00Z", // optional auto-revoke }) // scope.scopeId — on-chain scope identifier // scope.txHash — delegation transaction
revokeScope
Instantly revoke an agent's permissions. Takes effect immediately — any in-flight orders from the agent are cancelled.
await client.delegate.revokeScope(scope.scopeId)
listScopes
const scopes = await client.delegate.listScopes() // Returns all active delegation scopes with usage stats: // [{ scopeId, agent, budget, budgetUsed, markets, status }]
canWithdraw is enforced on-chain by the MarginVault contract. Even if an agent's private key is compromised, funds cannot be extracted. The worst case is the agent opening and closing positions within its budget.
Protocol Architecture
Ferrium is a stack of composable on-chain programs deployed on Ferros Network. The protocol has three layers:
Layer 1: Ferros Network (Infrastructure)
- Edge Channels — Bilateral state channels for sub-millisecond order matching. Orders are matched off-chain, then batched and settled on-chain.
- DAG Consensus — Directed Acyclic Graph consensus with no single sequencer. Eliminates MEV by design.
- Stablecoin Gas — Transaction fees paid in USDC. No need to hold a volatile gas token.
- Native CLOB — Central limit order book built into the network layer. No AMM, no slippage for resting orders.
Layer 2: Ferrium Protocol (On-chain Programs)
- MarginVault — Unified margin account with cross-product portfolio margining.
- PositionManager — Perpetual futures lifecycle: open, modify, close, funding.
- OptionsEngine — Black-Scholes priced European options with 0DTE hourly expiries.
- EventMarket — Binary prediction markets with oracle-based resolution.
- LiquidationEngine — Progressive liquidation with portfolio-aware risk assessment.
- FundingRate — Continuous funding rate mechanism anchored to oracle price.
Layer 3: Frontends (Your Application)
Any frontend, protocol, or agent can compose Ferrium's on-chain programs. The official Ferrium SDK makes integration straightforward, but you can also interact with the contracts directly.
┌─────────────────────────────────────────────────┐ │ Your Frontend │ Any App │ AI Agent │ Bot │ └───────────────────────┬─────────────────────────┘ │ @ferrium/sdk ┌───────────────────────┴─────────────────────────┐ │ MarginVault │ PositionMgr │ OptionsEngine │ │ EventMarket │ Liquidation │ FundingRate │ └───────────────────────┬─────────────────────────┘ │ Ferrium Protocol ┌───────────────────────┴─────────────────────────┐ │ Edge Channels │ DAG Consensus │ Native CLOB │ │ Stablecoin Gas │ └─────────────────────────────────────────────────┘ Ferros Network
Margin System
Ferrium uses unified portfolio margin — one collateral pool backs all your positions across every instrument and asset class. This is how professional trading firms operate, and it's a first for DeFi.
How Cross-Product Offsets Work
When you hold positions that naturally hedge each other, Ferrium reduces your margin requirement. Examples:
- Long ETH-PERP + Long ETH Put — The put protects the perp's downside. Margin on the perp is reduced proportional to the put's delta.
- Long BTC-PERP + Short US500-PERP — Historical correlation reduces combined margin by up to 30%.
- Short BTC Call + Long BTC-PERP — Covered call. Call is fully backed; no additional margin required for the short option.
Margin Calculation
// For each position: initialMargin = notionalValue / leverage // Portfolio offset (reduces total): portfolioMargin = sum(initialMargins) - crossOffsets // Cross offsets calculated from: // 1. Delta netting across same underlying // 2. Correlation offsets across asset classes // 3. Option coverage (covered calls, protective puts) // Maintenance margin = 50% of initial margin // Liquidation triggers when equity < maintenance margin
Order Matching
Orders are matched in two phases: instant matching via edge channels, and on-chain settlement via Ferros consensus.
Phase 1: Edge Channel Match (< 1ms)
When you submit an order, it's routed to the edge channel network. Orders are matched bilaterally between counterparties with cryptographic commitments. No single party sees the full order flow — this is what makes Ferrium MEV-free.
Phase 2: On-chain Settlement (~500ms)
Matched orders are batched and submitted to Ferros DAG consensus. Settlement updates the MarginVault, PositionManager, and FundingRate contracts atomically.
Order Submitted │ ├── Edge channel routes to matching engine ~0.2ms ├── Bilateral match with counterparty ~0.5ms ├── Cryptographic commitment exchanged ~0.1ms │ ├── Batch submitted to DAG consensus ~50ms ├── Consensus achieved (no single sequencer) ~400ms ├── State updated on-chain ~50ms │ Settlement Complete ~500ms total
Liquidation
Ferrium uses progressive liquidation rather than full position liquidation. When your portfolio's equity drops below the maintenance margin, positions are reduced gradually, starting with the highest-risk position.
Liquidation Process
- Warning zone (equity < 150% of maintenance) — No action taken, but
onMarginWarningevent fires. - Partial liquidation (equity < 100% of maintenance) — Highest-risk position reduced by 25%. If margin ratio recovers, liquidation stops.
- Full liquidation (equity < 50% of maintenance) — All positions closed at market. Remaining equity returned to vault.
Listening for Liquidation Events
client.on("marginWarning", (data) => { console.log(`Margin ratio: ${data.marginRatio}`) console.log(`Maintenance: ${data.maintenanceMargin}`) }) client.on("liquidation", (data) => { console.log(`Position ${data.market} reduced by ${data.amount}`) })
Oracle Feeds
Ferrium aggregates price data from multiple oracle sources with median filtering and staleness protection. The same feeds price your perps, options, and event markets.
Feed Sources
| Asset | Primary | Secondary | Update Frequency |
|---|---|---|---|
| BTC/USD | Pyth | Chainlink, Switchboard | 400ms |
| ETH/USD | Pyth | Chainlink, Switchboard | 400ms |
| US500 | Pyth | Custom Index | 1s (market hours) |
| XAU/USD | Pyth | Chainlink | 1s |
| WTI/USD | Pyth | Chainlink | 1s |
| XAG/USD | Pyth | Chainlink | 1s |
Reading Oracle Prices
const price = await client.getOraclePrice("BTC") // { // price: 87420.50, // confidence: 12.30, // +-$12.30 // timestamp: 1712345678, // sources: ["pyth", "chainlink", "switchboard"], // }
Settlement
All positions settle to the Ferros Network base layer. Settlement is atomic — margin updates, position changes, and fee accrual happen in a single transaction.
Settlement Types
| Type | Trigger | Timing |
|---|---|---|
| Trade settlement | Order fill via edge channel | ~500ms |
| Funding settlement | Continuous, every block | ~500ms |
| Option expiry | Expiry time reached | Automatic, at expiry block |
| Event resolution | Oracle condition met or expiry | Within 1 block of trigger |
| Liquidation | Margin ratio breach | Immediate, next block |
Force Exit
At any time, you can invoke forceExit() on your MarginVault to close all positions and withdraw all funds to the settlement layer. This is permissionless and cannot be blocked by anyone — not Ferrium, not a counterparty, not a frontend. Your funds are always yours.
Edge Channels
Edge channels are bilateral state channels between trading counterparties. They enable sub-millisecond order matching while preserving the security of on-chain settlement.
How They Work
- Channel opening — Two parties open a state channel backed by on-chain collateral in the MarginVault.
- Off-chain matching — Orders are matched bilaterally with cryptographic signatures. Neither party can cheat — both must sign to update state.
- Batch settlement — Matched trades are batched and submitted to DAG consensus. Settlement is final and atomic.
- Dispute resolution — If a counterparty goes offline, the latest signed state can be submitted on-chain to force-settle.
Why Sub-Millisecond Matters
Professional traders and market makers require low-latency execution. By matching off-chain and settling on-chain, Ferrium achieves faster execution than Hyperliquid's sequencer (<1ms vs ~2ms) while maintaining full decentralization — there is no single sequencer that can be front-run.
edgeChannel: false in your client config to force all orders through on-chain consensus only (slower, but some use cases require it).
0DTE Mechanics
0DTE (zero days to expiration) options are the fastest-growing instrument in traditional finance — 50% of CBOE's SPX volume. Ferrium brings them on-chain for the first time.
Expiry Schedule
| Underlying | Expiry Type | Frequency | Settlement |
|---|---|---|---|
| BTC | Hourly | Every hour, on the hour | Cash-settled in USDC |
| ETH | Hourly | Every hour, on the hour | Cash-settled in USDC |
| US500 | Daily | 4:15 PM ET (market close) | Cash-settled in USDC |
| XAU | 4-hour | Every 4 hours from 00:00 UTC | Cash-settled in USDC |
Pricing Model
Options are priced using Black-Scholes with implied volatility derived from the on-chain options orderbook and historical volatility from oracle feeds. Greeks (delta, gamma, theta, vega, rho) are computed in real-time and available through the SDK.
Strike Generation
For each expiry, strikes are auto-generated around the current oracle price at fixed intervals. For BTC: every $500 within 10% of spot. For US500: every 25 points within 5% of spot.
MEV Protection
Ferrium is MEV-free by design, not by mitigation. Three architectural properties make frontrunning and sandwich attacks structurally impossible:
1. Bilateral Matching
Orders in edge channels are matched between two specific counterparties. No third party — no searcher, no validator, no sequencer — sees your order before it's matched. There is nothing to frontrun because there is no shared mempool.
2. DAG Consensus (No Single Sequencer)
Ferros uses DAG-based consensus where multiple validators propose blocks in parallel. There is no single sequencer that can reorder transactions for profit. Block ordering is determined by cryptographic DAG structure, not by a single party's choice.
3. Atomic Settlement
When matched trades settle on-chain, they land as atomic batches. The settlement contract validates that both parties' signed commitments match. There is no window between match and settlement where a third party could intervene.
Ready to build?
Start integrating with the Ferrium SDK, or join the community to ask questions and share what you're building.