Moving assets between HyperCore and the HyperEVM
Linked tokens cross between HyperCore and the HyperEVM via per-token system addresses, with a decimal offset and a 200k-gas fee when leaving HyperCore.
HyperCore’s spot book trades a token; your contracts need it as an ERC20. A link makes the two one supply: a token sent to its system address on one side is released by the system address on the other. The protocol credits both ends, but the ERC20 still needs checking (linking a token).
Moving 100 USDC to the HyperEVM
Section titled “Moving 100 USDC to the HyperEVM”Say you hold 100 USDC in HyperCore spot, 10,000,000,000 in HyperCore wei. Send it to USDC’s system address and the next HyperEVM block credits you 100,000,000, as USDC has 6 decimals there. The 200k-gas fee comes out of your HyperCore balance, so keep HYPE there or send less than 100.
Every token has a system address
Section titled “Every token has a system address”A system address is 0x20 followed by the token index as a 19-byte big-endian number. HYPE is the exception, at 0x2222222222222222222222222222222222222222.
| Token | Index | System address |
|---|---|---|
| USDC | 0 | 0x2000000000000000000000000000000000000000 |
| PURR (docs example) | 1 | 0x2000000000000000000000000000000000000001 |
| docs example | 200 | 0x20000000000000000000000000000000000000c8 |
| USDT0 (mainnet) | 268 | 0x200000000000000000000000000000000000010c |
| USDH (mainnet) | 360 | 0x2000000000000000000000000000000000000168 |
| HYPE | 150 on mainnet | 0x2222222222222222222222222222222222222222 |
Use the token index, not the spot pair index: USDH is token 360 but pair @230, and the pair index gives another token’s address (asset ids). Indices differ by network: HYPE is 150 on mainnet, 1105 on testnet.
The two directions, side by side
Section titled “The two directions, side by side”Both directions go through the token’s system address and are credited by the protocol. HTTP forms are on transfers and withdrawals; contract forms on CoreWriter.
| HyperEVM to HyperCore | HyperCore to HyperEVM | |
|---|---|---|
| Send | The linked ERC20’s transfer(systemAddress, amount), in EVM decimals. HYPE: plain value with empty data to 0x2222...2222 |
spotSend, or sendAsset with sourceDex and destinationDex both "spot", to the system address. From a contract: CoreWriter action 6 (spot send) or 13 (send asset, type(uint32).max selecting spot) |
| Credit | HyperCore credits the sender from the Transfer log. HYPE’s receive() emits Received(address indexed user, uint256 amount) with user = msg.sender, so contracts and EOAs both work |
A system transaction from the system address calls transfer(recipient, amount) on the linked contract, recipient being the HyperCore sender; eth_getSystemTxsByBlockNumber returns these |
| When | Same L1 block, right after the EVM block is built (per the docs) | Queued until the next HyperEVM block |
| Cost | About an ordinary transfer’s gas, in HYPE on the HyperEVM | 200k gas at the next base fee, from the HyperCore balance (below) |
One token, two decimal scales
Section titled “One token, two decimal scales”EVM decimals = weiDecimals + evmExtraWeiDecimalsweiDecimals is the HyperCore precision; evmExtraWeiDecimals is set at linking, from -2 to 18. Neither is szDecimals, which governs order sizes. Read both from spotMeta (contract under evmContract, offset spelled evm_extra_wei_decimals) or the tokenInfo precompile at 0x80C.
| Token | weiDecimals (HyperCore) |
evmExtraWeiDecimals |
HyperEVM decimals |
|---|---|---|---|
| USDC | 8 | -2 | 6 |
| USDT0 | 8 | -2 | 6 |
| USDH | 8 | not recorded | 6 |
| PURR (docs example) | 5 | 13 | 18 |
| HYPE | 8 | native balance | 18 |
A negative offset makes the HyperEVM side coarser, as in the 100 USDC example above.
Non-round amounts are rejected, not burned
Section titled “Non-round amounts are rejected, not burned”Leaving HyperCore costs gas, paid on HyperCore
Section titled “Leaving HyperCore costs gas, paid on HyperCore”HyperCore to HyperEVM costs 200k gas at the next HyperEVM block’s base fee, taken from the HyperCore balance:
fee (HYPE) = 200,000 * next EVM block base fee (wei) / 1e18It is paid in HyperCore spot HYPE if that covers it, else in the token sent at the USD equivalent, though the docs mention only HYPE. One production SDK prices the conversion at the HYPE spot mark and records the debit order as confirmed on testnet.
On testnet, from 100 USDC, sending 99 cost 0.000588 USDC (charged in USDC, leaving 0.999412); sending all 100 was refused with “Insufficient USDC or HYPE balance for token transfer gas.” The EVM transaction that sent the action succeeded both times.
Activation and account existence
Section titled “Activation and account existence”The first transfer to an address that has never held anything on HyperCore costs 1 quote token (1 USDC, say), whatever the asset; on testnet, the first send to a fresh address carried 1.0 USDC and the second 0.0. Per the docs, an unactivated account cannot send CoreWriter actions, and a CoreWriter sender must exist on HyperCore before the EVM block is built (activation fee).
The numbers
Section titled “The numbers”| Parameter | Value |
|---|---|
| System address | 0x20 + 19-byte big-endian token index |
| HYPE system address | 0x2222222222222222222222222222222222222222 |
| HyperCore to HyperEVM fee | 200k gas x next EVM block base fee, charged on HyperCore |
| Measured fee, 99 USDC on testnet | 0.000588 USDC |
| HyperCore to HyperEVM timing | queued until the next HyperEVM block |
| HyperEVM to HyperCore timing | same L1 block, right after the EVM block |
evmExtraWeiDecimals range |
-2 to 18 |
| USDC | 8 decimals on HyperCore, 6 on the HyperEVM |
| USDC linked to HyperCore token 0 (mainnet) | 0x6b9e773128f453f5c2c60935ee2de2cbc5390a24, per spotMeta |
| Circle’s USDC on the HyperEVM, per the docs | 0xb88339cb7199b77e23db6e890353e22632ba630f, not linked |
| Mainnet linked USDT0 | 0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb |
| Activation fee | 1 quote token, first transfer to a new HyperCore account |
Moving tokens by hand
Section titled “Moving tokens by hand”- The app’s “Transfer to/from EVM” button does this. By hand, only HYPE goes to
0x2222...2222; the docs warn that other tokens sent there are lost. - HyperEVM “USDC” is two contracts and only one is linked; getting to Circle’s, which lending markets use, is a swap with its own price and liquidity.
Converting and flooring in code
Section titled “Converting and flooring in code”// System address for a HyperCore token index (not a spot pair index).function systemAddress(uint64 tokenIndex) pure returns (address) { return address(uint160(uint160(0x20) << 152 | uint160(tokenIndex)));}
// Largest HyperCore amount that survives a HyperCore to HyperEVM transfer.// USDC has evmExtraWeiDecimals = -2, so amounts must be a multiple of 100.function floorToEvmPrecision(uint64 coreWei, int8 evmExtraWeiDecimals) pure returns (uint64) { if (evmExtraWeiDecimals >= 0) return coreWei; uint64 step = uint64(10 ** uint256(uint8(-evmExtraWeiDecimals))); return coreWei - (coreWei % step);}- Floor before every HyperCore to HyperEVM send when the offset is negative: interest accrues at 8 decimals, so a full USDC lending balance is almost never a multiple of 100.
- Convert through one tested function. HyperEVM to HyperCore divides by
10^evmExtraWeiDecimalswhen positive and multiplies by10^-evmExtraWeiDecimalswhen negative; HyperCore to HyperEVM is the reverse, after flooring. - A HyperCore spot send to a contract has no sender the EVM can see. Take deposits on the HyperEVM side, or attribute them another way.
- Span blocks at setup: deploy, fund or activate on HyperCore, then send the first CoreWriter action in a later block.
- Same-block credit then action is untested. One mainnet deposit bridged 4,014.923507 USDC at block 45,041,469 and supplied it to the lending reserve 3 blocks later, deliberately floored by 1 EVM wei (execution order).
sendToEvmWithData, a documented user-signed action, callscoreReceiveWithDataon the linked contract instead oftransfer. It was not exercised in the work behind this site.
The contracts behind the stablecoin links
Section titled “The contracts behind the stablecoin links”| Contract | What it is | Evidence |
|---|---|---|
0x6b9e773128f453f5c2c60935ee2de2cbc5390a24, linked to HyperCore USDC (token 0) per spotMeta |
Upgradeable proxy; issuer not established | Carries the system transfers: 133 Transfer events to the USDC system address in 2,000 blocks, and a production deposit of 4,014.923507 USDC. Its standard views (name, symbol, decimals, balanceOf, totalSupply) reverted on two independent RPCs |
0xb88339cb7199b77e23db6e890353e22632ba630f, Circle’s USDC per the docs |
Standard 6-decimal ERC20 used by HyperEVM lending markets; not linked to token 0 | None of its transfers reached the USDC system address in the same 2,000 blocks |
0x0b80659a4076e9e93c7dbe0f10675a16a3e5c206, the testnet USDC link |
Broken | Every standard view and transfer reverts; no Transfer event in over 200 blocks; 99 USDC bridged there could not be moved by the receiving contract |
0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb, linked to USDT0 (token 268) |
The contract HyperEVM lending markets use | HyperCore and HyperEVM USDT0 are one asset |
Take decimals from tokenInfo or spotMeta, not the linked contract, and do not test the ERC20 leg of a USDC flow on testnet.
For the rounding, fee and attribution traps in one list, see footguns.