Docs White Yellow

The Hypurrliquid Paper

A Complete Reverse Engineering Reference for the Hyperliquid L1
lastdotnet/hyperliquid-rust · Binary build 105cb1dc (2026-03-21) mainnet / 331bef9b (2026-04-03) testnet · Hardfork v81

This document is derived entirely from reverse engineering of the deployed hl-node binary (81MB stripped ELF), live traffic captures, on-chain observation, and ABCI state snapshot analysis. It is not official Hyperliquid documentation. Every structural claim traces to confirmed binary evidence and is cited with its source.

Use the White Paper for the architectural narrative and the Yellow Paper for protocol-truth and implementation-boundary details.

1. Architecture Overview #

Hyperliquid L1 (HyperCore) is a purpose-built blockchain for perpetual futures, spot trading, lending (BOLE), prediction markets (HIP-4), and an integrated EVM (HyperEVM). It uses HyperBFT consensus with sub-second block times and processes ~200,000 operations/second.[1]

1.1 System Stack

graph TD A["HyperBFT Consensus\n24 validators, ~70ms blocks"] --> B["Exchange State Machine\n56-field god struct"] B --> C["Matching Engine\nPrice-time priority"] B --> D["Clearinghouse\n18 fields, margin"] B --> E["HyperEVM\nrevm 36, Cancun"] B --> F["BOLE Lending\n19-field BolePool"] B --> G["Outcomes HIP-4\nPrediction markets"] C --> H["Funding Settlement\n1h interval, EMA"] D --> I["Liquidation Engine\nADL, backstop"] E --> J["CoreWriter\n0x3333...3333"] style A fill:#8B5CF6,stroke:#6d45c8,color:#fff

1.2 Crate Map

CrateLinesPurpose
hl-engine~4KExchange state machine, matching, clearinghouse, funding, fees, state hash (LtHash16)
hl-evm~2.5Krevm 36, Cancun spec, L1 precompiles (0x0800+), CoreWriter, RocksDB, JSON-RPC
hl-consensus~1.5KHyperBFT two-chain commit, QC/TC validation, mempool, epoch manager
hl-network~2KGossip wire protocol, TCP framing, LZ4, MsgConcise/OutMsgConcise parsing
hl-devnet~2KDevnet orchestrator: mock oracle/bridge/broadcaster, block producer, HTTP API
hl-node~1KCLI binary (hlx), node builder, mode dispatch
hl-primitives~1.5KCore types: blocks, actions, validators, chain config
hl-rpc~500HTTP RPC server, /info API (30+ query types)
hl-storage~500QMDB backend, S3 ingest
hl-stages~300Reth-style pipeline stages
hl-exex~200Execution extensions (ExEx) framework
hl-re~200Binary RE tools (not runtime)

1.3 Confirmed Dependency Versions

Extracted from path strings in the 81MB binary.[2]

CrateVersionPurpose
blake31.7.0LtHash XOF (SSE2/AVX2/AVX512)
sha20.10.8LtHash finalization (SHA-256)
k2560.13.3secp256k1 signatures
secp256k10.29.0Consensus signing
rmp-serde1.3.0State serialization (MessagePack)
ethers-core2.0.14Ethereum types
tiny-keccak2.0.2Keccak-256 (address derivation)
revm19.2.0EVM executor
revm-precompile16.0.0EVM precompiles
alloy-rpc-types-eth0.9.2RPC types
alloy-consensus0.9.2Consensus types
tokio1.44.2Async runtime
serde_json1.0.120JSON serialization
chrono0.4.38Timestamps
clap2.34.0CLI parsing
rand_chacha0.3.1Deterministic RNG
Internal Source Layout (from binary panic paths)
/home/ubuntu/hl/code_Mainnet/        (mainnet build 105cb1dc)
+-- base/          -- Shared utilities (40+ files)
+-- db/            -- RocksDB backend
+-- evm_rpc/       -- EVM JSON-RPC
+-- l1/            -- Core logic
|   +-- abci/engine.rs, state.rs
|   +-- book/book/impl_insert_order.rs
|   +-- clearinghouse/
|   +-- exchange/impl_trading.rs, end_block.rs, exchange.rs, impl_outcome.rs
|   +-- evm/hyper_evm.rs, transactor.rs
|   +-- staking.rs, vault/, fees/compute.rs, bole/user_state.rs
+-- net_utils/     -- TCP + LZ4
+-- node/consensus/ -- state.rs, server.rs, types.rs, timer.rs, mempool.rs,
                      client_block.rs, heartbeat_tracker.rs, rpc.rs, network.rs

/home/ubuntu/hl/code_Testnet/        (testnet build 331bef9b, 2026-04-03)
+-- base/          -- Utilities (50+ files, expanded)
+-- db/            -- RocksDB backend
+-- evm_rpc/       -- EVM JSON-RPC
+-- l1/            -- Core logic (+ core_writer.rs in evm/)
+-- node/          -- Orchestration + Consensus

2. Consensus: HyperBFT #

HyperBFT is a two-chain HotStuff variant. CONFIRMED BIN: "CertifiedTwoChainCommit" in rodata[3]

2.1 Parameters

ParameterValueEvidence
Block time~70msOBSERVED
FinalityInstant (no reorgs)CONFIRMED
Active validators24 (mainnet), top 50 (testnet)OBSERVED
Epoch100,000 rounds (~90 min)CONFIRMED
Proposer selectionRoundRobinTtlCONFIRMED
Signingsecp256k1 (RFC 6979, low-S/EIP-2)CONFIRMED BIN: k256-0.13.3
Domain separator"Hyperliquid Consensus Payload" + 0x00CONFIRMED BIN: VA 0x6d10f4, GDB live capture
Signing formulakeccak256(domain + 0x00 + bincode(content))CONFIRMED
VoteAppHashEvery 2000 blocksOBSERVED

2.2 Round Lifecycle

sequenceDiagram participant P as Proposer participant V as Validators (2/3+) participant N as Next Proposer Note over P: Round R begins P->>V: PROPOSE (Block + QC for R-1) V->>V: Verify proposer, QC, parent_round V->>P: VOTE (sign block hash) Note over V: 2/3+ stake votes P->>V: QC formed for Round R Note over N: Round R+1 N->>V: PROPOSE (Block + QC for R) Note over V: Block R COMMITTED (two-chain)

2.3 Core Structures

Block { round, parent_round, tx_hashes, qc, tc, block_hash, time, proposer }
ClientBlock { proof: { signed_block, commit_proof }, txs }
Qc { block_hash, round, signatures }
Tc { signed_timeouts, round }
CommitProof { child: Signed<Block>, grandchild_qc: Qc }
EpochTracker { epoch_states, active_epoch, cur_epoch_state, cur_epoch, epoch_duration_seconds }

2.4 Consensus Errors

CONFIRMED at VA 0x6600fa.[4]

ErrorMeaning
QcNoQuorumInsufficient stake weight
QcRoundBeforeHardforkQC before hardfork boundary
EmptyValidatorsNo validators
CommitProofChildQcChild QC must reference committed block
CommitProofGrandchildQcGrandchild QC must reference child
CommitProofConsecutiveBlocks must be consecutive rounds
TcNoQuorumInsufficient TC stake weight
TimeoutRoundMismatchTimeout round mismatch
AlreadyHaveTimeoutFromNodeDuplicate timeout
BadBlockRoundBlock/commit round mismatch
BlockAlreadyRegisteredDuplicate block
ValidatorIPMismatchIP mismatch

2.5 Validator Signing Gates (6 Checks)

#CheckFailure
1is_main_signerNot designated signer
2Active set"Home validator has left the active set."
3Not jailedjailed_signers
4last_vote_roundDouble-vote prevention
5Not disableddisabled_validators
6Round matchVote round != consensus round

3. Mempool #

Mempool {
    committed_tx_hashes:  HashSet,    // dedup
    uncommitted_txs:      HashMap,    // pending
    tx_hash_to_seq_num:   HashMap,    // ordering
    block_hash_to_block:  HashMap,    // block buffer
    broadcaster_nonces:   HashMap,    // per-broadcaster
}

No hard mempool size limit CONFIRMED. Eviction is time-based.[5]

3.1 Admission Pipeline (7 Stages)

StageCheckError
1Parse action"could not parse action"
2Signature verifyAddTxNotSigned
3Broadcaster whitelistTxUnexpectedBroadcaster
4Broadcaster nonceTxInvalidBroadcasterNonce
5DedupAddTxDuplicate
6Already committedAddTxCommitted
7Enqueue--

4. Block Execution Pipeline #

CONFIRMED from binary VA 0x01e748e0 and string at 0x539f8a. Pipeline: RecoverUsers → BeginBlock → DeliverSignedActions → ProcessFills → EVM Block → EndBlock → Commit → VoteAppHash.[6]

graph LR A["RecoverUsers"] --> B["BeginBlock\n9 named effects"] B --> B2["Supplementary\n5 per-book effects"] B2 --> C["DeliverSignedActions\n90 action types"] C --> D["ProcessFills\nFees + Settlement"] D --> E["EVM Block\nSmall (1s) + Big (60s)"] E --> F["EndBlock\nMark prices"] F --> G["Commit\nLtHash16 + SHA-256"] G --> H["VoteAppHash\n(every 2000 blocks)"] style B fill:#fbbf24,stroke:#333,color:#000 style C fill:#34d399,stroke:#333,color:#000 style D fill:#34d399,stroke:#333,color:#000 style E fill:#60a5fa,stroke:#333,color:#000 style F fill:#fb923c,stroke:#333,color:#000 style G fill:#8B5CF6,stroke:#333,color:#fff

4.1 RecoverUsers

Before any effects: parse block header, validate proposer is active validator, verify broadcaster authorization per bundle, recover EIP-712 signers, reject duplicate nonces.

4.2 BeginBlock — 9 Named Effects CONFIRMED

Binary-confirmed order from VA 0x01e748e0 (2026-04-02). Note: this ordering differs from older RE notes which placed BOLE after funding.

#EffectGuardWhat
1update_oraclePre-process oracle state for block
2distribute_fundingfunding_distribute_guard (8s)Settle funding: payment = szi × px × Δcum_funding
3apply_bole_liquidationsHealth < 0.8 → partial/market/backstop liquidation + ADL cascade
4update_funding_ratesfunding_update_guard (8s)Sample premium, update DeterministicEma
5refresh_hip3_stale_mark_pxship3_stale_mark_px_guardFall back stale mark prices to oracle (10s window)
6prune_book_empty_user_statesbook_empty_user_states_pruning_guard (60s)Remove users with zero-size positions
7update_staking_rewardsStage epoch staking rewards
8update_action_delayerDrain matured CoreWriter delayed actions and execute as L1
9update_aligned_quote_tokenSample stake-weighted median SOFR rate from validator votes

Supplementary per-book maintenance (after the 9 named effects):

EffectGuard
check_trigger_orders (TP/SL)
cancel_aggressive_orders_at_oi_capcancel_oi_cap_guard (1s)
validator_l1_vote_tracker_prune_expiredInternal (60s)
reset_recent_oisreset_recent_oi_guard (1s)
update_stale_mark_guardsPer-book

4.3 DeliverSignedActions

Each bundle is processed sequentially. Per action: resolve actor (EIP-712 recovery), nonce check, try typed dispatch (HlAction enum, 90 variants), fall back to JSON string dispatch. Fills accumulate in BlockResult.

4.4 ProcessFills

After all actions: per-fill fee computation (compute_fee() with tiers + referral), debit fees, clearinghouse.process_fill() for position updates, volume tracking for tier progression, fill history (capped 1000/user), ExEx event emission.

4.5 EVM Block Phase

Dual-block architecture: small blocks (1s, 2M gas) for responsive UX + big blocks (60s, 30M gas) for heavy computation. Each block's receipts are scanned for CoreWriter RawAction(address,bytes) logs from 0x3333...3333. Decoded actions are enqueued in ActionDelayer with delay_scale × 3000ms delay and later fire through the named delayed-action lane in the next block's begin_block (slot 8 in the current widened testnet note).

In replay mode (no executor): raw tx calldata parsed via minimal RLP scanner to extract CoreWriter calls without EVM execution.

4.6 EndBlock

Update mark prices from order book mid-prices: for each book with orders, mark_prices[asset] = book.mid_price().

4.7 Commit + VoteAppHash

State hash: rmp_serde → blake3 XOF (2048B) → paddw u16 (LtHash16) → SHA-256 (32B). 11 L1 + 3 EVM accumulator categories. Final app_hash is first_16(SHA-256(L1_combined)) || first_16(SHA-256(EVM_combined)). Every 2000 blocks, validators submit VoteAppHash; quorum at 2/3+ stake agreement.

