gmx.contracts

Documentation for eth_defi.gmx.contracts Python module.

GMX Protocol Contract Infrastructure

This module provides contract addresses, ABIs, and utility functions for interacting with GMX protocol contracts across supported networks.

Module Attributes

GMX_DEFAULT_CONTRACT_RELEASE

Default GMX contract release used to resolve addresses.

GMX_CONTRACT_RELEASE_ENV_VAR

Environment variable overriding GMX_DEFAULT_CONTRACT_RELEASE.

GMX_CONTRACT_RELEASE_REMOTE

Sentinel release restoring live resolution from gmx-io/gmx-synthetics.

GMX_REMOTE_CACHE_TTL_SECONDS

How long a dynamically fetched address set stays cached, in seconds.

PINNED_CONTRACTS

Pinned GMX contract addresses, keyed by release then by chain.

Functions

clear_contract_address_cache()

Drop cached dynamically fetched addresses.

get_contract_addresses(chain[, release])

Get GMX contract addresses for a specific network.

get_datastore_contract(web3, chain)

Get DataStore contract instance for a specific network.

get_exchange_router_contract(web3, chain)

Get ExchangeRouter contract instance for a specific network.

get_glv_reader_contract(web3, chain)

Get GLV Reader contract instance for a specific network.

get_oracle_contract(web3, chain)

Get Oracle contract instance for a specific network.

get_pinned_contract_release()

Resolve which GMX contract release address lookups should use.

get_reader_contract(web3, chain)

Get SyntheticsReader contract instance for a specific network.

get_token_address(chain, symbol[, web3])

Get address for a specific token on a network.

get_token_address_normalized(chain, symbol)

Get address for a specific token on a network, with proper normalization for GMX.

get_token_balance_contract(web3, ...)

get_token_metadata(chain, address)

Get metadata for a specific token on a network.

get_tokens_address_dict(chain)

Get token address mapping for a specific network from GMX API.

get_tokens_metadata_dict(chain)

Get full token metadata for a specific network from GMX API.

normalize_gmx_token_symbol(chain, token_symbol)

Normalize token symbol to the canonical form used by GMX API for a given chain.

Classes

ContractAddresses

GMX contract addresses for a specific network.

class ContractAddresses

Bases: object

GMX contract addresses for a specific network.

datastore: eth_typing.evm.HexAddress

DataStore contract address for on-chain data storage

eventemitter: eth_typing.evm.HexAddress

EventEmitter contract address for protocol event logging

exchangerouter: eth_typing.evm.HexAddress

ExchangeRouter contract address for trading operations

depositvault: eth_typing.evm.HexAddress

DepositVault contract address for deposit operations

withdrawalvault: eth_typing.evm.HexAddress

WithdrawalVault contract address for withdrawal operations

ordervault: eth_typing.evm.HexAddress

OrderVault contract address for order management

syntheticsreader: eth_typing.evm.HexAddress

SyntheticsReader contract address for efficient data queries

syntheticsrouter: eth_typing.evm.HexAddress

SyntheticsRouter contract address for synthetic asset routing

glvreader: eth_typing.evm.HexAddress

GLVReader contract address for GLV token queries

chainlinkpricefeedprovider: Optional[eth_typing.evm.HexAddress]

ChainlinkPriceFeedProvider contract address (optional)

chainlinkdatastreamprovider: Optional[eth_typing.evm.HexAddress]

ChainlinkDataStreamProvider contract address (optional)

gmoracleprovider: Optional[eth_typing.evm.HexAddress]

GMOracleProvider contract address (optional)

orderhandler: Optional[eth_typing.evm.HexAddress]

OrderHandler contract address (optional)

oracle: Optional[eth_typing.evm.HexAddress]

Oracle contract address (optional)

__init__(datastore, eventemitter, exchangerouter, depositvault, withdrawalvault, ordervault, syntheticsreader, syntheticsrouter, glvreader, chainlinkpricefeedprovider=None, chainlinkdatastreamprovider=None, gmoracleprovider=None, orderhandler=None, oracle=None)
Parameters
Return type

None

GMX_DEFAULT_CONTRACT_RELEASE = 'v2.2c'

Default GMX contract release used to resolve addresses.

Address resolution is pinned rather than fetched live. GMX publishes new deployments to the updates branch of gmx-io/gmx-synthetics; resolving against that branch on every call means the ExchangeRouter a bot trades through can change because of an upstream git push, or flip back to the previous deployment when GitHub returns HTTP 429. Both happened in production and caused every order to revert with Target not allowed against a Lagoon vault guard whose allowlist still held the older router.

