Skip to content

Hyperliquid Support

Hyperliquid is the first perpetual-futures order-book venue supported by the Almanak SDK. The same intent-based workflow applies — decide() → Intent → compile → execute — but the execution substrate is unlike any EVM DEX: orders are placed on an off-EVM L1 order book (HyperCore) through a system contract on Hyperliquid's EVM layer (HyperEVM), and they settle asynchronously. Understanding that split is the key to using — and accounting for — the connector correctly.

Supported intents: PERP_OPEN and PERP_CLOSE on chain hyperevm (chain id 999).

The three layers (read this first)

Hyperliquid is not one chain. Value and execution live across three distinct layers, and each is visible on a different explorer. Confusing them is the single most common source of "where are my funds?" questions.

Layer What lives here How you interact Explorer
Arbitrum The entry/exit door for USDC. The canonical Bridge2 deposit contract (0x2Df1c51E…163dF7) lives here. Send native Circle USDC to Bridge2 to deposit; withdrawals arrive here. arbiscan.io
HyperCore (off-EVM L1) Your USDC margin and your perp positions. The order book, the matching engine, funding, liquidations. Not a smart contract — an L1 clearinghouse. Read via precompiles or the API. HL app / API only — no EVM explorer
HyperEVM (chain 999) The general-purpose EVM layer. The CoreWriter system contract (0x3333…3333) and read precompiles. Native gas token HYPE. Your strategy sends sendRawAction here to place orders; reads hit the precompiles. hyperevmscan.io

The practical consequences you must internalize:

  • Your USDC margin is NOT on HyperEVM. It never appears on hyperevmscan. It was deposited from Arbitrum into HyperCore, and it lives in HyperCore. hyperevmscan for your wallet shows only sendRawAction calls (your orders) and HYPE (gas).
  • Your ETH long is NOT an ERC-20. There is no token to balanceOf. A perp position is a clearinghouse entry in HyperCore, read via a precompile.
  • A successful HyperEVM transaction is a submission, not a fill. Settlement happens later on HyperCore (see Execution model).

Hyperliquid vs a standard EVM DEX — what's different

Aspect EVM DEX (Uniswap, GMX, …) Hyperliquid
Instrument Spot token / on-chain perp position Off-EVM perpetual, USDC-margined
Order placement A contract call that executes atomically in the tx CoreWriter.sendRawAction(bytes) — queues an order for HyperCore
Settlement Synchronous — the tx succeeds ⇒ the trade happened Asynchronous — the tx queues the order; HyperCore fills it ~1–2 s later
Position representation ERC-20 balance / NFT / on-chain struct HyperCore clearinghouse entry (no token)
Reading position balanceOf / contract view Read precompile 0x0800 (eth_call) or the HL API
Price oracle Chainlink / Pyth contracts HyperCore oracle precompile 0x0807 (0x0806 for mark)
Order types Market / limit, per-DEX Market synthesized as an aggressive IOC limit crossing the book (see below)
Collateral Deposited into the DEX contract USDC bridged from Arbitrum into the HyperCore account
Fill economics in the receipt Yes (logs) No — the EVM receipt has no fill price/size/PnL; those live on HyperCore

Supported intents & strategies

Intent What it does Notes
PERP_OPEN Open (or add to) a perp long/short Market IOC, oracle-anchored, fail-closed
PERP_CLOSE Reduce/close a perp Reduce-only IOC; sized from the on-chain position

There are no resting-limit / stop / take-profit order types in the intent vocabulary today — every perp intent is market-style (immediate IOC with a slippage bound). Strategy-side stops/targets are implemented by evaluating state each tick and emitting a market close (see the trailing-stop demo). leverage on an intent is recorded and surfaced as a warning, never faked: CoreWriter has no set-leverage action, so the position uses the account's current leverage setting.