4.8 Timing Parameters

ParameterValue
Block time (HyperBFT)~70ms
Funding interval8000ms
OI cap check1000ms
Book pruning60000ms
HIP-3 stale markFrom snapshot
CoreWriter delay3000ms × delay_scale
BOLE partial liq cooldown30s
VoteAppHash checkpoint2000 blocks
Aligned quote token voteDaily 22:00 UTC

4.9 Action Dispatch — All 97 Variants

Main dispatcher at VA 0x0272a320 (>500KB). CONFIRMED: the current widened testnet note exposes 90 mainnet + 7 testnet-only variants. Use the dedicated Action Inventory for the authoritative family/sub-variant tables; local parity work on the full surface is still active.[8]

Trading (9 types)

Wire NameActionState TouchedShare
orderPlace limit/IOC/ALO ordermatching.books, oid_to_order, fills68.2%
cancelCancel by OIDmatching.books, oid_to_order10.5%
cancelByCloidCancel by client order IDmatching.books, cloid_to_oid16.7%
modifyModify resting order price/sizematching.books<0.1%
batchModifyBatch modify multiple ordersmatching.books0.9%
scheduleCancelSchedule future cancel for assetuser_to_scheduled_cancel0.3%
twapOrderSubmit TWAP ordertwap.running_heap<0.1%
twapCancelCancel TWAP ordertwap.user_to_id_to_state<0.1%
liquidateLiquidate underwater positionclearinghouse.positions, balances<0.1%

Margin & Leverage (3 types)

Wire NameActionState Touched
updateLeverageSet leverage for assetclearinghouse.positions
updateIsolatedMarginAdd/remove isolated marginclearinghouse.balances, isolated_margins
topUpIsolatedOnlyMarginTop up isolated-only marginclearinghouse.balances

Transfers (6 types)

Wire NameActionState Touched
usdSendSend USDC to another userclearinghouse.balances (both users)
usdClassTransferUSD class transferclearinghouse.balances
spotSendSend spot tokenspot_clearinghouse.user_balances
sendAssetGeneral asset transfer (multi-dex)routing + balances
withdraw3Withdraw USDC (v3)clearinghouse.balances
sendToEvmWithDataL1 → EVM transfer with calldataclearinghouse.balances, hyper_evm queues

Sub-Accounts (3 types)

Wire NameActionState Touched
createSubAccountCreate sub-accountsub_accounts
subAccountTransferTransfer USD between master/subclearinghouse.balances
subAccountSpotTransferTransfer spot token between master/subspot_clearinghouse.user_balances

Vaults (6 types)

Wire NameActionState Touched
createVaultCreate a new vaultvaults.vaults
vaultTransferDeposit/withdraw from vaultvaults.followers, clearinghouse.balances
vaultDistributeDistribute vault profitsvaults.followers, total_equity
vaultModifyModify vault configvaults.vaults
netChildVaultPositionsNet child vault positionsvaults.children
setVaultDisplayNameSet vault display namevaults.vaults

Staking (5 types)

Wire NameActionState Touched
tokenDelegateDelegate HYPE to validatorstaking.delegations, stakes
claimRewardsClaim staking rewardsstaking.rewards, clearinghouse.balances
linkStakingUserLink staking identitystaking.linked_staking_users
registerValidatorRegister new validatorstaking.validator_profiles
extendLongTermStakingExtend long-term lockstaking.long_term_locks

Account (7 types)

Wire NameActionState Touched
approveAgentAuthorize agent addressagents.user_to_main_agent
setDisplayNameSet user display nameuser_to_display_name
setReferrerSet referrer codefee_tracker.referrer_states
convertToMultiSigUserConvert to multi-sig accountmulti_sig_users
approveBuilderFeeApprove builder fee rateagents.builder_fees
startFeeTrialStart fee trial periodfee_tracker.fee_trials
userPortfolioMarginEnable portfolio marginportfolio_margin_users

DeFi & Abstraction (5 types)

Wire NameActionState Touched
borrowLendBOLE deposit/borrow/repaybole.reserves, user_positions
userDexAbstractionEnable DEX abstractionuser_abstraction_settings
userSetAbstractionSet abstraction configuser_abstraction_settings
agentSetAbstractionAgent abstraction configuser_abstraction_settings
agentEnableDexAbstractionAgent enable DEX abstractionuser_abstraction_settings

Governance (3 types)

Wire NameActionState Touched
govProposeSubmit governance proposalgovernance_proposals
govVoteVote on proposalgovernance_proposals[].votes
voteGlobalValidator governance vote (22 sub-types)Various (see below)

VoteGlobal Sub-Types (22 wired)

Sub-TypeState Touched
ModifyBroadcasterstaking.broadcasters
HaltPerpTradingclearinghouse.halted_assets
SetPerpDexOpenInterestCapopen_interest_caps
DisableNodeIpdisabled_node_ips
QuarantineUserquarantined_users + cancel all orders
CancelUserOrdersmatching.cancel_all_for_user
SetOutcomeFeeScaleoutcome_fee_scale
SetCoreWriterActionEnabledhyper_evm.disabled_core_writer_actions
SetScheduledFreezeHeightscheduled_freeze_height
SetPostOnlyUntilTimepost_only_until_time
SetPostOnlyUntilHeightpost_only_until_height
SetMaxOrderDistanceFromAnchormax_order_distance_from_anchor
SetBridge2WithdrawFeebridge2_withdraw_fee
SetPerformAutoDeleveragingperform_auto_deleveraging
SetSpotDisabledspot_disabled
SetEvmEnabledevm_enabled
SetL1TransfersEnabledhyper_evm.l1_transfers_enabled
SetDexAbstractionEnableddex_abstraction_enabled
SetPerpsDisabledLaunchperps_disabled_launch
SetHip3NoCrosship3_no_cross
SetFundingMultiplierfunding[asset].multiplier
SetMarginModemargin_modes

Validator (9 types)

Wire NameActionState Touched
CValidatorValidator profile managementstaking.validator_profiles
CSignerUnjail/jail validatorstaking.jailed
validatorL1VoteL1 oracle consensus votevalidator_l1_vote_tracker
validatorL1StreamL1 stream (SOFR rate vote)hpt.validator_rate_votes
signValidatorSetUpdateSign bridge validator set updatebridge_vote_tracker
ValidatorSignWithdrawalSign bridge withdrawalbridge_vote_tracker
VoteEthDepositVote on ETH depositbridge_vote_tracker
VoteEthFinalizedWithdrawalVote finalized withdrawalbridge_vote_tracker
VoteEthFinalizedValidatorSetUpdateVote finalized validator setbridge_vote_tracker

HIP-3/HIP-4 (3 types + sub-types)

Wire NameActionSub-Types
SetGlobalActionOracle/margin/fee configoraclePxs, externalPerpPxs, usdtUsdcPx, nativePx, markPxs, marginTable
perpDeployHIP-3 perp deploymentregisterAsset, setOracle, setSubDeployers, setPerpAnnotation, setFeeScale, setFeeRecipient, haltTrading, insertMarginTable, outcomeDeploy
spotDeploySpot market deployment

System (11 types)

Wire NameActionState Touched
SystemBoleSystem BOLE operationsbole (stub)
SystemSpotSendSystem spot transferrouting + balances
SystemUsdClassTransferSystem USD class transferrouting + balances
SystemSendAssetSystem asset transferrouting + balances
SystemApproveBuilderFeeSystem builder fee approvalagents.builder_fees
SystemAlignedQuoteSupplyDeltaAligned quote supply adjustmentclearinghouse.balances
DeployerSendToEvmForFrozenUserRecovery for frozen usersclearinghouse.balances
CWithdrawConsensus withdrawalclearinghouse.balances
CUserModifyConsensus user balance modifyclearinghouse.balances
EvmUserModifyEVM user balance modifyclearinghouse.balances
ReassessFeesReassess user fee tierfee_tracker

Special (7 types)

Wire NameActionState Touched
evmRawTxExecute raw EVM transactionhyper_evm, action_delayer (via CoreWriter)
multiSigMulti-sig wrapperRe-dispatches inner action
noopNo-op (heartbeat)None
VoteAppHashValidator state hash voteapp_hash_vote_tracker
ForceIncreaseEpochForce epoch incrementstaking.current_epoch
userOutcomeOutcome market operationsoutcomes (split/merge/negate/mergeQuestion)
settleFractionPartial outcome settlementoutcomes.markets

Additional (8 types)

Wire NameActionState Touched
priorityBidGas priority biddingpriority_bids
registerSpot / registerSpot2Register spot assetspot_registrations
disableDexHalt asset tradingclearinghouse.halted_assets
setPerpAnnotationSet perp metadataperp_annotations
evmContractTransferEVM contract transferfinalized_evm_contracts
cancelAllOrdersCancel all user ordersmatching.cancel_all_for_user
quarantineUserFreeze + cancel allmatching + quarantined_users
setMarginModesSet per-asset margin modesmargin_modes

Total: the current widened testnet note exposes 97 action variants, expanding to 126 sub-types (+ 6 SetGlobal + 8 PerpDeploy + 22 VoteGlobal). Treat that as the current action-surface map, not as a blanket claim that parity is complete on every branch.[9]

5. Exchange State (57 Keys) #

The Exchange struct: ALL L1 state. ~1.1GB as .rmp, saved every ~20 min.[10]

CONFIRMED Serde struct chain discovered at .rodata offset 0x543428 in testnet binary (2026-04-03). This gives the complete ABCI state serialization layout -- every field name, order, and nesting depth for the full Exchange struct hierarchy. BIN: testnet 331bef9b .rodata 0x543428

All 57 Exchange Fields
#FieldType
1locusLocus(15)
2perp_dexsPerpDex(4)[]
3spot_booksBook[]
4agent_trackerAgentTracker(5)
5-6funding_distribute_guard, funding_update_guardBucketGuard
7sub_account_trackerSubAccountTracker(2)
8allowed_liquidatorsVec
9bridge2Bridge2(10)
10stakingStaking(6)
11c_stakingCStaking(23)
12funding_err_dur_guardErrDurGuard
13max_order_distance_from_anchorConfig
14-15scheduled_freeze_height, simulate_crash_heightOption<u64>
16validator_power_updatesVec
17cancel_aggressive_orders_at_oi_cap_guardBucketGuard
18-20last_hlp_cancel_time, post_only_until_time, post_only_until_heightu64/Option
21-24spot_twap_tracker, user_to_display_name, book_empty_user_states_pruning_guard, user_to_scheduled_cancelVarious
25-29hyperliquidity, spot_disabled, prune_agent_idx, max_hlp_withdraw_fraction_per_day, hlp_start_of_day_account_valueVarious
30-32register_token_gas_auction, perp_deploy_gas_auction, spot_pair_deploy_gas_auctionGasAuction
33hyper_evmHyperEvm(13)
34-36vtg, app_hash_vote_tracker, begin_block_logic_guardVarious
37-39user_to_evm_state, multi_sig_tracker, reserve_accumulatorsVarious
40-43partial_liquidation_cooldown, evm_enabled, validator_l1_vote_tracker, staking_link_trackerVarious
44-47action_delayer(9), default_hip3_limits(6), hip3_stale_mark_px_guard, disabled_precompilesVarious
48-54lvt, hip3_no_cross, initial_usdc_evm_system_balance, validator_l1_stream_tracker, last_aligned_quote_token_sample_time, user_to_evm_to_l1_wei_remaining, dex_abstraction_enabledVarious
55-57hil, oh, abstractionUnknown/AbstractionState

5.1 Locus (15 Keys, 3-Char Serde Renames)

Locus is the compact core container inside the 57-field Exchange. The parent Exchange uses full field names in serde; Locus is the notable exception that still uses short 3-character keys.

KeyFull nameRole
clsclearinghousesMain perp clearinghouse plus HIP-3 clearinghouses.
sclspot_clearinghouseSeparate spot clearinghouse state.
ctxcontextBlock height, round, time, next IDs, system nonce.
ftrfee_trackerFee schedule, referral state, builder fees.
ustuser_statesMain user state map.
chnchainChain label such as Mainnet or Testnet.
pdlperps_disabled_launchLaunch / gating flag for perp activity.
uaRuser_action_registrySparse or empty registry surface; exact operational use still weakly grounded.
blpbole_poolBOLE lending pool and reserve-level state.
qusqueue_signersQueue signer addresses.
ctrcountersTransaction / validation / action counters.
uacuser_account_configsPer-user account configuration and mode state.
vltvaultsAll vault state.
hcmhot_cold_modeOperational hot/cold mode switch.
auxauxiliaryLater-added auxiliary slot; present in snapshots even though older binary descriptors still say 14 elements.

