CoreWriter action reference
Every CoreWriter action id a HyperEVM contract can send to HyperCore, with its field tuple, units and measured behaviour, including the undocumented action 14.
CoreWriter is a HyperEVM system contract that turns a log into a HyperCore action taken by the calling address. Use this page to encode an action; why actions are not atomic, and how to confirm them, is on CoreWriter.
The contract
Section titled “The contract”| Item | Value |
|---|---|
| Address | 0x3333333333333333333333333333333333333333 |
| Method | sendRawAction(bytes), selector 0x17938e13 |
| Event | RawAction(address indexed user, bytes data); user is topics[1] |
| Gas | burns about 25,000 before emitting the log; a basic call uses about 47,000; one measured call used 47,889 |
| Acts for | msg.sender. An agent key calling it acts for itself, not for its master |
| Preconditions | the sender must already be a HyperCore account (activated) before the EVM block is built; multi-sig HyperCore users cannot use it |
| On failure | never reverts. The EVM transaction succeeds whatever HyperCore does |
Payload encoding
Section titled “Payload encoding”byte 0 0x01 encoding version (only 1 exists)bytes 1..3 action id, big-endian uint24bytes 4.. abi.encode(field tuple) no function selectorbytes memory data = abi.encodePacked( uint8(1), uint24(15), // version 1, action 15 abi.encode(uint8(0), uint64(0), uint64(401492350600)) // supply 4,014.923506 USDC);ICoreWriter(0x3333333333333333333333333333333333333333).sendRawAction(data);Mainnet golden vectors: supplying 4,014.923506 USDC is 0x0100000f + abi.encode(0, 0, 0x5d7acf1688); withdrawing 10 USDC is 0x0100000f + abi.encode(1, 0, 0x3b9aca00).
Actions
Section titled “Actions”| Id | Action | Field tuple | Units and notes |
|---|---|---|---|
| 1 | Limit order | (uint32 asset, bool isBuy, uint64 limitPx, uint64 sz, bool reduceOnly, uint8 tif, uint128 cloid) |
limitPx and sz are 1e8 times the human value. TIF 1 Alo, 2 Gtc, 3 Ioc; there is no FrontendMarket, so a market order is an Ioc with a bounded limitPx. cloid 0 means none |
| 2 | Vault transfer | (address vault, bool isDeposit, uint64 usd) |
the only measured delayed path, about 4 s |
| 3 | Token delegate | (address validator, uint64 wei, bool isUndelegate) |
HYPE wei, 1e8 |
| 4 | Staking deposit | (uint64 wei) |
spot to staking balance; HYPE wei |
| 5 | Staking withdraw | (uint64 wei) |
staking to spot, through the 7-day unstaking queue; HYPE wei |
| 6 | Spot send | (address destination, uint64 token, uint64 wei) |
HyperCore wei of token |
| 7 | USD class transfer | (uint64 ntl, bool toPerp) |
moves USDC between spot and perp balances |
| 8 | Finalize EVM contract | (uint64 token, uint8 variant, uint64 createNonce) |
variant 1 Create, 2 FirstStorageSlot, 3 CustomStorageSlot; only Create reads createNonce |
| 9 | Add API wallet | (address wallet, string name) |
an empty name makes it the main (unnamed) agent |
| 10 | Cancel by oid | (uint32 asset, uint64 oid) |
|
| 11 | Cancel by cloid | (uint32 asset, uint128 cloid) |
|
| 12 | Approve builder fee | (uint64 maxFeeRate, address builder) |
decibps: 10 = 0.01% |
| 13 | Send asset | (address destination, address subAccount, uint32 srcDex, uint32 dstDex, uint64 token, uint64 wei) |
type(uint32).max selects spot; a non-zero subAccount sends from that sub-account |
| 14 | Undocumented | unknown | exists on mainnet; see below |
| 15 | Borrow and lend | (uint8 op, uint64 token, uint64 wei) |
op 0 supply, 1 withdraw; wei = 0 means the maximum; HyperCore wei, USDC 1e8. Rejected in portfolio margin mode |
| 16 | Set abstraction | (address user, uint8 abstraction) |
1 disabled (Standard), 2 unifiedAccount, 3 portfolioMargin. The docs allow the master user or a sub-account |
| 17 | Outcome operation | (uint8 op, uint32 question, uint32 outcome, uint64 wei) |
op 0 split, 1 merge, 2 merge question, 3 negate. wei is 1e8 per contract, a whole number of contracts; wei = 0 merges the maximum. Unused fields must be zero |
Which fields each action 17 op reads:
| Op | Name | Reads question |
Reads outcome |
|---|---|---|---|
| 0 | SplitOutcome | no, must be 0 | yes |
| 1 | MergeOutcome | no, must be 0 | yes |
| 2 | MergeQuestion | yes | no, must be 0 |
| 3 | NegateOutcome | yes | yes |
Test vector: splitting one contract of outcome 1121 is (0, 0, 1121, 100000000).
Action 14: exists, undocumented
Section titled “Action 14: exists, undocumented”The docs list no action 14, but it appears on mainnet: 25 sightings in 3 million blocks. One decoded example: sender 0x111111a1...111111, words [360, 10752298000000, 0]. 360 is the USDH token index, and on 2026-11-03 spotMeta listed that sender as the HyperEVM contract linked to USDH, so it is probably USDH related (inference only). Its semantics are unknown. Do not send it.
Two open questions
Section titled “Two open questions”- Action 15 ops 2 and 3. One tool routes op 2 as borrow and op 3 as repay; measurements cover only supply (0) and withdraw (1). Unresolved.
- Action 17 on mainnet. Same-block execution is proven on testnet (n=6), inferred for mainnet.
Measured timing
Section titled “Measured timing”Delay from the EVM block timestamp to HyperCore execution:
| Action | Network | n | Delay |
|---|---|---|---|
| 2 vault transfer | mainnet | 6 | 4.05 to 4.10 s |
| 1 order, fills matched by cloid | mainnet | 52 | 0.35 to 0.51 s, mean 0.412 s |
| 6, 7 and 13 | mainnet | 6 each | 0.006 to 0.46 s |
| 17 split and merge | testnet | 6 | same block, 0.01 to 0.68 s |
| 1 resting order | testnet | 3 | same block, 0.75 to 0.82 s |
Mainnet usage
Section titled “Mainnet usage”Action ids emitted over 3 million mainnet blocks:
| Id | Count |
|---|---|
| 13 send asset | 249,116 |
| 1 limit order | 9,309 |
| 6 spot send | 6,403 |
| 16 set abstraction | 203 |
| 14 undocumented | 25 |
| 15 borrow and lend | 13 |
| 17 outcome operation | 4 |
Failure modes
Section titled “Failure modes”| Symptom | Cause |
|---|---|
| EVM transaction succeeds, nothing happens on HyperCore | every refusal is silent; read the result from a precompile in a later block or from the explorer’s userDetails, whose error field carries the reason |
| Action 17 silently dropped | a non-zero unused field |
| Action rejected for a new contract | the contract was not a HyperCore account before the EVM block was built; funding it in the same block is too late |
| Action 15 refused | the account is in portfolio margin mode (Manual borrow/lend not allowed with portfolio margin) |
| HyperCore to HyperEVM send refused | the amount is not a multiple of 10^abs(evmExtraWeiDecimals) (Invalid number of decimals), or the balance cannot cover the crossing gas |
| Multi-sig account cannot act | CoreWriter does not work for multi-sig HyperCore users |
In the explorer, CoreWriter action 15 appears as SystemBoleAction with integer wei, HTTP borrowLend with a string amount. The explorer keeps the last 300 actions per user.
To read the result back, see the Precompile reference. What action 17 does economically is on Split, merge, negate.