Files
proxmox/docs/07-ccip/TOKEN_MAPPING_AND_MAINNET_ADDRESSES.md
defiQUG bea1903ac9
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
Sync all local changes: docs, config, scripts, submodule refs, verification evidence
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-21 15:46:06 -08:00

8.5 KiB
Raw Blame History

Token Mapping and Mainnet Addresses (Chain 138 ↔ Ethereum Mainnet)

Last Updated: 2026-02-13
Status: Active
Source of truth: config/token-mapping.json


Overview

Ethereum Mainnet (chainId 1) in config/smart-contracts-master.json lists only CCIP relay contracts plus canonical WETH9 and LINK. It does not include wrapped/mirrored ERC20 addresses for tokens that originate on Chain 138 (e.g. Compliant USDT/USDC, WETH10). This document defines the full mapping and how to use it.


Definitive Mainnet Addresses (from source of truth)

Token Mainnet address Notes
WETH9 (canonical) 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 Same on Chain 138; only token the current Mainnet CCIPRelayBridge accepts.
LINK (canonical) 0x514910771AF9Ca656af840dff83E8264EcF986CA Canonical Mainnet LINK; relay bridge does not accept LINK yet (WETH9-only).

For any other token (USDT, USDC, WETH10, etc.) the JSON and the Mainnet bridge do not specify a Mainnet “bridged” contract. Mainnet canonical references (for documentation only) are in config/token-mapping.json under mainnetCanonicalReference.


Full mapping table (Chain 138 → Mainnet)

Token key Chain 138 address Mainnet address Relay supported (138→Mainnet)
WETH9 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 Yes
LINK_Token 0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03 0x514910771AF9Ca656af840dff83E8264EcF986CA No (bridge WETH9-only)
WETH10 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f No
Compliant_USDT 0x93E66202A11B1772E55407B32B44e5Cd8eda7f22 No
Compliant_USDC 0xf22258f57794CC8E06237084b353Ab30fFfa640b No
Tether_USDT_Chain138 0x15DF1D5BFDD8Aa4b380445D4e3E9B38d34283619 No

“—” means no Mainnet wrapped/mirrored contract in the current design; the Mainnet CCIPRelayBridge has no token registry or factory for these.


Where mapping is used

  • Relay service (smom-dbis-138/services/relay): config.js builds tokenMapping (Chain 138 address → Mainnet address) from config/token-mapping.json when available, otherwise uses a fallback object. Only WETH9 is accepted by the Mainnet bridge; LINK is mapped for future use.
  • Config: config/token-mapping.json is the single source of truth. config/token-mapping-loader.cjs provides getRelayTokenMapping() and getTokenList() for consumers.

Mainnet bridge behaviour

  • CCIPRelayBridge (Mainnet): 0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939
    • Accepts only WETH9 (message.tokenAmounts[0].token == weth9).
    • No view functions such as getWrappedToken(originChainId, originToken) or nativeToWrapped(...).
    • No on-chain token registry; no wrapped token deployment for Chain 138origin tokens.
  • Getting Mainnet token address for a bridged token:
    • WETH9: use 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2.
    • LINK: use 0x514910771AF9Ca656af840dff83E8264EcF986CA (canonical); relay bridge does not support it yet.
    • Anything else: not derivable from the current bridge or JSON; would require a different Mainnet contract that deploys/registers wrapped tokens and exposes a mapping.

Recommendations and suggestions

  1. Keep config/token-mapping.json as the single source of truth
    Add or change token entries there; the relay and docs should reference it. When adding a new token with a Mainnet address, set mainnetAddress and relaySupported as appropriate.

  2. Extend Mainnet bridge for LINK (optional)
    To support 138→Mainnet LINK via the relay, either:

    • Extend CCIPRelayBridge to accept LINK (and hold/fund LINK), or
    • Deploy a separate receiver contract for LINK and point relay to it for LINK messages.
      After that, set relaySupported: true for LINK in token-mapping.json.
  3. Document unsupported tokens
    WETH10, Compliant_USDT, Compliant_USDC, and Tether_USDT_Chain138 have no Mainnet wrapped address in this design. For token lists or UIs, use this doc or token-mapping.json so integrators do not assume a Mainnet address exists.

  4. If you introduce wrapped tokens on Mainnet later
    If a future bridge or TokenFactory deploys wrapped tokens on Mainnet for Chain 138 assets:

    • Add the Mainnet wrapped address to config/token-mapping.json for that token.
    • If the relay will deliver that token, add the Chain 138 → Mainnet mapping to the relays tokenMapping (already driven by token-mapping.json when the config path is available).
    • Optionally add the wrapped contract to config/smart-contracts-master.json under chain 1 if you want it in the main contract list.
  5. Canonical Mainnet references (reference only)
    For documentation and off-chain tooling, canonical Mainnet addresses are in config/token-mapping.json under mainnetCanonicalReference (e.g. USDT, USDC, WETH9, LINK). These are not “bridged” addresses from Chain 138 unless explicitly mapped in tokens.

  6. Relay service
    When running the relay from the monorepo, ensure config/token-mapping.json and config/token-mapping-loader.cjs are available so the relay uses the full mapping. Fallback in config.js covers WETH9 and LINK when the config is not present.


Additional recommendations

  1. CI validation
    The pipeline runs scripts/validation/validate-config-files.sh when config/ changes. That script checks for config/token-mapping.json and, if present, validates that it is valid JSON with a .tokens array. Keep the file valid so CI passes.

  2. Sync when adding tokens
    When adding a new token to Chain 138 (or a new bridged token), update both:

    • config/smart-contracts-master.json (under chains.138.contracts if it is a contract),
    • config/token-mapping.json (add an entry with key, chain138Address, mainnetAddress if known, relaySupported, notes).
      Optionally update CHAIN138_TOKEN_ADDRESSES.md and the cross-chain table there.
  3. Runbook for LINK support
    To enable 138→Mainnet LINK delivery, follow RELAY_BRIDGE_ADD_LINK_SUPPORT_RUNBOOK.md (extend bridge or deploy separate LINK receiver, then set relaySupported: true for LINK in token-mapping.json).

  4. Token lists and UIs
    When building token lists or UIs that show “Mainnet address” or “bridged address” for Chain 138 tokens, read from config/token-mapping.json or this doc. Do not assume every Chain 138 token has a Mainnet address; only WETH9 is relay-supported today; LINK has a canonical Mainnet address but is not yet relay-supported.


Multi-chain mapping (138↔651940, 651940↔other chains)

For 138↔651940 and 651940↔56, 137, 100, 43114, 8453, 42161, 10, 25, 1, use config/token-mapping-multichain.json. The same loader provides:

  • getTokenMappingForPair(fromChainId, toChainId) — returns { tokens, addressMapFromTo, addressMapToFrom }.
  • getAllMultichainPairs() — list of defined chain pairs.
  • getMappedAddress(fromChainId, toChainId, tokenAddress) — resolve token address on target chain.

See MAPPER_COVERAGE_BRIDGES_AND_LIQUIDITY_POOLS.md. To verify canonical token addresses per chain, use the explorer token lists in EXPLORER_TOKENS_CANONICAL_MAPPING.md.


References