5.2 Clearinghouse (18 Fields)

This is the perp risk and balance core that locus.cls[] stores for the main market and each HIP-3 perp universe.

FieldRole
metaPerp metadata, margin tables, collateral token, and market-level configuration.
user_statesPer-user position, balance, and open-order state for this clearinghouse.
oracleOracle and external-perp pricing state for this clearinghouse.
total_net_depositAggregate net deposits into the clearinghouse.
total_non_bridge_depositNon-bridge deposit aggregate used in accounting and safety checks.
perform_auto_deleveragingFlag that ADL is active for this clearinghouse.
adl_shortfall_remainingResidual shortfall still needing deleveraging.
bridge2_withdraw_feeBridge-related withdrawal fee carried in clearinghouse state.
daily_exchange_scaled_and_raw_vlmsVolume accounting and daily scaled volume trackers.
halted_assetsPer-asset halt state.
override_max_signed_distances_from_oraclePer-asset order-distance overrides relative to oracle / anchor prices.
max_withdraw_leverageWithdrawal leverage guardrail.
last_set_global_timeTimestamp of the last oracle / governance-style global update.
usdc_ntl_scaleUSDC notional scaling tuple.
isolated_externalIsolated-margin external accounting surface.
isolated_oracleOracle-side isolated-margin state.
mohMainOrHip3 discriminator for main clearinghouse vs HIP-3 clearinghouse.
znfnFill nonce counter.

5.3 CStaking (23 Fields)

CStaking is the on-chain validator, delegation, governance, and broadcaster-control surface. The raw binary inventory is easier to use when grouped by purpose.

FieldPurpose
stakesValidator stake ledger.
allow_all_validatorsOpen vs permissioned validator-set switch.
allowed_validatorsExplicit allow-list when the set is permissioned.
broadcastersWhitelisted broadcaster addresses for signed user action intake.
validator_to_profileValidator metadata and profile state.
validator_to_last_signer_change_timeSigner rotation timing guard.
delegationsDelegator-to-validator stake mapping.
proposalsGovernance proposal storage.
stakes_decay_bucket_guardRate limiter for stake decay / maintenance logic.
jailed_signersCurrently jailed signer set.
jail_vote_trackerVote aggregation for jailing decisions.
jail_untilJail expiry timestamps.
signer_to_last_manual_unjail_timeManual unjail cooldown tracking.
native_token_reserveNative-token reward / reserve pool.
stage_reward_bucket_guardRate limiter for reward staging.
validator_to_staged_rewardsPending rewards not yet distributed.
distribute_reward_bucket_guardRate limiter for reward distribution.
pending_withdrawalsUnstaking and pending withdrawal queue.
self_delegation_requirementMinimum self-bond requirement for validators.
disabled_validatorsValidators removed from service without deleting historical state.
disabled_node_ipsNode IP denylist / disable surface.
validator_to_statePer-validator lifecycle state.
gversionGovernance version marker.

5.4 Live State Size

MetricValue
Users2,138,136
Positions3,760,980
Total USDC$3.01B
Order book levels170,972

6. Matching Engine #

6.1 Cancel Reasons (11)

CONFIRMED at offset 0x64f964.[11]

#StatusCause
0marginCanceledInsufficient margin
1perpMaxPositionCanceledExceeds max position
2vaultWithdrawalCanceledVault withdrawal
3openInterestCapCanceledOI cap
4selfTradeCanceledSelf-trade prevention
5reduceOnlyCanceledWould increase position
6siblingFilledCanceledOCO sibling filled
7liquidatedCanceledUser liquidated
8outcomeSettledCanceledMarket settled
9scheduledCancelUser-scheduled
10internalCancelSystem-internal

6.2 Reject Reasons (17)

#StatusMessage
0tickRejected"Price must be divisible by tick size."
1minTradeNtlRejectedBelow minimum notional
2perpMarginRejected"Insufficient margin to place order."
3perpMaxPositionRejected"Order would exceed maximum position size"
4reduceOnlyRejected"Reduce only order would increase position."
5iocCancelRejected"Order could not immediately match"
6badTriggerPxRejected"Invalid TP/SL price."
7badAloPxRejected"Post only order would have immediately matched."
8marketOrderNoLiquidityRejected"No liquidity available for market order."
9positionIncreaseAtOpenInterestCapRejected"Cannot increase position when OI is at cap."
10positionFlipAtOpenInterestCapRejected"Cannot flip position when OI is at cap."
11tooAggressiveAtOpenInterestCapRejected"Asset open interest is at cap."
12openInterestIncreaseRejected"Open interest is increasing too quickly."
13insufficientSpotBalanceRejected"Insufficient spot balance"
14oracleRejected"Price too far from oracle"
15outcomeSettledRejected"Outcome has been settled"
16hip3CrossMarginReduceOnly"Cross margin currently only supports reduce-only"

6.3 Fee Tiers

VIP Tiers (7 Levels) API: app.hyperliquid.xyz/fees[12]

Tier14d NTLPerp TakerPerp MakerSpot TakerSpot Maker
Base$04.5 bps1.5 bps7.0 bps4.0 bps
VIP1$5M4.01.26.03.0
VIP2$25M3.50.85.02.0
VIP3$100M3.00.44.01.0
VIP4$500M2.80.03.50.0
VIP5$2B2.60.03.00.0
VIP6$7B2.40.02.50.0

MM Tiers (3): MM1 0.5%/-0.1bps, MM2 1.5%/-0.2bps, MM3 3.0%/-0.3bps

Staking Discount Tiers (7)

bps Staked00.010.1110100500
Discount0%5%10%15%20%30%40%

6.3.1 FeeSchedule and FeeTracker Layouts

CONFIRMED from binary struct chain in testnet build 331bef9b (2026-04-03). BIN: serde field chain at .rodata 0x543428

FeeSchedule (9 fields)

tiers                          // VIP tier definitions
referral_discount              // Referral discount percentage
referrer_keep                  // Referrer keep percentage
extra_destination_fractions    // Extra fee destination routing
stake_discount_tiers           // Staking discount tier table
weigh_spot_volume_double       // Double-weight spot volume flag
aligned_quote_token_config     // Aligned quote token configuration
+2 unknown fields              // Under investigation

FeeTracker (10 fields)

fee_schedule                   // Active FeeSchedule(9)
unrewarded_users               // Users pending reward distribution
user_states                    // Per-user fee accounting state
referrer_states                // Per-referrer fee accounting state
code_to_referrer               // Referral code -> referrer mapping
referral_bucket_millis         // Referral bucket timing
total_fees_collected           // Cumulative fees collected
total_spot_fees_collected      // Cumulative spot fees collected
collected_builder_fees         // Builder fee accumulator
trials_disabled                // Fee trial disable flag

6.4 Wire Format

OrderWireSerde  { a: u32, b: bool, p: String, s: String, r: bool, t: OrderTypeWire, c: Option<Cloid> }
OrderAction     { orders: Vec, builder: Option<OrderBuilderInfo>, grouping: Grouping }
Cancel          { a: u32, o: u64 }
CancelByCloid   { asset: u32, cloid: Cloid }
ModifyWire      { oid: u64, order: OrderWireSerde }
TwapWireSerde   { a: u32, b: bool, s: String, r: bool, m: u64, t: bool }
// Tif: Alo | Ioc | Gtc    Tpsl: Na | NormalTpsl | PositionTpsl
// Grouping: Na | Default | DexAbstraction | UnifiedAccount | PortfolioMargin

6.5 Matching Algorithm CONFIRMED

Price-time priority CLOB with self-trade prevention and post-only enforcement. Each asset has an independent order book backed by BTreeMap<PriceKey, VecDeque<Order>>.

flowchart TD A["Incoming Order\n(price, size, side, tif)"] --> B{ALO\npost-only?} B -->|Yes| C{Would cross\nbest opposite?} C -->|Yes| D["REJECT\nbadAloPxRejected"] C -->|No| E[Skip to Rest] B -->|No| F{Side?} F -->|Buy| G["Walk ask levels\n(ascending price)"] F -->|Sell| H["Walk bid levels\n(descending price)"] G --> I{Order price\n>= ask level?} H --> J{Order price\n<= bid level?} I -->|No| K[Stop matching] J -->|No| K I -->|Yes| L[Match at level] J -->|Yes| L L --> M{Same user?\nself-trade} M -->|Yes| N["Cancel resting maker\nselfTradeCanceled"] M -->|No| O["Generate Fill\nmin(remaining, maker_sz)"] O --> P[Update positions] P --> Q{Order\nfilled?} Q -->|No| L Q -->|Yes| K N --> L K --> R{TIF type?} R -->|IOC| S["Discard remainder\n(no rest)"] R -->|GTC| T{Remaining > 0?} R -->|ALO| E T -->|Yes| U["Rest on book\nstatus=resting"] T -->|No| V["Fully filled"] E --> U S --> W["Done\n(fills emitted)"] U --> W V --> W D --> X["Done\n(no fills)"]

Data Structure Layout

OrderBook {
  bid_levels: BTreeMap<-price, PriceLevel>   // negative key = descending sort (best bid first)
  ask_levels: BTreeMap<+price, PriceLevel>   // positive key = ascending sort (best ask first)
  oid_index:  HashMap<u64, (Side, PriceKey)> // O(1) cancel by OID
}

PriceLevel {
  orders: VecDeque<Order>   // FIFO: front = oldest (first priority)
  total_size: f64           // aggregate size at this price
}

// BTreeMap guarantees: O(log n) insert/lookup, ordered iteration
// VecDeque guarantees: O(1) push_back (new orders), O(1) pop_front (best time priority)
// HashMap guarantees: O(1) cancel by OID

Key Properties

PropertyBehaviorEvidence
Price priorityBest price matched first (highest bid, lowest ask)BTreeMap iteration order
Time priorityAt same price, earliest order fills firstVecDeque FIFO (front = oldest)
Self-trade preventionCancel resting maker order, continue matchingCONFIRMED: "selfTradeCanceled"
Post-only (ALO)Reject BEFORE matching if would cross bookCONFIRMED: "badAloPxRejected"
IOC behaviorFill what's available, discard remainder (no rest)CONFIRMED: "iocCancelRejected"
Reduce-onlyNever rests on book, cancels if would increase positionCONFIRMED: "reduceOnlyCanceled"
Fill priceMaker's resting price (not taker's limit price)Standard CLOB: passive side sets execution price
Trigger ordersStored separately, activated when oracle crosses trigger_pxCONFIRMED: must be reduce-only

Post-Match Pipeline

For each fill in block:
  1. Compute fees via full fee pipeline (VIP tier, MM, staking, referral, builder)
  2. Debit fees from maker and taker balances
  3. Update positions via clearinghouse.process_fill()
  4. Increment fill nonce counter (znfn)
  5. Record fill in state hash (OrderStatusHash::Filled → Na accumulator)
  6. Track volume for VIP tier advancement
  7. Emit fill event for WebSocket subscribers

7. Funding Rate System #

7.1 Parameters

ParameterValueEvidence
Settlement1 hourAPI: fundingHistory 3600s apart[13]
Rate expressionper 8hINFERRED
Default interest0.01%/8h = 0.0000125/1hOBSERVED: BTC pins 314/500 samples

7.2 Algorithm

1. premium = (mark_px - oracle_px) / oracle_px
2. EMA: decay = exp(-dt * ln(2) / half_life)
   num   = num * decay + premium * (1 - decay)
   denom = denom * decay + (1 - decay)
   smoothed = num / denom
3. Clamp to [-max_slippage, +max_slippage]
4. rate = smoothed * perp_to_funding_multiplier[asset]
5. rate += perp_to_funding_interest_rate[asset]
6. Binance mode: premium_index + clamp(interest - premium_index, -0.0005, 0.0005)

7.3 FundingTracker (8 Fields)

1. asset_to_premiums    2. override_impact_usd    3. clamp
4. default_impact_usd   5. hl_only_perps          6. use_binance_formula
7. perp_to_funding_multiplier    8. perp_to_funding_interest_rate

DeterministicEma(5): num, denom, decay_duration, n_samples, [last_update_time]
DeterministicVty(7): desc, samples, emas, val, n_updates, n_bucket_updates, alert_bucket_guard

8. Oracle and Mark Price #

The oracle pipeline transforms external price feeds into consensus oracle prices, mark prices, and ultimately funding rates and liquidation triggers. Every step has been confirmed from binary RE.[13]

