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, 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.