Research / Chain files / Hyperliquid

Hyperliquid: who can change what the oracle reads

16 targets on Hyperliquid are tracked and scored by an oracle on HyperEVM testnet: the HyperCore validator set, the HIP-3 perpetual dexes that anyone can deploy, the staking managers on HyperEVM and the legacy bridge. Here an authority is often a HyperCore identity that is also, or is not, an EVM contract.

What a track judge can check in two minutes

Three calls on the Hyperliquid (HyperEVM) oracle, read at the latest block. They need a public RPC and cast (Foundry) and nothing from us. The public RPC of this chain keeps no history for that block, so the values below are the ones the Watch read at block 66993098: they change when the oracle is re-pushed.

RPC=https://998.rpc.thirdweb.com
ORACLE=0x50840a7667baEa9D05ad4ae3dCeb384724b58720
TARGET=0x88806a71d74ad0a510b350545c9ae490912f0888   # HIP-3 dex xyz (trade[XYZ])

# 1. how many contracts this oracle tracks
cast call $ORACLE "trackedTargetsCount()(uint256)" --rpc-url $RPC

# 2. its score, five sub-scores then the composite, then lastUpdated and the method hash
cast call $ORACLE "getScore(address)((uint8,uint8,uint8,uint8,uint8,uint8,uint64,bytes32))" $TARGET --rpc-url $RPC

# 3. is that score older than maxStaleness
cast call $ORACLE "isStale(address)(bool)" $TARGET --rpc-url $RPC

Expected

1 -> 16
2 -> (10, 15, 0, 4, 100, 9, 1791783968, 0x36452ea42a84016f691a665855cc3482c3e8bb4d87155901b491b293457a4004)   admin, multisig, timelock, price feed, shared signers, composite
3 -> false

3 findings, each with its replay

1. The largest HIP-3 dex is deployed by a plain key with no code, while two others are deployed by upgradeable EVM proxies

Each HIP-3 dex has a deployer address on HyperCore. For the largest one, xyz, that address has no code on HyperEVM: it is a plain key, and it is a tracked target with a low score. For the dexes para and mkts (Markets by Kinetiq) the deployer address has real EVM code and is an EIP-1967 proxy, so its authority is a contract. The Kinetiq one was read against its verified source: the HyperCore calls it can make are staking and trading actions open to any account, not the dex-admin actions, so it does not hand a second root-control path to the dex. The note records two corrections of its own earlier, stronger wording.

Replay it (public data, no key)
# the deployers of the dexes, from Hyperliquid's public API
curl -s -X POST https://api.hyperliquid.xyz/info -H 'content-type: application/json' -d '{"type":"perpDexs"}' | python3 -c "import json,sys; [print(x['name'], x['deployer']) for x in json.load(sys.stdin) if x and x['name'] in ('xyz','para','mkts')]"
# -> xyz 0x88806a71d74ad0a510b350545c9ae490912f0888, para 0x8888888c43cbb7e1c4132542e46831bffd866ed3, mkts 0x71f0019cc7fa79e4f42587fb7b9a817d8d2429ec
# xyz: no code. mkts: code, and a non-zero EIP-1967 implementation slot
HV=https://rpc.hyperliquid.xyz/evm
cast code 0x88806a71d74ad0a510b350545c9ae490912f0888 --rpc-url $HV
cast code 0x71f0019cc7fa79e4f42587fb7b9a817d8d2429ec --rpc-url $HV | wc -c
cast storage 0x71f0019cc7fa79e4f42587fb7b9a817d8d2429ec 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc --rpc-url $HV
# -> 0x, then a long code (about 1,589 characters), then a non-zero word

Notes: finding_2026-09-17-hyperliquid-hip3-evm-proxy-authority.md · finding_2026-09-26-untracked-hip3-dexes-are-empty.md

2. Four HIP-3 dexes the oracle does not track have every asset delisted: a coverage lead that measured as empty