8.1 Full Oracle Pipeline

graph TD A["External Feeds\nBinance, CME, etc."] --> B["Validators fetch prices\nvia HTTP"] B --> C["ValidatorL1VoteAction\nper-validator signed vote"] C --> D["ValidatorL1VoteTracker\nprune_bucket_guard, action_to_tracker"] D --> E["StreamTracker\nstake-weighted median"] E --> F["SetGlobalAction\nBroadcaster submits consensus prices"] F --> G["Oracle struct\npxs, external_perp_pxs, err_dur_guard, lpxk"] G --> H["Mark Price Calculation"] H --> I["coin_to_mark_px\ncoin_to_oracle_px\ncoin_to_external_perp_px"] I --> J["Funding + Liquidation"] style E fill:#8B5CF6,stroke:#333,color:#fff style F fill:#fbbf24,stroke:#333,color:#000

8.2 SetGlobalAction (4 Fields) CONFIRMED

The broadcaster submits consensus oracle prices via SetGlobalAction (variant 1 of SetGlobal sub-types). The 4th field is nativePx -- the native token (HYPE) price. BIN: confirmed 2026-04-02

SetGlobalAction {
    pxs: Vec<Option<String>>,              // oracle prices, indexed by asset
    externalPerpPxs: Vec<Option<String>>,   // external perp prices (Binance, etc.)
    usdtUsdcPx: Option<String>,            // USDT/USDC exchange rate
    nativePx: Option<String>,              // CONFIRMED: HYPE price
}

Governance sub-actions (variant index 0..14): registerAsset, setOracle, insertMarginTable, setFeeRecipient, haltTrading, setMarginTableIds, setOpenInterestCaps, setFundingMultipliers, setMarginModes, setFeeScale, setGrowthModes, setFundingInterestRates, disableDex, setPerpAnnotation.

8.3 Oracle Struct (4 Fields) CONFIRMED

Oracle {
    pxs: HashMap<u32, f64>,               // consensus oracle prices per asset
    external_perp_pxs: HashMap<u32, f64>,  // external perp prices
    err_dur_guard: BucketGuard,            // error duration tracking
    lpxk: OracleKindMap,                   // last price kind map
}

OracleKindMap  // Maps assets to oracle kind: Reserved, NO_ERROR, universe, oraclePx, disabled

8.4 Oracle History Ring Buffer CONFIRMED

Exchange field [55] oh is a ring buffer of 100 oracle snapshots, each containing a full copy of the oracle state at that point in time. SNAP: confirmed from ABCI state at h=942770000

Exchange.oh: Vec<(DateTime, OracleSnapshot)>  // 100 entries
OracleSnapshot {
    pxs: HashMap<u32, f64>,
    external_perp_pxs: HashMap<u32, f64>,
    err_dur_guard: BucketGuard,
    l: ???,   // abbreviated field, purpose TBD
}

This ring buffer provides recent oracle price history for mark price smoothing, stale detection, and error duration tracking.

8.5 Validator Voting Pipeline

Validators submit price votes via ValidatorL1VoteAction. Votes are tracked per action type with expiry-based rounds. CONFIRMED: stake-weighted median.

ValidatorL1VoteTracker(3) {
    prune_bucket_guard: BucketGuard,
    action_to_tracker: HashMap<ActionType, ActionTracker>,
    active: bool,
}
ActionTracker(3) { active: bool, expire_time: u64, vote_tracker: VoteTracker }
VoteTracker(7) { version, round, initial_round, round_to_val, order_ntl, max_px, ema }

StreamTracker(3) {
    validator_to_value: HashMap<Address, ValidatorValue>,
    median_value: f64,                    // CONFIRMED: stake-weighted median
    update_median_bucket_guard: BucketGuard,
}

8.6 Mark Price Formula CONFIRMED

Mark price is derived from the oracle price and order book impact prices. The impact price simulates a trade of impact_usd notional against the book to determine a fair market price.

Impact price configuration:
    default_impact_usd: f64,                   // typically 200 USD
    override_impact_usd: HashMap<u32, f64>,    // per-asset override
    clamp: bool,                                // whether to clamp impact price

Mark price computation:
    impact_bid = simulate_buy(book, impact_usd_notional)
    impact_ask = simulate_sell(book, impact_usd_notional)
    mark_px = f(oracle_px, impact_bid, impact_ask, ema)

Three parallel price maps in exchange state:
    coin_to_mark_px: HashMap<u32, f64>          // mark prices
    coin_to_oracle_px: HashMap<u32, f64>        // oracle prices
    coin_to_external_perp_px: HashMap<u32, f64> // external perp prices

API response per asset (PerpAssetCtx): markPx, funding, openInterest, prevDayPx, dayNtlVlm, premium, midPx, impactPxs (array of [bid_impact, ask_impact]), dayBaseVlm, circulatingSupply, totalSupply.

8.7 HIP-3 Stale Mark Price CONFIRMED