GMX_CONTRACT_RELEASE_ENV_VAR = 'GMX_CONTRACT_RELEASE'

Environment variable overriding GMX_DEFAULT_CONTRACT_RELEASE.

This is the documented escape hatch. Set it to another key of PINNED_CONTRACTS (e.g. v2.2b) to roll back without a code change, or to GMX_CONTRACT_RELEASE_REMOTE to restore the legacy dynamic-fetch behaviour.

GMX_CONTRACT_RELEASE_REMOTE = 'remote'

Sentinel release restoring live resolution from gmx-io/gmx-synthetics.

Opt-in only. Results are still cached for GMX_REMOTE_CACHE_TTL_SECONDS so the order hot path does not perform an HTTP round trip per order.

GMX_REMOTE_CACHE_TTL_SECONDS = 3600.0

How long a dynamically fetched address set stays cached, in seconds.

PINNED_CONTRACTS: dict[str, dict[str, eth_defi.gmx.contracts.ContractAddresses]] = {'v2.2b': {'arbitrum': ContractAddresses(datastore='0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8', eventemitter='0xC8ee91A54287DB53897056e12D9819156D3822Fb', exchangerouter='0x1C3fa76e6E1088bCE750f23a5BFcffa1efEF6A41', depositvault='0xF89e77e8Dc11691C9e8757e84aaFbCD8A67d7A55', withdrawalvault='0x0628D46b5D145f183AdB6Ef1f2c97eD1C4701C55', ordervault='0x31eF83a530Fde1B38EE9A18093A333D8Bbbc40D5', syntheticsreader='0x470fbC46bcC0f16532691Df360A07d8Bf5ee0789', syntheticsrouter='0x7452c558d45f8afC8c83dAe62C3f8A5BE19c71f6', glvreader='0x2C670A23f1E798184647288072e84054938B5497', chainlinkpricefeedprovider='0x38B8dB61b724b51e42A88Cb8eC564CD685a0f53B', chainlinkdatastreamprovider='0xE1d5a068c5b75E0c7Ea1A9Fe8EA056f9356C6fFD', gmoracleprovider='0x5d6B84086DA6d4B0b6C0dF7E02f8a6A039226530', orderhandler='0x63492B775e30a9E6b4b4761c12605EB9d071d5e9', oracle='0x7F01614cA5198Ec979B1aAd1DAF0DE7e0a215BDF'), 'avalanche': ContractAddresses(datastore='0x2F0b22339414ADeD7D5F06f9D604c7fF5b2fe3f6', eventemitter='0xDb17B211c34240B014ab6d61d4A31FA0C0e20c26', exchangerouter='0x8f550E53DFe96C055D5Bdb267c21F268fCAF63B2', depositvault='0x90c670825d0C62ede1c5ee9571d6d9a17A722DFF', withdrawalvault='0xf5F30B10141E1F63FC11eD772931A8294a591996', ordervault='0xD3D60D22d415aD43b7e64b510D86A30f19B1B12C', syntheticsreader='0x62Cb8740E6986B29dC671B2EB596676f60590A5B', syntheticsrouter='0x820F5FfC5b525cD4d88Cd91aCf2c28F16530Cc68', glvreader='0x5C6905A3002f989E1625910ba1793d40a031f947', chainlinkpricefeedprovider='0x05d97cee050bfb81FB3EaD4A9368584F8e72C88e', chainlinkdatastreamprovider='0xC181eB022F33b8ba808AD96348B03e8A753A859b', gmoracleprovider='0x9Dc4f12Eb2d8405b499FB5B8AF79a5f64aB8a457', orderhandler='0x823b558B4bC0a2C4974a0d8D7885AA1102D15dEC', oracle='0xE1d5a068c5b75E0c7Ea1A9Fe8EA056f9356C6fFD')}, 'v2.2c': {'arbitrum': ContractAddresses(datastore='0xFD70de6b91282D8017aA4E741e9Ae325CAb992d8', eventemitter='0xC8ee91A54287DB53897056e12D9819156D3822Fb', exchangerouter='0x7dE39FF2e232A2203196788d37e234cF8F1b83f1', depositvault='0xF89e77e8Dc11691C9e8757e84aaFbCD8A67d7A55', withdrawalvault='0x0628D46b5D145f183AdB6Ef1f2c97eD1C4701C55', ordervault='0x31eF83a530Fde1B38EE9A18093A333D8Bbbc40D5', syntheticsreader='0xfA26cBb46e2614609406de08CA1Dc7f70a684184', syntheticsrouter='0x7452c558d45f8afC8c83dAe62C3f8A5BE19c71f6', glvreader='0x85fcBD684D08053f1efAB302dCb04F22E20E65B1', chainlinkpricefeedprovider='0x90218fbb064b1475E4382b041Cc7ccF08AF718B0', chainlinkdatastreamprovider='0x7BA7Ae61887F1aca28E0FE5aB1434ce85b6606aa', gmoracleprovider='0x5d6B84086DA6d4B0b6C0dF7E02f8a6A039226530', orderhandler='0xa5D2d45228ee2E3A18AB122B2cE84997d008f4Eb', oracle='0x26C02F221e8dB5A821e12347C7eA8a6b6E10842f'), 'avalanche': ContractAddresses(datastore='0x2F0b22339414ADeD7D5F06f9D604c7fF5b2fe3f6', eventemitter='0xDb17B211c34240B014ab6d61d4A31FA0C0e20c26', exchangerouter='0xc002Db96E682FFF6675966F959677285a0C45Efa', depositvault='0x90c670825d0C62ede1c5ee9571d6d9a17A722DFF', withdrawalvault='0xf5F30B10141E1F63FC11eD772931A8294a591996', ordervault='0xD3D60D22d415aD43b7e64b510D86A30f19B1B12C', syntheticsreader='0xa34320a507493C71Fe35E982e496F7C5d1a7fa02', syntheticsrouter='0x820F5FfC5b525cD4d88Cd91aCf2c28F16530Cc68', glvreader='0x321EB66dD95ad33715ee615AAb8dAC6394E7b3F9', chainlinkpricefeedprovider='0x86E284921273E1442f32ebd1b567Ce988Cf50dfE', chainlinkdatastreamprovider='0xc581aF9d20b1d95e456e4Bb9E3039aa0d48F9891', gmoracleprovider='0x9Dc4f12Eb2d8405b499FB5B8AF79a5f64aB8a457', orderhandler='0xC993eF170859DAE0241a3c12B8186e456Fa1c1B0', oracle='0x29220fA3b24279279C211701DE4a7b035122B911')}}

