For DevelopersGX EVMGX Core <> GX EVM Transfers

GX Core EVM Transfers

This page explains how to transfer assets between the GX Core trading engine and the GX EVM smart contract environment.

Architecture

GX Exchange maintains two separate balance systems:

LayerBalance TypeUsed For
GX CoreTrading balanceOrder placement, margin, perp/spot trading
GX EVMEVM balanceSmart contract interactions, ERC-20 tokens, DeFi

Assets must be explicitly transferred between these layers. They cannot be spent in one layer while held in the other.

Core to EVM Transfer

Move USDC from your GX Core trading balance to your GX EVM address.

Via API

POST /exchange
 
{
  "action": {
    "type": "coreToEvm",
    "amount": "1000.0"
  },
  "nonce": 1700000000123,
  "signature": { "r": "0x...", "s": "0x...", "v": 27 }
}
FieldTypeDescription
amountstringUSDC amount to transfer to EVM

Via SDK

const result = await client.exchange({
  action: {
    type: "coreToEvm",
    amount: "1000.0",
  },
  nonce: Date.now(),
});
result = exchange.core_to_evm(amount="1000.0")

Processing

  • The transfer is processed in the current GX Core block (< 2 seconds).
  • USDC appears as an ERC-20 balance at the USDC contract address on GX EVM.
  • No gas fee is charged for the Core-to-EVM direction.

EVM to Core Transfer

Move USDC from your GX EVM address back to your GX Core trading balance.

Via Bridge Contract

Call the depositToCore function on the GX Bridge precompile:

// From a smart contract
interface IGxBridge {
    function depositToCore(uint256 amount) external;
}
 
IGxBridge constant bridge = IGxBridge(address(0x103));
 
function sendToCore(uint256 amount) external {
    // First approve the bridge to spend USDC
    IERC20(usdcAddress).approve(address(0x103), amount);
    bridge.depositToCore(amount);
}

Via ethers.js

import { ethers } from "ethers";
 
const provider = new ethers.JsonRpcProvider("https://rpc.gx.exchange");
const wallet = new ethers.Wallet("0xYourPrivateKey...", provider);
 
const bridgeAddress = "0x0000000000000000000000000000000103";
const bridgeAbi = ["function depositToCore(uint256 amount) external"];
const bridge = new ethers.Contract(bridgeAddress, bridgeAbi, wallet);
 
// Approve USDC spend first
const usdcAddress = "0x..."; // GX EVM USDC contract
const usdc = new ethers.Contract(usdcAddress, [
  "function approve(address spender, uint256 amount) external returns (bool)"
], wallet);
 
const amount = ethers.parseUnits("1000", 6); // 1000 USDC (6 decimals)
await usdc.approve(bridgeAddress, amount);
 
// Transfer to Core
const tx = await bridge.depositToCore(amount);
await tx.wait();
console.log("Transferred to GX Core");

Processing

  • The EVM transaction must be mined in a block (1 second for fast block, up to 1 minute for slow block).
  • The GX Core balance is credited in the next Core block after the EVM block is finalized.
  • Total latency: 2-5 seconds for fast blocks.

Transfer Timing Summary

DirectionInitiationConfirmationTotal Latency
Core to EVMAPI callNext Core block1-2 seconds
EVM to CoreEVM transactionNext Core block after EVM finality2-5 seconds

Checking Balances

GX Core Balance

POST /info
{ "type": "clearinghouseState", "user": "0xYourAddress..." }

GX EVM Balance

const provider = new ethers.JsonRpcProvider("https://rpc.gx.exchange");
 
// Native GX balance
const gxBalance = await provider.getBalance("0xYourAddress...");
 
// USDC ERC-20 balance
const usdc = new ethers.Contract(usdcAddress, [
  "function balanceOf(address) view returns (uint256)"
], provider);
const usdcBalance = await usdc.balanceOf("0xYourAddress...");

Fees

Transfer DirectionFee
Core to EVMFree
EVM to CoreEVM gas fee only (no additional bridge fee)

Constraints

ConstraintValue
Minimum transfer1 USDC
Maximum transferLimited by available balance
Transfer currencyUSDC only (other assets require swaps)
CooldownNone — transfers can be submitted at any frequency