Two reference strategies ship with the connector:

  • hyperliquid_trailing_perp (demo) — a single-direction perp with a ratcheting trailing stop: take-profit caps the upside, a hard stop is the liquidation buffer, and once the trade is up by an activation threshold a trailing stop ratchets behind the high-water PnL. Exits are evaluated strategy-side and fired as market reduce-only closes; it re-enters after each close.
  • strategies/accounting/perp_hyperliquid (accounting fixture) — a USDC-margined ETH/USD round-trip (open → hold → teardown close) used to score the Accountant Test.

Execution model: CoreWriter

A perp order is placed by encoding a HyperCore action and submitting it to the CoreWriter system contract:

Intent (PERP_OPEN, ETH/USD, $15, long)
  → compiler reads the HyperCore oracle price (precompile 0x0807)  ← fail-closed if unavailable
  → builds an aggressive IOC limit at oracle ± slippage
  → encode_limit_order_action(...) → sendRawAction(bytes) calldata
  → one tx to CoreWriter 0x3333…3333  (selector 0x17938e13)
  → tx status 1 + one RawAction log   ← SUBMISSION accepted
  → HyperCore settles ~1–2 s later    ← the actual FILL

Key properties:

  • Market = aggressive IOC limit. HyperCore has no "market order" primitive; every order is a limit order with a time-in-force. A market order is synthesized as an IOC limit priced at oracle ± slippage, so it crosses the book immediately or cancels the remainder.
  • Fail-closed anchoring. If the oracle precompile read is unavailable, compilation fails rather than sending an unanchored order.
  • Reduce-only closes. PERP_CLOSE reads the live position (precompile 0x0800), derives the direction from the on-chain sign, and submits a reduce-only order sized to the position — it can only shrink, never flip.

Verifying execution: submission ≠ fill

Because settlement is asynchronous, a green HyperEVM transaction does not prove your order filled. An IOC order can partially fill or be rejected (insufficient margin, sub-$10 order value, no liquidity) while sendRawAction still returns status 1. The EVM receipt carries no fill information.

You confirm execution by reading HyperCore state, not the receipt — two independent ways:

  1. Trustless, on-chain — position precompile 0x0800. eth_call it and decode (szi, entryNtl, isolatedRawUsd, leverage, isIsolated). If szi matches the size you submitted, the order filled and the position is yours. This is what the SDK's perps_read.py does every portfolio snapshot.
  2. Independent API — api.hyperliquid.xyz clearinghouseState. Same position + margin + entry + unrealized PnL in human units; cross-check it against the precompile.

The rule of thumb: a sendRawAction is a "sent," not a "done." "Done" is a position read that matches what you sent. The connector productizes this as a settlement observer: the position "appears" in the portfolio only once HyperCore has filled it and the precompile read reflects it — the same async pattern GMX V2 uses for keeper-settled fills.

Accounting

Accounting on Hyperliquid draws from two surfaces with very different granularity and trust properties.

A. Precompiles — trustless on-chain state (point-in-time)

Read Precompile Granularity
Position (size, entry notional, margin, leverage, isolated flag) 0x0800 current, per-market
Account margin summary 0x080F current account
Mark / oracle / spot price 0x0806 / 0x0807 / 0x0808 current, per-asset

Precompiles give you current balances and position state, provable on-chain. They do not provide order lifecycle or fill history.

B. The HyperCore API — full order/fill lifecycle (authoritative, not on-chain)

Read API type Granularity
Order status: submitted → resting → filled / partial / cancelled / rejected orderStatus (by oid/cloid) per order
Fills — price, size, side, fee, closedPnl, time, order id userFills per fill (finest)
Open/resting orders openOrders per order
Funding paid/received userFunding per funding event
Deposits / withdrawals / transfers / liquidations userNonFundingLedgerUpdates per ledger event

Our CoreWriter orders carry a deterministic client-order-id (cloid) derived from the intent id, so orderStatus-by-cloid can positively confirm fill vs reject for a specific submission.

What the SDK reads today

perps_read.py reads the position precompile — the trustless state layer: position size, entry notional, margin, and unrealized PnL (from the mark price). Confirmed against live mainnet: szi = ×10^szDecimals, entryNtl = 1e6 USD.