Pinned GMX contract addresses, keyed by release then by chain.

Sourced from gmx-io/gmx-synthetics: v2.2c from the updates branch and v2.2b from main, both read from docs/contracts.json.

Seven addresses rotated between v2.2b and v2.2c, identically on both chains: ExchangeRouter, Reader, GlvReader, ChainlinkPriceFeedProvider, ChainlinkDataStreamProvider, OrderHandler and Oracle. Of these only the first three matter to this integration — ExchangeRouter is the trading target a vault guard allowlists, and the two readers are decoded with vendored ABIs. Nothing here reads the other four.

The rest are unchanged: Router (SyntheticsRouter), OrderVault, DataStore, EventEmitter, DepositVault, WithdrawalVault and GmOracleProvider. That is the load-bearing property — an existing ERC-20 approval targets the SyntheticsRouter and a guard maps each ExchangeRouter to an OrderVault, so both survive the upgrade and the migration is a single whitelist entry rather than a re-approval plus a guard remap.

test_release_rotation_set_is_documented pins this list, so a future release that rotates something else fails rather than silently invalidating the claim.

get_pinned_contract_release()

Resolve which GMX contract release address lookups should use.

Reads GMX_CONTRACT_RELEASE_ENV_VAR at call time so tests and operators can override the pin without reimporting the module.

Returns

Release key into PINNED_CONTRACTS, or GMX_CONTRACT_RELEASE_REMOTE for live resolution.

Return type

str

clear_contract_address_cache()

Drop cached dynamically fetched addresses.

Only affects the GMX_CONTRACT_RELEASE_REMOTE code path; pinned lookups are not cached because they perform no I/O.

Return type

None

get_contract_addresses(chain, release=None)

Get GMX contract addresses for a specific network.

Addresses are resolved from PINNED_CONTRACTS by default. Pinning is deliberate: a trading target must not change because GMX pushed to the updates branch of gmx-io/gmx-synthetics, and must not flip back to the previous deployment because GitHub returned HTTP 429. Both occur in practice, and against an on-chain allowlist (such as a Lagoon vault guard) a silently rotated ExchangeRouter turns every order into a reverted transaction.

