Skip to content

Precompile reference

Expert

The 21 read precompiles at 0x800 to 0x814 that let a HyperEVM contract read HyperCore state: address, input, output and scaling for each.

A read precompile is a fixed HyperEVM address that answers with HyperCore state instead of running contract code. Look one up here; patterns and pitfalls are on reading HyperCore.

  • Calldata is raw abi.encode(args) with no function selector, which would be read as the first argument. 0x809 takes empty calldata.
  • Return data decodes straight into the output tuple.
  • Values match the latest HyperCore state when the EVM block is built.
  • Gas: 2000 + 65 * (input_len + output_len). An invalid input (unknown asset or vault) errors and consumes all forwarded gas: cap it per call.
(bool ok, bytes memory out) = address(0x807).staticcall{gas: 20_000}(abi.encode(uint32(3)));
uint64 raw = abi.decode(out, (uint64)); // divide by 10^(6 - szDecimals) for a perp
Address Name in L1Read.sol Input Output Scaling and notes
0x800 position address user, uint16 perp (int64 szi, uint64 entryNtl, int64 isolatedRawUsd, uint32 leverage, bool isIsolated) superseded by 0x813 for indices above uint16
0x801 spotBalance address user, uint64 token (uint64 total, uint64 hold, uint64 entryNtl) token also accepts an outcome asset id 100000000 + 10 * outcome + side
0x802 userVaultEquity address user, address vault (uint64 equity, uint64 lockedUntilTimestamp)
0x803 withdrawable address user uint64 withdrawable
0x804 delegations address user (address validator, uint64 amount, uint64 lockedUntilTimestamp)[] per-validator delegations only
0x805 delegatorSummary address user (uint64 delegated, uint64 undelegated, uint64 totalPendingWithdrawal, uint64 nPendingWithdrawals) HYPE wei 1e8; the deployer stake check reads delegated + undelegated here
0x806 markPx uint32 index (perp) uint64 divide by 10^(6 - szDecimals)
0x807 oraclePx uint32 index (perp) uint64 divide by 10^(6 - szDecimals)
0x808 spotPx uint32 index (spot pair) uint64 divide by 10^(8 - base szDecimals); also accepts an outcome asset id
0x809 l1BlockNumber none (empty calldata) uint64 the HyperCore block number
0x80a perpAssetInfo uint32 perp (string coin, uint32 marginTableId, uint8 szDecimals, uint8 maxLeverage, bool onlyIsolated)
0x80b spotInfo uint32 spot (string name, uint64[2] tokens) tokens is [base, quote] token indices
0x80c tokenInfo uint32 token (string name, uint64[] spots, uint64 deployerTradingFeeShare, address deployer, address evmContract, uint8 szDecimals, uint8 weiDecimals, int8 evmExtraWeiDecimals) evmContract is the linked ERC20
0x80d tokenSupply uint32 token (uint64 maxSupply, uint64 totalSupply, uint64 circulatingSupply, uint64 futureEmissions, (address user, uint64 balance)[] nonCirculatingUserBalances)
0x80e bbo uint32 asset (uint64 bid, uint64 ask) a perp index, or 10000 + spot pair index
0x80f accountMarginSummary uint32 perp_dex_index, address user (int64 accountValue, uint64 marginUsed, uint64 ntlPos, int64 rawUsd) per perp dex
0x810 coreUserExists address user bool exists whether the address is a HyperCore account
0x811 borrowLendUserState address user, uint64 token ((uint64 basis, uint64 value) borrow, (uint64 basis, uint64 value) supply) reverts when the account has no record for the token
0x812 borrowLendReserveState uint64 token (not uint32) (uint64 borrowYearlyRateBps, uint64 supplyYearlyRateBps, uint64 balance, uint64 utilizationBps, uint64 oraclePx, uint64 ltvBps, uint64 totalSupplied, uint64 totalBorrowed) rates in bps; USDC amounts 1e8
0x813 position2 address user, uint32 perp same tuple as 0x800 the widened sibling of 0x800
0x814 outcomeStatus uint32 outcome (uint8 status, uint64 settledValue, uint32 question) see below

0x815 to 0x8ff are unassigned on both networks (measured 2026-08-17): they return empty 0x with success, where a live one returns data or PrecompileError. New versions arrive as new sibling addresses, as 0x813 did.

status Meaning settledValue
0 never existed none
1 active none
2 settled readable; 1e8 = 1.0
3 settled and pruned gone for good

question is type(uint32).max (4294967295) for a standalone outcome or an unavailable question. Status 3 means pruned: the settled value is then only in the info request settledOutcome.

  • Supply APY is borrow APY * utilisation * 0.9, reproducing the API to 9 decimal places.
  • balance is not totalSupplied - totalBorrowed: the measured gap, a retained buffer, was about 46.57 USDC. Never price shares off balance.
  • In the matching info request, HYPE (token 150) and UBTC (token 197) report a supply rate of 0: only quote assets pay.
  • There is no rate history: sample 0x812 yourself.
Behaviour Detail Basis
No historical state Precompiles answer only at latest. Any explicit block number, even the current head, fails with PrecompileOutOfGas on archive nodes measured
Stale by execution A read reflects state when the EVM block was built; a CoreWriter action sent in the same transaction executes later docs and measured
Bad input burns everything PrecompileOutOfGas(50000000) observed on an unsupported input measured
0x811 reverts on no record an unguarded totalAssets() bricks a new vault until its first supply measured
Stake check uses 0x805 undelegated stake counts toward a deployer requirement; 0x804 alone misses it measured
No abstraction mode no precompile exposes an account’s abstraction mode measured

For why a read is stale by the time an action lands, see Execution order and timing. The write side is the CoreWriter action reference.