The fill-level layer (per-fill fees + realized PnL via userFills, funding via userFunding, and orderStatus-by-cloid to close the submission-vs-fill gap) is API-sourced and flows through the gateway; wiring it is ongoing work. Until it lands, position-lifecycle events and per-fill economics are not recorded, so the full 21-cell Accountant Test for the Hyperliquid perp is not yet scored — the connector's execution and position-read paths are validated on live mainnet, but the fill-economics accounting is pending.

Funding a wallet

USDC margin lives on HyperCore and is reached through Arbitrum, not HyperEVM:

  1. Get native Circle USDC (0xaf88…5831) onto your wallet on Arbitrum (USDC.e is rejected).
  2. Transfer that USDC to Bridge2 0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7 on Arbitrum. A plain transfer credits the sender's HyperCore perp account in under a minute. Minimum $5.
  3. Fund HYPE for gas on chain 999 (CoreWriter txs are cheap — ~50k gas).

Note the $10 minimum order value applies to spot as well as perps (only reduce-only closes are exempt). Withdrawal is the reverse: HyperCore → Arbitrum via the bridge (a small fixed fee), then Arbitrum → your destination.

Safe / Zodiac permissions

For Safe-wallet execution, the connector authorizes exactly one target: CoreWriter sendRawAction, scoped to PERP_OPEN/PERP_CLOSE, with native-value send disallowed (margin is off-EVM, gas is native HYPE, tx value is 0). No ERC-20 approvals are needed. The selector is derived from the signature — not a hand-typed literal — so the authorized selector cannot drift from the calldata the compiler emits.

Running strategies

# Live on mainnet (gateway auto-starts); continuous, torn down by a separate signal
uv run almanak strat run -d almanak/demo_strategies/hyperliquid_trailing_perp --network mainnet --dashboard

# Dry run — build the snapshot and run decide(), compile the intent, but do NOT submit
uv run almanak strat run -d almanak/demo_strategies/hyperliquid_trailing_perp --network mainnet --dry-run --once

# Teardown (separate signal; resolve the deployment_id from the boot log / strategy DB)
uv run almanak strat teardown request -d almanak/demo_strategies/hyperliquid_trailing_perp -s deployment:<hash> -f

Hyperliquid cannot be tested on a managed Anvil fork — the HyperCore precompiles only exist on the live node, and orders fill off the EVM. Validation is done on live mainnet (small size) or via --dry-run against live chain-999 data.

Production considerations

Data layer

The gateway serves hyperevm price by reading the HyperCore oracle precompile (0x0807) — there is no Chainlink on HyperEVM, and perp majors have no ERC-20 to price by address. USDC/USDT0/WHYPE are statically registered so balance/price resolution is instant; other symbols on hyperevm resolve static-only (a perp index like "ETH" is not an ERC-20 balance and fails fast rather than doing on-chain discovery).

Known limitations

  • Async settlement. A submitted order is not a confirmed fill — reconcile against the position read (above). Strategy state should be driven by the observed position, not by submission success.
  • No native limit/stop/TP orders. The intent vocabulary is market-IOC only; strategy-side logic emits market closes for stops/targets.
  • Fill-economics accounting is pending. Per-fill fees, realized PnL, funding, and orderStatus-by-cloid are API-sourced and not yet wired; the 21-cell Accountant Test for the perp is not yet scored.
  • Cross-margin valuation. Cross-margin positions carry no per-position collateral (margin is shared at the account level); until the account-margin-summary read (0x080F) is wired into valuation, a cross-margin position's net value is PnL-only.
  • Isolated-margin scale. isolatedRawUsd is assumed 1e6 USD; confirm against a live isolated position before trusting isolated-margin net value.

Next steps

  • Read Supported Chains for the hyperevm chain descriptor.
  • See almanak/connectors/hyperliquid/ for the connector implementation and almanak/demo_strategies/hyperliquid_trailing_perp/ for the reference strategy.
  • The connector API reference is auto-generated at Connectors → Hyperliquid.