A routine listed four HIP-3 dexes (flx, hyna, cash, abcd) that the oracle does not track. Read live, every asset of each one is delisted and its open interest is zero, while the tracked dexes hold the open interest of the platform. The lead was closed without a new target, and the note says so. It also records that one key posts prices for two dexes, io (tracked) and flx (delisted).

Replay it (public data, no key)
# for each untracked dex: number of assets, delisted assets, open interest in dollars
for d in flx hyna cash abcd; do curl -s -X POST https://api.hyperliquid.xyz/info -H 'content-type: application/json' -d "{\"type\":\"metaAndAssetCtxs\",\"dex\":\"$d\"}" | python3 -c "import json,sys; m,c=json.load(sys.stdin); u=m['universe']; print('$d', len(u), sum(1 for a in u if a.get('isDelisted')), round(sum(float(x['openInterest'])*float(x['markPx']) for x in c)))"; done
# -> flx 16 16 0, hyna 25 25 0, cash 17 17 0, abcd 1 1 0 (as read on 14 October 2026)
# the shared price-updater key of io and flx
curl -s -X POST https://api.hyperliquid.xyz/info -H 'content-type: application/json' -d '{"type":"perpDexs"}' | python3 -c "import json,sys; [print(x['name'], x['oracleUpdater']) for x in json.load(sys.stdin) if x and x['name'] in ('io','flx')]"
# -> io and flx print the same address (0x94757f8dcb4bf73b850195660e959d1105cfedd5)

Notes: finding_2026-09-26-untracked-hip3-dexes-are-empty.md

3. Two Kinetiq staking managers carried the same product name; the older one is the kmHYPE manager, and the repository corrected its own label

Target 6 was published as the kHYPE staking manager, while a later target, 9, carried the same name at another address. Read live, they are two separate pools: target 9 is wired to the oracle manager of kHYPE, while target 6 exposes a reserve token that names itself as the accounting layer of kmHYPE, and the two accountants report different exchange rates. Target 6 was relabelled kmHYPE. The note was written after the mismatch was flagged, not guessed.

Replay it (public data, no key)
# the older manager points to a reserve token that names itself as kmHYPE accounting
HV=https://rpc.hyperliquid.xyz/evm
RES=$(cast call 0x71f0019cc7fa79e4f42587fb7b9a817d8d2429ec "kHYPE()(address)" --rpc-url $HV)
cast call $RES "name()(string)" --rpc-url $HV
cast call $RES "symbol()(string)" --rpc-url $HV
# -> "Reserve LST for kmHYPE accounting", then "kmGHOST"
# the newer manager is wired to the oracle manager that the repository lists for kHYPE
cast call 0x393D0B87Ed38fc779FD9611144aE649BA6082109 "oracleManager()(address)" --rpc-url $HV
# -> 0x192826e470bd65FDC2CB472eDd834D096233049b

Notes: finding_2026-09-19-hyperliquid-khype-kmhype-identity.md

Targets

16 targets are tracked on Hyperliquid, read from mainnet and scored by the oracle on Hyperliquid (HyperEVM). Bands of the composite score:

critical10
weak3
moderate2
decent1

Up to 12 targets, ordered by value where known, then by lowest score. Each name opens the contract page.

TargetCompositeBand
Hyperliquid L1 (HyperCore validator set)26weak
Unit UBTC, UETH and USOL treasuries9critical
Unit UBTC, UETH and USOL treasuries9critical
Unit UBTC, UETH and USOL treasuries9critical
Kinetiq kHYPE StakingManager (HyperEVM)4critical
Legacy USDC bridge (Bridge2, Arbitrum One)48moderate
HyperLend Pooled (Aave v3 fork)61decent
Hyperliquidity Provider (HLP) vault9critical
Kinetiq HIP3StakingManager (kmHYPE)4critical
Ventuals vHYPE staking (HyperEVM)31weak
para StakingVault (HyperEVM)4critical
HIP-3 dex para (Paragon)5critical

What is not read

Read from the public repository and the Watch at build, 2026-10-15 21:09 UTC. A finding is a dated reading with its replay, not an audit and not investment advice. All chain files · Dashboard.