HIP-3 stale mark price detection uses a 10-second window. Mark prices older than 10 seconds are considered stale and refreshed during begin_block (effect #7 of 9). BIN: hip3_stale_mark_px_guard, refresh_hip3_stale_mark_pxs

Exchange fields:
    hip3_stale_mark_px_guard: BucketGuard,   // guards stale mark detection
    hip3_no_cross: bool,                      // disable crossing

Function: refresh_hip3_stale_mark_pxs() -- called in begin_block effect #7
Companion: prune_book_empty_user_states() -- cleanup (begin_block effect #4)

8.8 Oracle Price Bounds

BoundField / Message
Max oracle pricehas_max_oracle_px
Min oracle pricehas_min_oracle_px
Per-asset distance overrideoverride_max_signed_distances_from_oracle
Order distance from anchormax_order_distance_from_anchor = 0.95
OI cap rejection"more aggressive than oracle when open interest is at cap."

9. Liquidation Engine #

See the dedicated Liquidation and ADL reference for the execution split across perps, portfolio margin, BOLE, spot, and outcomes, plus the current call-graph links and open-gap table.

graph TD A["account_value < maintenance"] --> B{"Cross/Isolated?"} B -->|Cross| C["LiquidatedCross"] B -->|Isolated| D["LiquidatedIsolated"] C --> E["Standard liquidation"] D --> E E --> F{"Shortfall?"} F -->|No| G["LtHash updated"] F -->|Yes| H["ADL: sort by PnL%"] H --> G style H fill:#f87171,stroke:#333,color:#fff
TypeLtHash CategoryTrigger
Cross liquidationLiquidatedCrossCross margin below maintenance
Isolated liquidationLiquidatedIsolatedIsolated margin below maintenance
BOLE marketBoleMarketLiquidationHealth factor below threshold
BOLE backstopBoleBackstopLiquidationBackstop takes over
BOLE partialBolePartialLiquidationPartial reduction (cooldown)

Perp liquidation condition: margin_available < 0, equivalently account_value < maintenance_margin. Maintenance is tiered by notional bracket using lower_bound, max_leverage, and maintenance_deduction. Cross positions share account equity; isolated positions use per-position allocated margin.

9.0 begin_block Liquidation Trigger Flow CONFIRMED

BOLE liquidations run as effect #3 of the 9-step begin_block pipeline. Perp liquidations are user-initiated via the Liquidate action during action processing.

graph TD BB["begin_block"] --> E0["1. update_oracle"] E0 --> E1["2. distribute_funding"] E1 --> E2["3. apply_bole_liquidations"] E2 --> E3["4. update_funding_rates"] E3 --> E4["5. refresh_hip3_stale_mark"] E4 --> E5["6. prune_book_empty_states"] E5 --> E6["7. update_staking_rewards"] E6 --> E7["8. update_action_delayer"] E7 --> E8["9. update_aligned_quote_token"] E8 --> DA["Supplementary maintenance"] DA --> AP["Process User Actions"] AP --> LIQ{"Liquidate action?"} LIQ -->|Yes| CHK["check_all_users_for_liquidatables"] CHK --> MM{"maintenance_margin check"} MM -->|Cross below| LC["LiquidateRequest::Cross"] MM -->|Isolated below| LI["LiquidateRequest::Isolated"] LC --> EXEC["Execute LiquidationMarket order"] LI --> EXEC EXEC --> SF{"Shortfall remaining?"} SF -->|No| LT["LtHash updated"] SF -->|Yes| ADL["ADL: rank by ROE"] ADL --> LT E2 --> BOLE{"healthFactor below 0.8?"} BOLE -->|Yes| BLQ["BOLE Market/Backstop/Partial"] BLQ --> BLT["LtHash: BoleMarket/Backstop/Partial"] style E2 fill:#fb923c,stroke:#333,color:#fff style ADL fill:#f87171,stroke:#333,color:#fff style BLQ fill:#fb923c,stroke:#333,color:#fff

9.1 Margin And Trigger Logic

ComponentCurrent best formula / ruleStatus
Initial marginsum(notional_in_tier / max_leverage)Confirmed structure
Maintenance marginsum(notional_in_tier / max_leverage - maintenance_deduction)Confirmed
Cross liquidationbalance + cross_uPnL - maintenance_margin_used < 0Confirmed
Isolated liquidationallocated_margin + uPnL - maintenance_margin < 0Confirmed
Liquidation priceTier-aware maintenance boundary; local implementation uses an approximate closed formApproximation

9.2 Auto-Deleveraging (ADL)

ADL is the shortfall path, not the first path. Standard liquidation runs first. If liquidation still leaves residual bad debt, Hyperliquid flips on perform_auto_deleveraging and tracks the unresolved amount in adl_shortfall_remaining. There are no socialized losses in the current model; loss is pushed into opposing profitable positions.

ADL propertyMeaning
perform_auto_deleveragingExchange / clearinghouse flag indicating ADL mode is active
adl_shortfall_remainingResidual shortfall that liquidation did not cover
asset_and_side_to_adl_requirementsPer-asset, per-side shortfall buckets in the binary model
position_index, risk_keyOrdering fields used in the liquidation / ADL pipeline
returnOnEquityAPI-facing profitability field that matches the ADL ranking surface

Ranking rule: counter-parties are selected from the opposing profitable side and ranked by ROE / PnL%, i.e. unrealized_pnl / margin_allocated. Higher ROE means higher ADL priority. In practical terms: a liquidated long pushes into profitable shorts first; a liquidated short pushes into profitable longs first.

1. Detect liquidatable account
2. Execute ordinary liquidation
3. Compute residual shortfall
4. If residual shortfall > 0:
   - set perform_auto_deleveraging = true
   - update adl_shortfall_remaining
   - bucket by (asset, opposing side)
   - rank profitable counterparties by ROE descending
   - delever until shortfall is exhausted or no eligible size remains

9.3 BOLE Liquidation

BOLE is a separate lending liquidation system with its own three LtHash categories. The strongest confirmed trigger is a 0.8 health-factor threshold. When a BOLE user falls below that boundary, the system can route through one of three liquidation modes:

BOLE modeMeaningGuardrail
MarketOrdinary BOLE liquidation into the market pathRuns only when health is below threshold and no higher-priority backstop route applies
BackstopDefault/backstop liquidator takes over the borrow positionRequires configured liquidator routing
PartialReduce risk without fully closing the borrowSubject to partial_liquidation_cooldown

The current best state model for BOLE risk is: supplied_value, borrowed_value, ltv, and healthFactor. The begin-block pass apply_bole_liquidations is the confirmed entrypoint for that lane.

9.4 Safeguards And Safety Controls

ControlPurpose
allowed_liquidatorsExplicit liquidator allowlist at Exchange scope
defaultLiquidatorUser/BOLE routing hint for backstop-style liquidations
partial_liquidation_cooldown~30 second spacing between repeated partial liquidations
halted_assetsPer-asset halt switch preventing normal trading on frozen markets
override_max_signed_distances_from_oraclePer-asset mark/oracle distance overrides used in risk gating
max_withdraw_leveragePrevents high-leverage withdrawals from extracting too much collateral
MarginMode::NoCross / StrictIsolatedBlocks unsafe cross-margin usage on selected assets

Operational rule set: liquidator margin is checked before liquidation, some assets require the liquidator to use cross margin, and BOLE backstop routing sits beside the ordinary liquidation path rather than replacing it. The current implementation effort mirrors that separation: planner first, then exact state transitions once the remaining edge semantics are proved.

9.5 Formula Sheet

Cross account value
  = balance + sum(unrealized_pnl_cross_positions)

Cross margin available
  = account_value - cross_maintenance_margin_used

Cross liquidation trigger
  = (margin_available < 0)

Isolated margin available
  = allocated_margin + unrealized_pnl - maintenance_margin

Isolated liquidation trigger
  = (isolated_margin_available < 0)

Initial margin
  = sum_over_tiers(notional_in_tier / max_leverage)

Maintenance margin
  = sum_over_tiers(notional_in_tier / max_leverage - maintenance_deduction)

ADL ranking score
  = return_on_equity
  = unrealized_pnl / margin_allocated

BOLE utilization
  = total_borrows / total_deposits

BOLE local health factor
  = supplied_value / borrowed_value

BOLE liquidation trigger
  = (health_factor < 0.8)

Confirmed for the trigger shapes and tier structure. Inferred / local model for parts that still depend on exact binary-side execution semantics, especially final BOLE transfer sizing and full portfolio-margin netting.

9.6 Product Surfaces

SurfaceTrigger pathWhat happensStatus
Perps, cross marginmargin_available < 0 at account levelUser-facing Liquidate path, then ADL if residual shortfall remainsCore trigger confirmed
Perps, isolated marginallocated_margin + uPnL - maintenance < 0LiquidateRequest::Isolated on one assetConfirmed
Portfolio marginSame liquidation family, but on portfolio-netted account stateMode overlay on top of margin engine, not a separate liquidation subsystemSemantics still being tightened
SpotNo ordinary leverage liquidation engine confirmedSpotDustConversion is a separate system cleanup path, not perp-style liquidationDistinct from liquidation
Outcomes (HIP-4)No liquidation path1x isolated-only; settlement auto-cancels open orders and rejects new orders post-settlementNo leverage, no liquidation
BOLE lendinghealthFactor < 0.8Market / Backstop / Partial liquidation lane in begin_blockMode family confirmed

9.7 Trigger Call Graph

graph TD A["Block / User action"] --> B{"Surface"} B -->|Perp Cross| C["Compute account_value and maintenance"] B -->|Perp Isolated| D["Compute isolated_margin_available"] B -->|Portfolio Margin| E["Portfolio-netted margin engine"] B -->|BOLE| F["apply_bole_liquidations in begin_block"] B -->|Spot| G["SpotDustConversion / no perp-style liquidation"] B -->|Outcomes| H["Settlement gating only"] C --> I{"margin_available < 0 ?"} D --> J{"isolated_margin_available < 0 ?"} E --> K{"portfolio margin available < 0 ?"} I -->|Yes| L["LiquidateRequest::Cross"] J -->|Yes| M["LiquidateRequest::Isolated"] K -->|Yes| L L --> N["Check liquidator margin + allowlist + asset rules"] M --> N N --> O["Execute LiquidationMarket"] O --> P{"Residual shortfall?"} P -->|Yes| Q["ADL: bucket by asset/side, rank profitable counterparties by ROE"] P -->|No| R["LtHash: LiquidatedCross / LiquidatedIsolated"] Q --> S["perform_auto_deleveraging = true"] S --> T["adl_shortfall_remaining updated"] F --> U{"healthFactor < 0.8 ?"} U -->|Yes| V["BOLE Market / Backstop / Partial candidate"] V --> W["LtHash: BoleMarket / Backstop / Partial"] H --> X["outcomeSettledCanceled / outcomeSettledRejected"] G --> Y["Spot dust sweep / system cleanup"] style Q fill:#f87171,stroke:#333,color:#fff style V fill:#fb923c,stroke:#333,color:#fff style X fill:#60a5fa,stroke:#333,color:#fff

10. State Hashing: LtHash16 #

10.1 Algorithm CONFIRMED

Action Response (per action)
  -> rmp_serde::to_vec_named(response)     // rmp-serde 1.3.0, named/map mode
  -> blake3::Hasher (streaming Write)      // blake3 1.7.0 at VA 0x04e03010
  -> blake3 XOF (2048 bytes)
  -> 1024 x u16 LE
  -> SSE2 paddw wrapping-add               // VA 0x04e05786
  -> Per-category LtHash16 accumulator (11 L1 + 3 EVM = 14 total)

Final app_hash (32 bytes):
  L1_combined  = paddw(all 11 L1 accumulators)
  EVM_combined = paddw(all 3 EVM accumulators)
  app_hash     = first_16(SHA-256(L1_combined)) || first_16(SHA-256(EVM_combined))
  // NOT a single SHA-256 of all 14 combined! Confirmed from node log at h=536290000

10.2 All 11 L1 Hash Categories

CONFIRMED at rodata 0x65fb61.[15]

#CategoryOffsetPairing
0CValidator0x75fb61[0,1]
1CSigner0x75fb6b[0,1]
2Na0x75fb72[2,3]
3LiquidatedCross0x75fb74[2,3]
4LiquidatedIsolated0x75fb83Unique
5Settlement0x75fb95Unique
6NetChildVaultPositions0x75fb9fUnique
7SpotDustConversion0x75fbb5[7,8]
8BoleMarketLiquidation0x75fbc7[7,8]
9BoleBackstopLiquidation0x75fbdc[9,10]
10BolePartialLiquidation0x75fbf3[9,10]

10.3 RespHash Dispatch

VA 0x205a300. 20-entry jump table at 0x37fe2c. 14 accumulators at 0x800-byte intervals (0x50066c8..0x500cec8). Hashes response structs (not raw mutations).[15]

Response Struct Field Ordering (11 structs, CRACKED)
StructFields (order)VA
OrderStatus"filled": totalSz, avgPx, oid; "error": string; "waitingForFill": oid; "waitingForTrigger": oid; "resting": oid, cloid0x4a75120
RestingOrder (15)coin, side, limitPx, sz, timestamp, triggerCondition, isTrigger, triggerPx, isPositionTpsl, reduceOnly, orderType, origSz, tif, cloid, children0x4a98d30
TwapSliceFill (10)coin, user, side, sz, executedSz, executedNtl, minutes, reduceOnly, randomize, timestamp0x4a701a0
TwapState (4)status, running, error, twapId0x4a70410
Fill/Trade API wrapper (24)API/user-fill wrapper with coin, feeToken, fill context, and externally-tagged OrderStatus; hashed fill payload is a separate 18-field struct0x4a47ec0
ActionError (3)status, success, error0x4a707f0
StatusResult (1)status0x4a70a60
OrderBase (3)side, sz, reduceOnly0x4a80610
OrderWithTiming (5)side, sz, reduceOnly, randomize, timestamp0x4a82640
TriggerParams (2)triggerPx, tpsl0x4a8d2d0
TriggeredFill (2)triggered, filled0x4a99070

2026-04-05 clarification: hybrid G-family actions hash as {status:"success"} on success and use the 3-field {status:"err", success:false, error:<msg>} payload only on error. Fill hashes also no longer share the ordinary ledger-update/API wrapper shape.

10.4 EVM Element Formats

CategorySizeFormat (raw byte concat)
accounts_hash92Baddress(20) || balance(32 BE) || nonce(8 BE) || code_hash(32)
storage_hash84Baddress(20) || slot(32) || value(32)
contracts_hashVariableaddress(20) || code(bytecode)

10.5 VoteAppHash

Every 2000 blocks, 3 validators, ~150 blocks after checkpoint. Mismatch: /tmp/abci_state_with_quorum_app_hash_mismatch.rmp.

10.6 Hash Accumulator Naming Pattern CONFIRMED

Binary strings reveal a systematic naming convention for hash accumulators, partitioned per clearinghouse (DEX) instance. BIN: rodata string search

Pattern: {category}_{dex_prefix}
Where dex_prefix:
    H   = main clearinghouse (clearinghouse index 0)
    H3  = HIP-3 clearinghouses

Examples from binary strings:
    AllBoleTH3        -- all BOLE state for HIP-3 clearinghouse
    borrowLeH3        -- borrow ledger entries, HIP-3
    funding_H3        -- funding state, HIP-3
    1emasH            -- EMAs for main clearinghouse

Per-clearinghouse hash partitioning confirmed:
    Each clearinghouse (main + HIP-3 instances) maintains
    separate LtHash16 accumulators for its own state.
    The suffix distinguishes which clearinghouse owns the
    accumulator. This enables incremental hashing per-DEX
    without cross-contamination between clearinghouse instances.

The 14 total accumulators (11 L1 + 3 EVM) cover: validator state changes, liquidation events (cross, isolated, BOLE), settlement, vault netting, spot dust conversion, and EVM state (accounts, contracts, storage).

11. Gossip Protocol (FULLY CRACKED) #

11.1 Wire Frame

[u32 BE body_len][u8 kind][body]   kind=0x01: LZ4 bincode-fork

11.2 Handshake

Out: [00 00 00 02][00][00][00]  (7B)    In: [00 00 00 01][00][chain]  (6B, chain=0x04=Mainnet)

11.3 MsgConcise (Tag 27, 8 variants)

#Variant
0Tx
1Block
2Vote
3Timeout
4Tc
5BlocksAndTxs
6Heartbeat
7HeartbeatAck

11.4 OutMsgConcise (Tag 28, 9+ variants)

#Variant
0Block
1ClientBlock
2VoteJailBundle
3Timeout
4Tc
5Heartbeat
6NextProposer
7Tx
8RpcRequest

11.5 Mid Field

CONFIRMED: jump table VA 0x65f47c.[20]

MidLabel
0in
1execution state
2out
3status
4round advance

11.6 Heartbeat Wire Layout

Heartbeat { validator(20B), round(u64),
  snapshot: HeartbeatSnapshot {
    validator_set_snapshot: { stakes, jailed_validators },
    evm_block_number: u64,
    concise_lt_hashes: {
      accounts_hash:  ConciseLtHash { hash_concise: [u8;32], n_elements, n_bytes },
      contracts_hash: ConciseLtHash,
      storage_hash:   ConciseLtHash
    }
  },
  validator_to_last_msg_round, random_id
}
// hash_concise = 32B SHA-256 digest (NOT 2048B LtHash16)

11.7 Send Path (6 Layers)

LayerVARole
10x043b8330..8f70Field serializers
20x04593d40MsgConcise struct builder
30x042f8fc0Ring buffer producer
40x043bf670send_to_destination + bincode-fork
50x0409c0e0BTreeMap peer routing
60x01cc9d00tcp_bytes (bswap for BE)

12. HyperEVM #

ParamValue
Enginerevm 36 (upstream 19.2.0)
SpecCancun (no blobs)
Chain ID999 mainnet / 998 testnet
Fast blocks1s, 3M gas
Large blocks60s, 30M gas
FeesBase + priority burned
HYPE0x2222...2222
CoreWriter0x3333...3333 (15 actions, ~25K gas)
Read precompiles0x0800+, gas=2000+65*(in+out)

12.1 Dual-Block Architecture CONFIRMED

HyperEVM runs two parallel block streams with different parameters:

PropertyFast BlockLarge Block
Interval1 second60 seconds
Gas limit3,000,00030,000,000
Use caseDefault transactionsHeavy computation (deploys, batch ops)
RoutingDefaultevmUserModify.usingBigBlocks

Users opt into large blocks via the evmUserModify action with usingBigBlocks: true. Both block types share the same state -- they are sequential, not parallel execution environments.

12.2 CoreWriter (0x3333...3333) CONFIRMED

CoreWriter is the EVM-to-L1 bridge contract at address 0x3333333333333333333333333333333333333333. It is a system precompile, not a deployed contract.

Interface

interface ICoreWriter {
    event RawAction(address indexed user, bytes data);
    function sendRawAction(bytes calldata data) external;
}

Packed Encoding

abi.encodePacked(uint8(1), uint24(actionId), abi.encode(params...))

The version byte is always 1. The uint24 action ID selects the L1 action type. Parameters are standard ABI-encoded after the 4-byte prefix.

CoreWriter Action Types (15)

IDActionParameters
1IocOrderasset, isBuy, limitPx, sz, reduceOnly, cloid
2Cancelasset, cloid
3TransferUsddestination, amount
4TransferSpotdestination, token, amount
5Withdrawdestination, amount
6SpotDeploytoken params
7VaultTransfervault, isDeposit, usd
8UpdateLeverageasset, isCross, leverage
9UpdateIsolatedMarginasset, isBuy, ntl
10Delegatevalidator, amount
11Undelegatevalidator, amount
12ApproveAgentagentAddress, agentName
13ApproveBuilderFeebuilder, maxFeeRate
14BorrowLendoperation, token, amount
15SetReferrercode

All CoreWriter actions go through the ActionDelayer -- they are NOT executed immediately. CONFIRMED

12.3 L1 to EVM Flow (sendToEvmWithData) CONFIRMED

The sendToEvmWithData action transfers funds from L1 (HyperCore) to HyperEVM, with optional calldata execution on arrival. 11 fields confirmed for the action.

StepDescription
1User submits sendToEvmWithData on L1
2User is debited on L1 immediately
3Transfer is queued for the next EVM block
4SystemTx is injected in next EVM block to mint tokens to the user's EVM address
5If calldata was specified, it is executed on the EVM side after minting
sequenceDiagram participant U as User participant L1 as HyperCore (L1) participant EVM as HyperEVM U->>L1: sendToEvmWithData(destination, amount, calldata) L1->>L1: Debit user balance L1->>L1: Queue transfer for next EVM block L1->>EVM: Inject SystemTx (mint tokens) EVM->>EVM: Execute optional calldata

12.4 EVM to L1 Flow (CoreWriter Scan Loop) CONFIRMED

After each EVM block is executed, the L1 state machine scans transaction receipts for CoreWriter log events and enqueues them as delayed L1 actions.

graph TD A["EVM Block Executed"] --> B["Scan Receipts for\nCoreWriter RawAction logs"] B --> C{"Logs found?"} C -->|No| H["Done"] C -->|Yes| D["Decode packed params\nversion(u8) + actionId(uint24) + ABI params"] D --> E{"Action disabled?\ndisabled_core_writer_actions"} E -->|Yes| F["Drop silently"] E -->|No| G["Enqueue in ActionDelayer"] G --> I["Execute in future\nbegin_block when matured"] style A fill:#60a5fa,stroke:#333,color:#000 style G fill:#fb923c,stroke:#333,color:#000 style I fill:#34d399,stroke:#333,color:#000
StepDescription
1EVM block finishes execution
2Scan all transaction receipts for RawAction events from 0x3333...3333
3Decode packed params: version byte (0x01) + uint24 action ID + ABI-encoded parameters
4Check disabled_core_writer_actions per-type kill switch
5Enqueue in ActionDelayer with maturity timestamp
6Actions execute in a future begin_block when the delay has elapsed; exact placement within begin_block is still open in current RE

12.5 Action Delayer (9 Fields) CONFIRMED

delayed_actions, user_to_n_delayed_actions, n_total_delayed_actions,
max_n_delayed_actions, vty_trackers, status_guard, enabled,
delayer_mode(Alternating), delay_scale

Capacity behavior: When the delayer is at capacity (n_total_delayed_actions >= max_n_delayed_actions), new actions are silently rejected. There is no eviction of existing actions and no error returned to the caller. CONFIRMED

Placement note: the widened execution note and current local engine now align on update_action_delayer as the named delayed-action lane at slot 8. What remains open is the ActionDelayer control logic around enabled, delayer_mode, status_guard, and vty_trackers.

ActionDelayerStatus

enum ActionDelayerStatus {
    On,                           // Always active
    Alternating { seconds: u64 }, // Active in alternating windows
}

DelayedActionSerde

DelayedActionSerde {
    action,          // The L1 action to execute
    id,              // Unique action identifier
    is_frontend,     // Whether submitted via frontend
    expires_after,   // Expiry timestamp
    evm_tx_hash,     // Source EVM transaction hash
    broadcaster,     // Broadcasting validator
}

12.6 Security Model

ControlPurpose
No ERC20 approve attackCoreWriter reads msg.sender directly -- no transferFrom pattern, preventing approval-based exploits
disabled_core_writer_actionsPer-action-type kill switch. Validators can disable individual CoreWriter action IDs
l1_transfers_enabledGlobal kill switch for all L1 transfers
Action delayAll CoreWriter actions go through ActionDelayer, preventing MEV/front-running from EVM contracts
Frozen user recoveryDeployerSendToEvmForFrozenUserAction allows deployers to recover funds for frozen users (new in testnet 2026-04-03)
Silent rejection at capacityNo eviction, no error -- prevents DoS amplification

13. Bridge #

The ETH-Hyperliquid bridge (version 2, "Bridge2") enables deposits and withdrawals between Ethereum L1 (Arbitrum) and HyperCore. Bridge operations use the same validator signer keys as consensus -- there are NOT separate EOA signing keys for bridge operations. CONFIRMED[22]

13.1 Bridge2 Struct (10 Fields) CONFIRMED

Exchange field [8] bridge2. SNAP: confirmed from ABCI state

Bridge2(10) {
    eth_id_to_deposit_votes,           // deposit confirmation tracking
    finished_deposits_data,            // completed deposits
    withdrawal_signatures,             // withdrawal signature collection
    withdrawal_finalized_votes,        // finalization vote tracking
    finished_withdrawal_to_time,       // withdrawal completion timestamps
    validator_set_signatures,          // validator set update signatures
    validator_set_finalized_votes,     // validator set finalization votes
    bal,                               // bridge balance as UsdcNtl [usdc, ntl]
    last_pruned_deposit_block_number,  // deposit pruning watermark
    oaw,                               // only-allow-withdrawals flag
}

13.2 Signing Model CONFIRMED

Bridge signing = consensus signing. The consensus signer key (the key used for HyperBFT voting) is the same key that signs bridge withdrawal messages and validator set updates. There are NOT separate EOAs.

PropertyValue
Signing keySame secp256k1 key as consensus (hot signer)
Quorum threshold2/3+ stake-weighted (same as HyperBFT consensus)
Ethereum-side architectureHot/cold wallet on Bridge2.sol contract
Hot signersValidator signer keys (mirrors consensus signer set)
Cold signersHigher-security keys for validator set updates and emergencies
Dispute periodWithdrawals have a dispute period before finalization on Ethereum

13.3 Deposit Flow

sequenceDiagram participant U as User participant ETH as Ethereum L1 (Arbitrum) participant V as Validators (2/3+) participant HL as HyperCore U->>ETH: Deposit ETH/tokens to Bridge2.sol ETH->>V: Validators observe deposit on-chain V->>HL: VoteEthDepositAction(3) Note over V: deposit_id, chain, validator Note over HL: Accumulate votes HL->>HL: 2/3+ stake-weighted votes reached HL->>U: Funds credited on HyperCore

VoteEthDepositAction (3 fields): deposit_id, chain, validator. Each validator independently observes the Ethereum deposit and submits a vote. When 2/3+ of stake weight has voted, the deposit is confirmed and funds are credited.

13.4 Withdrawal Flow

sequenceDiagram participant U as User participant HL as HyperCore participant V as Validators (2/3+) participant ETH as Ethereum L1 (Arbitrum) U->>HL: withdraw3 action HL->>HL: Debit user balance V->>HL: ValidatorSignWithdrawalAction(5) Note over V: signature, chain, nonce, withdrawal_hash, validator Note over HL: Collect signatures HL->>HL: 2/3+ stake-weighted signatures HL->>ETH: Withdrawal enters dispute period Note over ETH: Dispute window open ETH->>ETH: Dispute period expires ETH->>U: Funds released on Ethereum

ValidatorSignWithdrawalAction (5 fields): signature, chain, nonce, withdrawal_hash, validator. Validators sign the withdrawal using their consensus signer keys. After 2/3+ signatures are collected, the withdrawal enters a dispute period on Ethereum before funds can be claimed.

13.5 Validator Set Update Flow

When the active validator set changes (due to staking changes, jailing, or epoch transitions), the bridge's Ethereum-side contract must be updated to reflect the new signer set.

1. Validator set changes on HyperCore (epoch transition, delegation change)
2. Validators sign the new validator set: SignValidatorSetUpdateAction
3. validator_set_signatures accumulates signatures
4. 2/3+ stake-weighted signatures collected
5. validator_set_finalized_votes confirms finalization
6. New validator set submitted to Bridge2.sol on Ethereum
7. Bridge2.sol updates hot/cold signer sets

13.6 Bridge Action Types

ActionFieldsPurpose
VoteEthDepositAction3Vote to confirm L1 deposit
ValidatorSignWithdrawalAction5Sign withdrawal message
SignValidatorSetUpdateAction--Sign validator set change
VoteEthFinalizedWithdrawalAction--Finalize withdrawal on L1
InvalidateWithdrawals--Cancel pending withdrawals during dispute period

13.7 Security Model

FindingSeverityDetail
Broadcaster centralizationCriticalSingle broadcaster controls action ordering and inclusion. MEV extraction possible.
InvalidateWithdrawalsCriticalValidators can cancel ANY pending withdrawal during dispute period. No escape hatch for users if validators collude.
No escape hatchCriticalUsers cannot force-withdraw if the validator set becomes adversarial. Bridge is fully trust-dependent on active validator set.
Broadcaster MEVHighBroadcaster sees all pending transactions before inclusion and can front-run, sandwich, or censor.
Instant validator set updateHighModifyBroadcaster is instant (no timelock). Validator set update on Ethereum can be changed with hot key quorum.
Configurable withdrawal feeMediumbridge2_withdraw_fee -- validators can change the withdrawal fee via governance.

14. HIP-4: Outcomes #

Native L1 prediction markets (event contracts). Binary instruments that settle between 0 and 1 (or fractionally via settleFraction). Deployed through the HIP-3 (builder-deployed perps) pipeline but with fundamentally different mechanics: 1x isolated margin only, no leverage, no liquidation, no continuous oracle feed. Price discovery is purely CLOB-based. Settlement by deployer-designated oracleUpdater. Requires 1M HYPE stake (slashable for oracle manipulation).[23]

14.1 OutcomeTracker (11 Fields) CONFIRMED

The OutcomeTracker is stored in the Exchange state and manages all live/active outcomes. BIN: struct OutcomeTracker with 11 elements

State structures:
    OutcomeTracker(11)     -- manages all outcome state in Exchange
    OutcomeSpec(4)         -- tuple struct: settleFraction, details, questions, outcome
    OutcomeSideSpec(3)     -- one side (YES or NO)
    QuestionSpec(5)        -- question grouping related outcomes
    SettledOutcome         -- resolved state
    SettledOutcomeSpec(3)  -- settlement parameters
    SettledOutcomeHistory(3) -- historical record
    SettledQuestionSpec(4) -- question-level settlement

14.2 Outcome Lifecycle

graph TD A["Deploy via Hip3DeployAction\n1M HYPE stake required"] --> B["Opening Auction\n~15 min single-price clearing"] B --> C["Continuous Trading\nStandard CLOB, 1x isolated"] C --> D{"oracleUpdater posts\nSettleOutcome?"} D -->|Yes| E["Trading halts immediately"] E --> F["Open orders auto-cancelled\noutcomeSettledCanceled"] F --> G["Positions auto-settle\nat posted outcome value"] G --> H["Slot Recycling\nReuse 1M HYPE stake"] D -->|No| C style A fill:#8B5CF6,stroke:#333,color:#fff style E fill:#f87171,stroke:#333,color:#fff style H fill:#34d399,stroke:#333,color:#000

14.3 OutcomeDeploy Enum (8 Variants) CONFIRMED

Nested inside Hip3DeployAction. BIN: impl_outcome.rs

VariantFieldsPurpose
RegisterQuestion3Create question grouping multiple outcomes
RegisterOutcome4Create outcome (outcome, settleFraction, details, namedOutcome)
RegisterNamedOutcome2Add named outcome to existing question
ChangeOutcomeDescription2Update outcome metadata
SettleOutcome3Oracle posts final resolution
ChangeQuestionDescription2Update question metadata
RegisterOutcomeToken1Register backing token for outcome market
RegisterTokensAndStandaloneOutcome3Combined token + outcome registration

14.4 UserOutcomeAction Enum (4 Variants) CONFIRMED

VariantFieldsPurpose
SplitOutcome2 (wei, outcome_id)Lock collateral, mint YES+NO pair. Deposit 1 unit collateral = 1 YES + 1 NO.
MergeOutcome1Burn 1 YES + 1 NO to reclaim 1 unit of collateral. Exit without directional view.
MergeQuestion1Redeem complete set across all outcomes in a question (multi-outcome markets).
NegateOutcome3Flip YES to NO (or vice versa) atomically. Swap without two separate trades.

14.5 Settlement Flow

The oracleUpdater address is set at deployment time in Hip3SchemaInput. It is the deployer-designated settlement authority -- the deployer IS the oracle. There is no Chainlink, Pyth, or continuous feed for outcome prices.

Settlement flow:
    1. oracleUpdater submits SettleOutcome(3) via Hip3DeployAction
    2. Trading halts immediately
    3. All open orders auto-cancelled (outcomeSettledCanceled)
    4. New orders rejected (outcomeSettledRejected)
    5. Positions auto-settle at posted outcome value (0, 1, or settleFraction)
    6. Collateral released to winners in collateralToken
    7. Slot recycled -- 1M HYPE stake available for new markets

Price bounds during trading: 0.001 to 0.999
Settlement values: 0 or 1 (binary), or fractional via settleFraction
Collateral: configurable per deployment (any aligned quote token, NOT restricted to USDH)

14.6 Price Discovery Model

PropertyPerps (HIP-3)Outcomes (HIP-4)
Price during tradingcoin_to_oracle_px (external feed) + coin_to_mark_px (book)CLOB mid only -- no external oracle feed
Oracle roleContinuous price feed (Binance/Pyth) for mark/fundingSettlement only -- oracleUpdater posts final 0/1 result
Mark priceDerived from oracle + bookDerived from book only
FundingYes (EMA premium)No funding rates
LeverageUp to 50x1x only (isolated)
LiquidationYes (margin engine)None -- loss capped at premium

14.7 HIP-3 Shared Infrastructure

Outcomes share deployment and orderbook infrastructure with HIP-3 perps:

Hip3SchemaInput(3): collateralToken, oracleUpdater, OutcomeDeploy
Hip3Schema(9): full_name, oracle_updater, fee_recipient, asset_to_oi_cap,
    sub_deployers, deployer_fee_scale, last_deployer_fee_scale_change_time, +2
Hip3Limits(6): total_oi_cap2, oi_sz_cap_per_perp, max_transfer_ntl2,
    max_under_initial_margin_transfer_ntl2, daily_px_range, max_n_users_with_positions

LtHash category: Settlement (index 5 of 11 L1 categories)

15. BOLE Lending #

Protocol-controlled lending system built into HyperCore L1. Not an EVM contract. BOLE is NOT deployer-configurable -- pool parameters (reserves, rate limits, ADL, backstop liquidation) are set at protocol level by validator governance via SystemBole (action 46, broadcaster-only).[24]

15.1 BolePool (19 Fields) CONFIRMED

Per-token lending pool state. Stored in locus.blp (Exchange Locus field [8]). SNAP: confirmed from ABCI state

BolePool(19) {
    dp, du, o, pmmt, e, pmv, r, p, n, b,
    bog, pmdl, pml, uobc, ubgl, ubul, bwo, mbs, u
}
// Abbreviated serde names. Maps to:
//   totalSupplied, totalBorrowed, utilization, rates,
//   reserve config, user states, backstop params, etc.

Key API state per token:
    totalSupplied        // total supplied to pool
    totalBorrowed        // total borrowed from pool
    utilization          // totalBorrowed / totalSupplied
    healthFactor         // per-user health metric
    ltv                  // loan-to-value ratio
    predictedRate        // predicted interest rate
    borrowYearlyRate     // annualized borrow rate
    interestAmount       // accrued interest
    portfolioMarginEnabled // portfolio margin flag

15.2 User Operations CONFIRMED

BoleAction(3): operation, token, amount. Wire name: borrowLend.

OperationDescription
borrowBorrow tokens from pool. Requires sufficient collateral.
supplySupply tokens to pool. Earn interest.
repayRepay borrowed tokens.
defaultLiquidatorDesignate a default liquidator for borrow positions.
optOutOpt out of lending.

15.3 Rate Curve (Aave-Style Kink Model) CONFIRMED

Interest rates follow a standard two-slope kink model, similar to Aave/Compound.

RawRateCurve {
    kink_rate: f64,          // interest rate at kink utilization point
    kink_utilization: f64,   // utilization threshold where slope changes
    base_rate: f64,          // base interest rate (at 0% utilization)
    slope1: f64,             // slope below kink (gentle)
    slope2: f64,             // slope above kink (steep)
}

Rate computation:
    if utilization <= kink_utilization:
        rate = base_rate + (utilization / kink_utilization) * slope1
    else:
        excess = (utilization - kink_utilization) / (1 - kink_utilization)
        rate = base_rate + slope1 + excess * slope2

15.4 SetBole Governance Variants (6) CONFIRMED

Protocol-level configuration via SystemBole (broadcaster-only). BIN: SetBole variants from Ghidra

VariantFieldsPurpose
Reserve9Configure reserve parameters per token
Adl2Auto-deleveraging for lending positions
BackstopLiquidatorTokenParams4Per-token backstop liquidator configuration
ResetIndex2Reset lending index (administrative)
RateLimit7Rate limiting configuration for lending operations
TestnetAction2Testnet-only operations

15.5 BOLE Liquidation Flow CONFIRMED

BOLE liquidation is triggered in begin_block effect #3 (apply_bole_liquidations). Health factor threshold: 0.8. Three liquidation modes with distinct LtHash categories.

graph TD BB["begin_block effect #3\napply_bole_liquidations"] --> HC{"healthFactor below 0.8?"} HC -->|No| SAFE["No action"] HC -->|Yes| MODE{"Liquidation mode"} MODE -->|Standard| MKT["BoleMarketLiquidation\nOrdinary market liquidation"] MODE -->|Backstop| BST["BoleBackstopLiquidation\nBackstop liquidator takes position"] MODE -->|Partial| PRT["BolePartialLiquidation\nPartial reduction, cooldown enforced"] MKT --> LT["LtHash updated"] BST --> LT PRT --> LT style BB fill:#fb923c,stroke:#333,color:#fff style MKT fill:#f87171,stroke:#333,color:#fff style BST fill:#f87171,stroke:#333,color:#fff style PRT fill:#fbbf24,stroke:#333,color:#000
BOLE health computation:
    healthFactor = supplied_value / borrowed_value
    Liquidation trigger: healthFactor < 0.8

Order type: borrowLendLiquidation (display: "Borrow Liquidation")
Cooldown: partial_liquidation_cooldown = 30.0 seconds

Error messages:
    "Insufficient collateral for operation"
    "Insufficient balance"
    "Exceeded cap for asset"
    "Only supplying is enabled"
    "Too many operations"
    "borrow_cap > supply_cap"

15.6 Hash Accumulator Naming CONFIRMED

BOLE state is tracked in per-clearinghouse hash accumulators following the naming pattern from Section 10.6.

AllBoleTH3      -- all BOLE state for HIP-3 clearinghouse
borrowLeH3      -- borrow ledger entries, HIP-3

LtHash categories for BOLE liquidation events:
    BoleMarketLiquidation    (index 8 of 11 L1 categories)
    BoleBackstopLiquidation  (index 9, paired with [9,10])
    BolePartialLiquidation   (index 10, paired with [9,10])

Exchange field: reserve_accumulators -- Vec of (token_id, accumulator) pairs
    Mainnet keys: 107, 207, 232, 255 (4 tokens with BOLE reserves)

16. Guards (16 BucketGuards) #

GuardPurpose
funding_distribute_guardHourly funding
funding_update_guardEMA updates
begin_block_logic_guardReentrancy
cancel_aggressive_orders_at_oi_cap_guardOI cap cancels
book_empty_user_states_pruning_guardState pruning
ensure_order_bucket_guardOrder validation
reset_recent_oi_bucket_guardOI reset
stakes_decay_bucket_guardStake decay
stage_reward_bucket_guardReward staging
distribute_reward_bucket_guardReward distribution
update_median_bucket_guardMedian price
prune_bucket_guardGeneral pruning
alert_bucket_guardAlert rate
partial_liquidation_cooldown~30s spacing
hip3_stale_mark_px_guardHIP-3 stale detection
status_guardAction Delayer

Volume-Gated: Sub-accounts, scheduled cancels, portfolio margin, extra agents, referral codes.

17. Validator Operations #

Hyperliquid uses a two-key model per validator: a cold validator key that holds funds, receives rewards, and manages the validator profile, and a hot signer key stored in node_config.json that signs consensus messages and bridge operations.

17.1 CStaking (23 Fields) CONFIRMED

Exchange field [10] c_staking. Full consensus staking state. SNAP: confirmed from ABCI state

CStaking(23) {
    stakes,                                // validator stakes
    allowed_validators,                    // validator allowlist
    allow_all_validators,                  // permissionless mode flag
    broadcasters,                          // whitelisted broadcasters
    validator_to_profile,                  // CValidatorProfile per validator
    validator_to_last_signer_change_time,  // signer rotation tracking
    delegations,                           // delegation state per user
    proposals,                             // governance proposals
    stakes_decay_bucket_guard,             // stake decay timing
    jailed_signers,                        // currently jailed signers
    jail_vote_tracker,                     // jail vote accumulation
    jail_until,                            // jail expiry per validator
    signer_to_last_manual_unjail_time,     // unjail cooldown tracking
    native_token_reserve,                  // HYPE reserve for rewards
    stage_reward_bucket_guard,             // reward staging timing
    validator_to_staged_rewards,           // staged (pending) rewards
    distribute_reward_bucket_guard,        // reward distribution timing
    user_states,                           // per-user staking state
    pending_withdrawals,                   // pending stake withdrawals
    self_delegation_requirement,           // minimum self-delegation
    disabled_validators,                   // disabled validator set
    disabled_node_ips,                     // disabled node IPs
    validator_to_state,                    // per-validator state tracking
}

17.2 CValidatorProfile and CValidatorAction CONFIRMED

CValidatorProfile (6 Fields)

CValidatorProfile {
    node_ip: String,                // validator node IP address
    delegations_disabled: bool,     // whether delegations are accepted
    commission_bps: u32,            // commission in basis points
    signer: Address,                // hot signer key address
    register_time: u64,             // registration timestamp
    last_signer_change_time: u64,   // last signer rotation time
}

CValidatorAction (16 Variants) CONFIRMED

Requires cold validator key. BIN: variant index 0 <= i < 16

ActionPurpose
Register (3 fields)Register as validator (profile, signer, initial stake)
ChangeProfile (7 fields)Update node_ip, delegations_disabled, commission_bps, signer, etc.
registerAssetRegister new tradeable asset
registerAsset2Extended asset registration
setOracleOracle management
setFeeRecipientFee destination configuration
setFeeScaleFee scale adjustment
insertMarginTableAdd margin table
setMarginTableIdsAssign margin tables to assets
setOpenInterestCapsSet OI caps per asset
setFundingMultipliersPer-asset funding multipliers
setFundingInterestRatesPer-asset funding interest rates
disableDexDisable a DEX instance
setPerpAnnotationSet perp annotation metadata
setMarginModesSet margin modes per asset
setGrowthModesSet growth modes per asset

CSignerAction (3 Variants)

Requires hot signer key. BIN: CSignerAction dispatch at VA 0x3352310

ActionPurpose
unjailSelfSelf-unjail after cooldown period
jailSelfVoluntary jail before shutdown/maintenance
jailSelfIsolatedJail in isolated mode

17.3 Epoch Lifecycle CONFIRMED

Validator set transitions are epoch-based. The active set is determined by total delegation at epoch boundaries.

Staking(6) {
    epoch_states,             // historical epoch state snapshots
    active_epoch,             // currently active epoch index
    cur_epoch_state,          // current epoch validator set
    cur_epoch,                // current epoch number
    epoch_duration_seconds,   // epoch length (e.g. ~90 min for 100K rounds)
    allowed_validators,       // validator whitelist
}

EpochTracker {
    epoch_states,             // Vec of epoch snapshots
    active_epoch,             // active epoch index
    cur_epoch_state,          // current state
    cur_epoch,                // epoch counter
    epoch_duration_seconds,   // duration
}

Epoch transition:
    1. ForceIncreaseEpoch action triggers epoch boundary
    2. Rank validators by total delegation (self + delegated)
    3. Top N validators become the active set (24 mainnet, 50 testnet)
    4. New proposer rotation computed from new active set
    5. Bridge validator set updated (same signer keys)
    6. validator_power_updates applied to consensus

17.4 Delegation Flow CONFIRMED

Users delegate HYPE to validators via tokenDelegate. Rewards are distributed per epoch based on commission rates.

Delegation flow:
    1. User submits tokenDelegate action (validator, amount)
    2. Delegation recorded in c_staking.delegations
    3. Takes effect at next epoch boundary
    4. Rewards staged: stage_reward_bucket_guard fires periodically
    5. Rewards distributed: distribute_reward_bucket_guard fires
    6. User claims via claimRewards action

Reward distribution:
    validator_reward = block_reward * validator_stake_fraction
    validator_commission = validator_reward * commission_bps / 10000
    delegator_share = (validator_reward - commission) * delegator_fraction

Constraints:
    self_delegation_requirement enforced (minimum self-stake)
    pending_withdrawals tracked for unbonding period
    stakes_decay_bucket_guard handles stake decay over time

17.5 Jailing CONFIRMED

Validators are jailed for poor performance (latency) or manual self-jailing for maintenance.

graph TD R["Register validator\nCValidatorAction::Register"] --> A["Active in epoch\ntop N by delegation"] A --> P["Proposing blocks\nRoundRobinTtl rotation"] P --> HB["Heartbeat monitoring\nvalidator_latency_ema"] HB --> JC{"latency_ema above\njail threshold?"} JC -->|No| P JC -->|Yes| JV["JailVoteTimer fires\nConstruct VoteJailBundle"] JV --> JQ{"2/3+ validators\nagree to jail?"} JQ -->|No| P JQ -->|Yes| J["JAILED\njailed_signers, jail_until"] J --> UJ{"Unjail conditions met?\ncooldown elapsed, active epoch"} UJ -->|Yes| US["CSignerAction::unjailSelf"] US --> A UJ -->|No| J A --> SJ["CSignerAction::jailSelf\nvoluntary maintenance"] SJ --> J style J fill:#f87171,stroke:#333,color:#fff style A fill:#34d399,stroke:#333,color:#000
Jailing fields:
    validator_latency_ema            // EMA of response latency
    latency_ema_jail_threshold       // threshold for jailing
    validators_missing_heartbeat     // set of non-responsive validators
    disconnected_validators          // detected network partitions
    jailed_signers                   // currently jailed signer set
    jail_until                       // jail expiry timestamp per validator
    signer_to_last_manual_unjail_time // unjail cooldown tracking
    jail_vote_tracker                // vote accumulation for jailing

Unjail requirements:
    1. Jail cooldown period must have elapsed (jail_until)
    2. Validator must be in active epoch set
    3. Submit CSignerAction::unjailSelf with hot signer key
    4. "Signer invalid or inactive for current epoch" if not in active set

17.6 RPC Backfill (9 Validation Checks)

#CheckError
1QC roundClientBlockQcRound
2QC hashClientBlockQcHash
3Tx validityClientBlockTx
4tx_hashes matchClientBlockTxHashes
5Timestamp monotonicClientBlockTime
6Commit proofClientBlockMissingCommitProof
7Child QCCommitProofChildQc
8Grandchild QCCommitProofGrandchildQc
9Consecutive roundsCommitProofConsecutive

18. Key Function Addresses #

FunctionVA
Main Exchange dispatcher0x0272a320
RespHash dispatch0x0205a300
compute_resps_hash (testnet)0x2355860
Blake3 hasher write0x04e03010
SSE2 paddw0x04e05786
LtHash insert0x04e0ccf0
MsgConcise serializer0x42b7e50
OutMsgConcise serializer0x42b87e0
ConciseMid serializer0x42b92f0
HeartbeatSnapshot ser/de0x438fcc0 / 0x43b9a10
ConciseLtHash ser/de0x43db480 / 0x4387640
bincode-fork serializer0x474f3f0
send_to_destination0x43bf670
BTreeMap peer routing0x409c0e0
tcp_bytes0x1cc9d00
Greeting builder0x2767ee0
Peer rejection0x75fe5e
CSignerAction dispatch0x3352310
Signer epoch check0x3355790
Validator lookup0x2eb8fb0

19. Binary Structure #

Source module map from testnet binary 331bef9b (2026-04-03). CONFIRMED from panic paths and debug strings in the stripped ELF.

PropertyValue
BinaryTestnet build 2026-04-03
Size87 MB (stripped ELF)
SHA-2561a99c892...
Commit331bef9b
Build date2026-04-03

19.1 Source Module Map

/home/ubuntu/hl/code_Testnet/
+-- base/src/      -- Utilities (50+ files)
|   +-- types.rs, config.rs, serialize.rs, ...
+-- db/src/        -- RocksDB backend
|   +-- db.rs, compaction.rs
+-- evm_rpc/src/   -- EVM JSON-RPC
|   +-- server.rs, handlers.rs
+-- l1/src/        -- Core L1 logic
|   +-- abci/engine.rs, state.rs
|   +-- book/book/impl_insert_order.rs
|   +-- clearinghouse/
|   +-- exchange/impl_trading.rs, end_block.rs, exchange.rs, impl_outcome.rs
|   +-- evm/hyper_evm.rs, transactor.rs, core_writer.rs
|   +-- staking.rs, vault/, fees/compute.rs, bole/user_state.rs
+-- node/src/      -- Orchestration + Consensus
|   +-- consensus/state.rs, server.rs, types.rs, timer.rs, mempool.rs
|   +-- client_block.rs, heartbeat_tracker.rs, rpc.rs, network.rs

Compared to mainnet build 105cb1dc (40+ files in base/), the testnet binary shows 50+ files in base/ and additional modules in the evm/ subtree.

Changelog & Corrections #

Reverse engineering is iterative. This section documents wrong assumptions, corrections, and when findings were updated. Entries are newest-first.

2026-04-05

TopicWasNowHow discovered
G-family success shape Success and error both treated as the same G-style family Success hashes as {status:"success"}; the 3-field G payload is error-only RE closure in re_g_success_format.json plus local source verification
Fill hash payload Public fill/trade summary treated API wrapper fields as if they were the hashed payload Hashed fills use a separate 18-field payload; coin and feeToken are API wrapper fields re_fill_details.json + re_ledger_serialization.json
Port 4003 signed greeting body Tiny fixed body model Variable-sized bincode-fork content with validator addr, round, variant flag, optional ABCI extra, counters/hash material, sorted heartbeat map, trailing mempool varint re_greeting_exact.json from captured sign-input blobs + Ghidra

2026-04-04

TopicWasNowHow discovered
Signing formula keccak256(domain + content) keccak256(domain + 0x00 + content) — NULL byte separator GDB live capture of keccak256 input at VA 0x4a9442f
Signing content encoding Assumed msgpack (file is rmp_signable.rs) Content is bincode-encoded GDB capture: 1601-byte input is bincode, not msgpack
App hash format SHA-256(all_14_combined) — single 32-byte digest first_16(SHA256(L1)) || first_16(SHA256(EVM)) — two halves Node log at h=536290000: L1 half matched, EVM half differed
Port 4001 greeting 6-byte body, u32 LE variant index, variant 0 = send_abci 7-8 byte body, u32 BE variant index, testnet=3, mainnet=2 Live peer connection: 8-byte greeting gets response on testnet
Port 4001 framing [u32 BE len][body] [u32 BE len][u8 kind][body] — includes kind byte Wire trace: kind=0 for greeting, kind=1 for data frames
Book order price field p field on order = limit price p = linked-list prev-pointer. Price is at c.l[0] Orders loading with 100-6000x wrong prices, traced to p vs c.l
Bridge2 oaw type serde_json::Value (opaque) bool Binary deserializer helper confirmed read_bool call
BSS accumulators Assumed to be live running accumulators Stale heartbeat cache — never matches committed hashes Multiple BSS captures never matched any VoteAppHash quorum value
szDecimals fallback Default 0 when metadata absent Default 5 (matches rest of bootstrap's unknown-asset path) Price scaling divergence on assets missing from metadata map
Heartbeat concise_lt_hashes Contains all 14 category accumulators (L1 + EVM) EVM only (accounts, contracts, storage). L1 rebuilt from state. Ghidra trace of heartbeat serializer path, confirmed 3 fields only

2026-04-03

TopicWasNowHow discovered
Hash response serialization rmp_serde::to_vec (compact/positional mode) rmp_serde::to_vec_named (map mode, camelCase keys) Binary RE of hash serializer functions at VA 0x427xxxx
Order fill hash shape Flat 9-field struct with null fields Externally-tagged enum: {"filled":{"totalSz":...}} Ghidra decompile of SerializerJ at VA 0x4280c90
L1 hash categories 12 categories assumed 11 confirmed: CValidator, CSigner, Na, LiquidatedCross, LiquidatedIsolated, Settlement, NetChildVaultPositions, SpotDustConversion, BoleMarketLiquidation, BoleBackstopLiquidation, BolePartialLiquidation Binary rodata at 0x65fb61, consecutive enum strings
Bridge2 field baloaw Single combined field Three separate fields: bal, last_pruned_deposit_block_number, oaw Binary serializer/deserializer helper functions for Bridge2

2026-04-02

TopicWasNowHow discovered
Bridge signing keys Separate EOA keys for bridge operations Same key as consensus — bridge signing = consensus signing Binary string trace: same signer struct used in bridge + consensus paths
Gossip peer verification Assumed open connection Server-side connection_checks: IP must be known validator/sentry Connection timeout analysis + binary string "not validator or sentry"

References #

  1. OBS Live mainnet: peak 7,746 actions/second, 2,451 in one 70ms block.
  2. BIN Crate versions from path strings in rodata. Binary: 81MB ELF, build 105cb1dc.
  3. BIN "CertifiedTwoChainCommit" in rodata. Domain separator at VA 0x76db94.
  4. BIN Consensus errors at VA 0x6600fa. Field names from serde at VA 0x660467.
  5. BIN No capacity string. "dropping txs/blocks" confirmed. Source: mempool.rs.
  6. BIN Pipeline at offset 0x539f8a.
  7. BIN begin_block_logic_guard. 5-step order from end_block.rs.
  8. BIN variant index 0..90. Dispatcher at VA 0x0272a320.
  9. RE Testnet: RestingOrder 12 fields, Fill 21 fields, 92 action variants.
  10. SNAP Exchange state at h=535280000. 57 keys. 2.1M users, $3.01B.
  11. BIN Cancel reasons at 0x64f964, index 0..10. Rejects at adjacent offsets.
  12. API Fee tiers from app.hyperliquid.xyz/fees.
  13. API fundingHistory 3600s apart. BTC 0.0000125 in 314/500 samples.
  14. BIN blake3 at 0x04e03010, paddw at 0x04e05786, SHA-256 final.
  15. BIN 11 categories at 0x65fb61. RespHash at 0x205a300. 14 accumulators.
  16. BIN compute_resps_hash at 0x2355860, table at 0x3aa3f8.
  17. SNAP EVM sizes from lt_hashes.json: 92B accounts, 84B storage.
  18. BIN Wire: bswap at 0x1cc9f59, kind at 0x1cc9f5b.
  19. BIN MsgConcise table 0x65f418, OutMsgConcise 0x65f458. Type: RpcUpdate.
  20. BIN Mid table at 0x65f47c. 5 LEA: "in", "execution state", "out", "status", "round advance".
  21. BIN hash_concise hex loop at 0x449e0f0, 32 bytes. ValidatorSetSnapshot 2 fields at 0x42b9b80.
  22. RE ModifyBroadcaster no timelock. invalidateWithdrawals confirmed.
  23. RE impl_outcome.rs confirmed. OutcomeDeploy(8), UserOutcomeAction(4).
  24. BIN BolePool(19), SetBole variants, BoleAction(3). Source: bole/user_state.rs.
  25. BIN Testnet binary 331bef9b (2026-04-03, 87MB). 97 action variants, 9 BeginBlock steps.
  26. BIN Serde struct chain at .rodata 0x543428 -- complete ABCI state serialization layout.
  27. BIN FeeSchedule(9) and FeeTracker(10) field layouts from struct chain.
  28. BIN CoreWriter scan loop, ActionDelayer silent reject at capacity, DelayedActionSerde(6).
  29. BIN 7 new action variants: GossipPriorityBidAction, ReserveRequestWeightAction, SystemAlignedQuoteSupplyDeltaAction, DeployerSendToEvmForFrozenUserAction, SystemUsdClassTransferAction, FinalizeEvmContractAction, SubAccountSpotTransferAction.
  30. BIN SetGlobalAction 4th field confirmed as nativePx (HYPE price). Oracle(4) struct fields confirmed. Oracle history ring buffer (100 entries) at Exchange field [55] oh.
  31. RE Bridge2(10) full field layout from ABCI state. Bridge signing = consensus signing confirmed. Deposit/withdrawal flows from binary action handlers.
  32. BIN OutcomeTracker(11), OutcomeDeploy(8 variants), UserOutcomeAction(4 variants). Source: l1/src/exchange/impl_outcome.rs.
  33. BIN CStaking(23) full field layout. CValidatorProfile(6), CValidatorAction(16 variants). Staking(6) epoch lifecycle. Jailing: latency_ema_jail, VoteJailBundle.
  34. BIN Hash accumulator naming: AllBoleTH3, borrowLeH3, funding_H3, 1emasH. Per-clearinghouse partitioning confirmed from binary strings.
  35. BIN RawRateCurve kink model fields: kink_rate, kink_utilization. BOLE health factor threshold 0.8. apply_bole_liquidations in begin_block effect #3.

The Hypurrliquid Paper · lastdotnet/hyperliquid-rust · 2026-04-03
Derived from reverse engineering. Not official Hyperliquid documentation.