TLDR
| Direction | Method |
|---|---|
| HyperCore → HyperEVM | spot_transfer() to system address 0x2000000000000000000000000000000000000000 |
| HyperEVM → HyperCore | Approve native USDC to CoreDepositWallet, then call deposit(amount, 4294967295) for spot |
Overview
Hyperliquid operates two interconnected layers:- HyperCore — the high-performance L1 for trading (perps and spot)
- HyperEVM — the EVM-compatible layer for smart contracts
Connect to a reliable Hyperliquid RPC endpoint to follow along with the examples.
System addresses
Every token on Hyperliquid has a designated system address that serves as the bridge between HyperCore and HyperEVM. The format is:| Token | Index | System address |
|---|---|---|
| USDC | 0 | 0x2000000000000000000000000000000000000000 |
| HYPE | N/A | 0x2222222222222222222222222222222222222222 |
| Token 200 | 200 | 0x20000000000000000000000000000000000000c8 |
Contract addresses
Mainnet
| Contract | Address | Purpose |
|---|---|---|
| Native USDC (Circle) | 0xb88339CB7199b77E23DB6E890353E22632Ba630f | Standard ERC20 USDC |
| CoreDepositWallet | 0x6b9e773128f453f5c2c60935ee2de2cbc5390a24 | Bridge contract (from spotMeta) |
| System address (USDC) | 0x2000000000000000000000000000000000000000 | HyperCore → HyperEVM destination |
| System address (HYPE) | 0x2222222222222222222222222222222222222222 | HYPE bridge |
| CoreWriter | 0x3333333333333333333333333333333333333333 | HyperCore actions from EVM |
Testnet
| Contract | Address | Purpose |
|---|---|---|
| Native USDC (Circle) | 0x2B3370eE501B4a559b57D449569354196457D8Ab | Standard ERC20 USDC |
| CoreDepositWallet | 0x0b80659a4076e9e93c7dbe0f10675a16a3e5c206 | Bridge contract (from spotMeta) |
| System address (USDC) | 0x2000000000000000000000000000000000000000 | HyperCore → HyperEVM destination |
You can retrieve the correct linked USDC contract address programmatically using the
spotMeta API endpoint. The contract address is returned in the evmContract.address field.Endpoint requirements
Different bridging operations require different endpoints:| Operation | Endpoint | Provider |
|---|---|---|
HyperCore → HyperEVM (spotSend) | Info HTTP API | Hyperliquid public RPC only |
HyperEVM → HyperCore (transfer) | EVM JSON-RPC | Chainstack or Hyperliquid |
Check balances (spotMeta, userState) | Info HTTP API | Chainstack or Hyperliquid |
Read EVM state (eth_call, eth_getBalance) | EVM JSON-RPC | Chainstack or Hyperliquid |
Prerequisites
1
Install dependencies
Install the required Python packages:
2
Set up configuration
Create a
config.json file with your credentials:3
Verify token linking
USDC must be linked between HyperCore and HyperEVM. On mainnet, USDC is already linked. On testnet, check token linking status before bridging.
HyperCore to HyperEVM
Transfer USDC from your HyperCore spot account to your HyperEVM wallet using thespotSend action directed at the system address.
Using the Python SDK
How it works
- You send a
spotSendaction with the system address (0x2000000000000000000000000000000000000000) as the destination - Hyperliquid detects this as a bridge request and triggers a system transaction
- The system transaction calls
transfer(sender_address, amount)on the linked ERC20 contract - USDC appears in your HyperEVM wallet (the sender’s address)
The bridge is nearly instant—funds typically appear within 2 seconds. The HyperCore → HyperEVM transfer costs approximately 200K gas at the base gas price.
HyperEVM to HyperCore
Transfer USDC from HyperEVM back to HyperCore for trading using the CoreDepositWallet contract.The linked USDC contract shown in
spotMeta is a CoreDepositWallet contract developed by Circle—not a standard ERC20. To bridge USDC from HyperEVM to HyperCore, you must use the deposit() function on this contract after approving the native USDC token.Understanding the two USDC contracts
Bridging from HyperEVM to HyperCore involves two contracts:| Contract | Mainnet | Testnet | Purpose |
|---|---|---|---|
| Native USDC (Circle) | 0xb88339CB7199b77E23DB6E890353E22632Ba630f | 0x2B3370eE501B4a559b57D449569354196457D8Ab | Standard ERC20 USDC |
| CoreDepositWallet | 0x6b9e773128f453f5c2c60935ee2de2cbc5390a24 | 0x0b80659a4076e9e93c7dbe0f10675a16a3e5c206 | Bridge contract (from spotMeta) |
evmContract.address returned by the spotMeta API endpoint.
Using the CoreDepositWallet
Thedeposit() function signature:
amount— amount in 6 decimals (native USDC decimals)destinationDex— destination on HyperCore:0= perps balance4294967295(type(uint32).max) = spot balance
The CoreDepositWallet source code is available at circlefin/hyperevm-circle-contracts.
How it works
- Approve the native USDC contract to allow CoreDepositWallet to spend your tokens
- Call
deposit()on the CoreDepositWallet with:- Amount in 6 decimals
- Destination dex (
0for perps,4294967295for spot)
- The CoreDepositWallet transfers USDC from your wallet and credits your HyperCore account
Using CoreWriter for spot/perps transfers
Once USDC is on HyperCore (via the direct transfer method above), you can use the CoreWriter system contract to transfer between spot and perps accounts:For simple spot/perps transfers, you can also use the Python SDK’s
usd_class_transfer() method which handles the encoding automatically. The CoreWriter approach is useful when building smart contracts that need to interact with HyperCore.Token linking
For custom tokens (not USDC), you must link the HyperEVM ERC20 contract to the HyperCore spot token before bridging works.Check if a token is linked
You can use Chainstack’s Info HTTP API endpoint for this:The
spotMeta response includes the evmContract field for linked tokens. For USDC, you’ll see the contract address and evm_extra_wei_decimals (typically -2, meaning 6 decimals on EVM vs 8 on HyperCore).Linking process (for token deployers)
Token linking is a two-step process:1
Request EVM contract
Send a
RequestEvmContract action specifying the ERC20 contract address and decimal difference.2
Finalize linking
Send a
FinalizeEvmContract action with nonce verification or storage slot validation.Testnet considerations
Net-transfer restriction
On testnet, the net transfer from HyperCore to HyperEVM is capped. If you try to bridge more USDC to HyperEVM than you’ve previously bridged to HyperCore, the transaction will fail silently. Workaround:- First bridge USDC from an external chain (like Arbitrum Sepolia) to HyperCore
- Then you can bridge that amount to HyperEVM
New account fees
New HyperCore accounts incur a 1 USDC fee on first deposit:- Minimum first deposit: >1 USDC + any forwarding fees
- Deposits ≤1 USDC to new accounts fail silently
- Multiple deposits to new accounts in the same block each incur the fee
Common issues
”Cannot self-transfer” error
Cause: You tried to send tokens to your own address usingspot_transfer().
Solution: For bridging, send to the system address (0x2000000000000000000000000000000000000000), not to your own address. Self-transfers to the same user are not allowed.
”Token not linked” error
Cause: The token hasn’t been linked between HyperCore and HyperEVM. Solution: For USDC, this shouldn’t happen on mainnet. For custom tokens, the token deployer must complete the linking process.balanceOf() reverts on CoreDepositWallet
Cause: The CoreDepositWallet contract (fromspotMeta) is not a standard ERC20—it’s a bridge contract that doesn’t support balanceOf() or other ERC20 read functions.
Solution: This is expected behavior. To check your USDC balance on HyperEVM, call balanceOf() on the Native USDC contract (0xb88339CB7199b77E23DB6E890353E22632Ba630f on mainnet).
”Caller is not the system address” error
Cause: You tried to calltransfer() directly on the CoreDepositWallet contract. This contract has access control and does not support standard ERC20 transfers.
Solution: Use the deposit(amount, destinationDex) function on the CoreDepositWallet instead:
- First approve your native USDC to the CoreDepositWallet
- Call
deposit(amount, 4294967295)for spot balance ordeposit(amount, 0)for perps
Silent failure on testnet
Cause: Net-transfer restriction or insufficient amount for new account. Solution:- Ensure you’ve deposited to HyperCore before trying to bridge to HyperEVM
- For new accounts, deposit >1 USDC
Transaction succeeds but balance unchanged
Cause: Transfer to unlinked token system address or incorrect destination. Solution: Verify the system address matches the token you’re bridging.”No HYPE for gas” on HyperEVM
Cause: HyperEVM uses HYPE as the native gas token, and your wallet has no HYPE. Solution: Bridge some HYPE from HyperCore to HyperEVM first. HYPE uses the special system address0x2222222222222222222222222222222222222222.
Gas costs
| Direction | Approximate cost |
|---|---|
| HyperCore → HyperEVM | ~200K gas at base price |
| HyperEVM → HyperCore | ~100K gas (ERC20 transfer) |
Best practices
DO
- Use the Python SDK
spot_transfer()for HyperCore → HyperEVM bridging - Use the
CoreDepositWallet.deposit()function for HyperEVM → HyperCore bridging - Approve native USDC to the CoreDepositWallet before calling deposit
- Verify token linking status before bridging custom tokens
- Test with small amounts first
- Check balances on both sides after bridging
Related resources
- Hyperliquid methods — Complete list of supported methods and endpoint capabilities
- Hyperliquid tooling — SDKs and API reference
- HyperCore to HyperEVM transfers — Official Hyperliquid documentation
- Circle CCTP documentation — Cross-chain USDC transfers
- Circle HyperEVM contracts — CoreDepositWallet source code