To follow GMX’s published addresses live instead, pass release=GMX_CONTRACT_RELEASE_REMOTE or set the GMX_CONTRACT_RELEASE_ENV_VAR environment variable. Remote results are cached for GMX_REMOTE_CACHE_TTL_SECONDS, so this no longer costs an HTTP round trip per order.

Example — pin to the previous release without a code change:

export GMX_CONTRACT_RELEASE=v2.2b
Parameters
Returns

Contract addresses for the network

Raises

ValueError – If chain or release is not supported

Return type

eth_defi.gmx.contracts.ContractAddresses

get_reader_contract(web3, chain)

Get SyntheticsReader contract instance for a specific network.

Parameters
  • web3 (web3.main.Web3) – Web3 connection instance

  • chain (str) – Network name

Returns

Web3 contract instance for SyntheticsReader

Return type

web3.contract.contract.Contract

get_datastore_contract(web3, chain)

Get DataStore contract instance for a specific network.

Parameters
  • web3 (web3.main.Web3) – Web3 connection instance

  • chain (str) – Network name

Returns

Web3 contract instance for DataStore

Return type

web3.contract.contract.Contract

get_tokens_metadata_dict(chain)

Get full token metadata for a specific network from GMX API.

Returns address -> {symbol, decimals, synthetic} mapping. This avoids expensive contract calls for each token.

Parameters

chain (str) – Network name

Returns

Dictionary mapping token addresses to metadata

Raises

ValueError – If chain is not supported or API request fails

Return type

dict[str, dict]

get_tokens_address_dict(chain)

Get token address mapping for a specific network from GMX API.

Returns symbol -> address mapping for backward compatibility.

Parameters

chain (str) – Network name

Returns

Dictionary mapping token symbols to addresses

Raises

ValueError – If chain is not supported or API request fails

Return type

dict[str, str]

get_token_address(chain, symbol, web3=None)

Get address for a specific token on a network.

Parameters
  • chain (str) – Network name

  • symbol (str) – Token symbol

  • web3 (Optional[web3.main.Web3]) – Web3 connection instance (optional, not required for API calls)

Returns

Token address or None if not found

Return type

Optional[str]

get_exchange_router_contract(web3, chain)

Get ExchangeRouter contract instance for a specific network.

Parameters
  • web3 (web3.main.Web3) – Web3 connection instance

  • chain (str) – Network name

Returns

Web3 contract instance for ExchangeRouter

Return type

web3.contract.contract.Contract

get_oracle_contract(web3, chain)

Get Oracle contract instance for a specific network.

Parameters
  • web3 (web3.main.Web3) – Web3 connection instance

  • chain (str) – Network name

Returns

Web3 contract instance for Oracle, or None if not available for the chain

Return type

Optional[web3.contract.contract.Contract]

get_glv_reader_contract(web3, chain)

Get GLV Reader contract instance for a specific network.

Parameters
  • web3 (web3.main.Web3) – Web3 connection instance

  • chain (str) – Network name

Returns

Web3 contract instance for GLV Reader

Return type

web3.contract.contract.Contract

get_token_metadata(chain, address)

Get metadata for a specific token on a network.

Parameters
  • chain (str) – Network name

  • address (str) – Token address

Returns

Token metadata dictionary or None if not found

Return type

Optional[dict]

normalize_gmx_token_symbol(chain, token_symbol)

Normalize token symbol to the canonical form used by GMX API for a given chain.

On GMX, ETH and WETH are treated as the same token, as are AVAX and WAVAX. This function returns the canonical symbol that GMX API uses.

Parameters
  • chain (str) – Network name

  • token_symbol (str) – Original token symbol (e.g., “ETH”, “WETH”)

Returns

Canonical token symbol (e.g., always “ETH” for ETH/WETH on Arbitrum)

Return type

str

get_token_address_normalized(chain, symbol, web3=None)

Get address for a specific token on a network, with proper normalization for GMX.

This function handles the special case where ETH and WETH are treated as the same token on GMX protocol, as well as AVAX and WAVAX on Avalanche.

Parameters
  • chain (str) – Network name

  • symbol (str) – Token symbol (ETH/WETH will be normalized)

  • web3 (Optional[web3.main.Web3]) – Web3 connection instance (optional, not required for API calls)

Returns

Token address or None if not found

Return type

Optional[str]