Skip to content

CoreWriter action reference

Expert

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.

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
byte 0 0x01 encoding version (only 1 exists)
bytes 1..3 action id, big-endian uint24
bytes 4.. abi.encode(field tuple) no function selector
bytes 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).

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

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.

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

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

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