Skip to main content

r402_evm/
networks.rs

1//! Well-known EVM network definitions and token deployments.
2//!
3//! This module provides static network metadata and USDC/USDM token deployment
4//! information for all supported EIP-155 chains.
5
6use std::sync::LazyLock;
7
8use r402::networks::NetworkInfo;
9
10use crate::chain::{Eip155ChainReference, Eip155TokenDeployment, TokenDeploymentEip712};
11
12/// Well-known EVM (EIP-155) networks with their names and CAIP-2 identifiers.
13///
14/// Source: <https://developers.circle.com/stablecoins/usdc-contract-addresses>
15pub static EVM_NETWORKS: &[NetworkInfo] = &[
16    NetworkInfo {
17        name: "ethereum",
18        namespace: "eip155",
19        reference: "1",
20    },
21    NetworkInfo {
22        name: "ethereum-sepolia",
23        namespace: "eip155",
24        reference: "11155111",
25    },
26    NetworkInfo {
27        name: "base",
28        namespace: "eip155",
29        reference: "8453",
30    },
31    NetworkInfo {
32        name: "base-sepolia",
33        namespace: "eip155",
34        reference: "84532",
35    },
36    NetworkInfo {
37        name: "arbitrum",
38        namespace: "eip155",
39        reference: "42161",
40    },
41    NetworkInfo {
42        name: "arbitrum-sepolia",
43        namespace: "eip155",
44        reference: "421614",
45    },
46    NetworkInfo {
47        name: "optimism",
48        namespace: "eip155",
49        reference: "10",
50    },
51    NetworkInfo {
52        name: "optimism-sepolia",
53        namespace: "eip155",
54        reference: "11155420",
55    },
56    NetworkInfo {
57        name: "polygon",
58        namespace: "eip155",
59        reference: "137",
60    },
61    NetworkInfo {
62        name: "polygon-amoy",
63        namespace: "eip155",
64        reference: "80002",
65    },
66    NetworkInfo {
67        name: "avalanche",
68        namespace: "eip155",
69        reference: "43114",
70    },
71    NetworkInfo {
72        name: "avalanche-fuji",
73        namespace: "eip155",
74        reference: "43113",
75    },
76    NetworkInfo {
77        name: "celo",
78        namespace: "eip155",
79        reference: "42220",
80    },
81    NetworkInfo {
82        name: "celo-sepolia",
83        namespace: "eip155",
84        reference: "11142220",
85    },
86    NetworkInfo {
87        name: "sei",
88        namespace: "eip155",
89        reference: "1329",
90    },
91    NetworkInfo {
92        name: "sei-testnet",
93        namespace: "eip155",
94        reference: "1328",
95    },
96    NetworkInfo {
97        name: "sonic",
98        namespace: "eip155",
99        reference: "146",
100    },
101    NetworkInfo {
102        name: "sonic-blaze",
103        namespace: "eip155",
104        reference: "57054",
105    },
106    NetworkInfo {
107        name: "unichain",
108        namespace: "eip155",
109        reference: "130",
110    },
111    NetworkInfo {
112        name: "unichain-sepolia",
113        namespace: "eip155",
114        reference: "1301",
115    },
116    NetworkInfo {
117        name: "world-chain",
118        namespace: "eip155",
119        reference: "480",
120    },
121    NetworkInfo {
122        name: "world-chain-sepolia",
123        namespace: "eip155",
124        reference: "4801",
125    },
126    NetworkInfo {
127        name: "zksync",
128        namespace: "eip155",
129        reference: "324",
130    },
131    NetworkInfo {
132        name: "zksync-sepolia",
133        namespace: "eip155",
134        reference: "300",
135    },
136    NetworkInfo {
137        name: "linea",
138        namespace: "eip155",
139        reference: "59144",
140    },
141    NetworkInfo {
142        name: "linea-sepolia",
143        namespace: "eip155",
144        reference: "59141",
145    },
146    NetworkInfo {
147        name: "ink",
148        namespace: "eip155",
149        reference: "57073",
150    },
151    NetworkInfo {
152        name: "ink-sepolia",
153        namespace: "eip155",
154        reference: "763373",
155    },
156    NetworkInfo {
157        name: "hyperevm",
158        namespace: "eip155",
159        reference: "999",
160    },
161    NetworkInfo {
162        name: "hyperevm-testnet",
163        namespace: "eip155",
164        reference: "998",
165    },
166    NetworkInfo {
167        name: "monad",
168        namespace: "eip155",
169        reference: "143",
170    },
171    NetworkInfo {
172        name: "monad-testnet",
173        namespace: "eip155",
174        reference: "10143",
175    },
176    NetworkInfo {
177        name: "plume",
178        namespace: "eip155",
179        reference: "98866",
180    },
181    NetworkInfo {
182        name: "plume-testnet",
183        namespace: "eip155",
184        reference: "98867",
185    },
186    NetworkInfo {
187        name: "codex",
188        namespace: "eip155",
189        reference: "81224",
190    },
191    NetworkInfo {
192        name: "codex-testnet",
193        namespace: "eip155",
194        reference: "812242",
195    },
196    NetworkInfo {
197        name: "xdc",
198        namespace: "eip155",
199        reference: "50",
200    },
201    NetworkInfo {
202        name: "xdc-apothem",
203        namespace: "eip155",
204        reference: "51",
205    },
206    NetworkInfo {
207        name: "xrpl-evm",
208        namespace: "eip155",
209        reference: "1440000",
210    },
211    NetworkInfo {
212        name: "peaq",
213        namespace: "eip155",
214        reference: "3338",
215    },
216    NetworkInfo {
217        name: "iotex",
218        namespace: "eip155",
219        reference: "4689",
220    },
221    NetworkInfo {
222        name: "megaeth",
223        namespace: "eip155",
224        reference: "4326",
225    },
226];
227
228/// Well-known USDC token deployments on EVM (EIP-155) networks.
229///
230/// This is the **single source of truth** for USDC contract addresses, decimal
231/// precision, and EIP-712 domain parameters on each supported EVM chain.
232///
233/// Use [`usdc_evm_deployment()`] for per-chain lookups, or [`usdc_evm_deployments()`]
234/// to iterate over all known deployments.
235///
236/// Source: <https://developers.circle.com/stablecoins/usdc-contract-addresses>
237static USDC_DEPLOYMENTS: LazyLock<Vec<Eip155TokenDeployment>> = LazyLock::new(|| {
238    vec![
239        // Ethereum mainnet — native Circle USDC (FiatTokenV2.1)
240        // Verify: https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
241        Eip155TokenDeployment {
242            chain_reference: Eip155ChainReference::new(1),
243            address: alloy_primitives::address!("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
244            decimals: 6,
245            eip712: Some(TokenDeploymentEip712 {
246                name: "USD Coin".into(),
247                version: "2".into(),
248            }),
249        },
250        // Ethereum Sepolia — native Circle USDC testnet
251        // Verify: https://sepolia.etherscan.io/address/0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238
252        Eip155TokenDeployment {
253            chain_reference: Eip155ChainReference::new(11_155_111),
254            address: alloy_primitives::address!("0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"),
255            decimals: 6,
256            eip712: Some(TokenDeploymentEip712 {
257                name: "USDC".into(),
258                version: "2".into(),
259            }),
260        },
261        // Base mainnet — native Circle USDC
262        // Verify: https://basescan.org/token/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
263        Eip155TokenDeployment {
264            chain_reference: Eip155ChainReference::new(8453),
265            address: alloy_primitives::address!("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"),
266            decimals: 6,
267            eip712: Some(TokenDeploymentEip712 {
268                name: "USD Coin".into(),
269                version: "2".into(),
270            }),
271        },
272        // Base Sepolia — native Circle USDC testnet
273        // Verify: https://base-sepolia.blockscout.com/address/0x036CbD53842c5426634e7929541eC2318f3dCF7e
274        Eip155TokenDeployment {
275            chain_reference: Eip155ChainReference::new(84532),
276            address: alloy_primitives::address!("0x036CbD53842c5426634e7929541eC2318f3dCF7e"),
277            decimals: 6,
278            eip712: Some(TokenDeploymentEip712 {
279                name: "USDC".into(),
280                version: "2".into(),
281            }),
282        },
283        // Arbitrum One — native Circle USDC
284        // Verify: https://arbiscan.io/token/0xaf88d065e77c8cC2239327C5EDb3A432268e5831
285        Eip155TokenDeployment {
286            chain_reference: Eip155ChainReference::new(42161),
287            address: alloy_primitives::address!("0xaf88d065e77c8cC2239327C5EDb3A432268e5831"),
288            decimals: 6,
289            eip712: Some(TokenDeploymentEip712 {
290                name: "USD Coin".into(),
291                version: "2".into(),
292            }),
293        },
294        // Arbitrum Sepolia — native Circle USDC testnet
295        // Verify: https://sepolia.arbiscan.io/address/0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d
296        Eip155TokenDeployment {
297            chain_reference: Eip155ChainReference::new(421_614),
298            address: alloy_primitives::address!("0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d"),
299            decimals: 6,
300            eip712: Some(TokenDeploymentEip712 {
301                name: "USDC".into(),
302                version: "2".into(),
303            }),
304        },
305        // OP Mainnet — native Circle USDC
306        // Verify: https://optimistic.etherscan.io/token/0x0b2c639c533813f4aa9d7837caf62653d097ff85
307        Eip155TokenDeployment {
308            chain_reference: Eip155ChainReference::new(10),
309            address: alloy_primitives::address!("0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"),
310            decimals: 6,
311            eip712: Some(TokenDeploymentEip712 {
312                name: "USD Coin".into(),
313                version: "2".into(),
314            }),
315        },
316        // OP Sepolia — native Circle USDC testnet
317        // Verify: https://sepolia-optimism.etherscan.io/address/0x5fd84259d66Cd46123540766Be93DFE6D43130D7
318        Eip155TokenDeployment {
319            chain_reference: Eip155ChainReference::new(11_155_420),
320            address: alloy_primitives::address!("0x5fd84259d66Cd46123540766Be93DFE6D43130D7"),
321            decimals: 6,
322            eip712: Some(TokenDeploymentEip712 {
323                name: "USDC".into(),
324                version: "2".into(),
325            }),
326        },
327        // Polygon PoS — native Circle USDC (not the old bridged USDC.e at 0x2791...)
328        // Verify: https://polygonscan.com/token/0x3c499c542cef5e3811e1192ce70d8cc03d5c3359
329        Eip155TokenDeployment {
330            chain_reference: Eip155ChainReference::new(137),
331            address: alloy_primitives::address!("0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"),
332            decimals: 6,
333            eip712: Some(TokenDeploymentEip712 {
334                name: "USDC".into(),
335                version: "2".into(),
336            }),
337        },
338        // Polygon Amoy — native Circle USDC testnet
339        // Verify: https://amoy.polygonscan.com/address/0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582
340        Eip155TokenDeployment {
341            chain_reference: Eip155ChainReference::new(80002),
342            address: alloy_primitives::address!("0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582"),
343            decimals: 6,
344            eip712: Some(TokenDeploymentEip712 {
345                name: "USDC".into(),
346                version: "2".into(),
347            }),
348        },
349        // Avalanche C-Chain — native Circle USDC
350        // Verify: https://snowtrace.io/token/0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E
351        Eip155TokenDeployment {
352            chain_reference: Eip155ChainReference::new(43114),
353            address: alloy_primitives::address!("0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"),
354            decimals: 6,
355            eip712: Some(TokenDeploymentEip712 {
356                name: "USD Coin".into(),
357                version: "2".into(),
358            }),
359        },
360        // Avalanche Fuji — native Circle USDC testnet
361        // Verify: https://testnet.snowtrace.io/token/0x5425890298aed601595a70ab815c96711a31bc65
362        Eip155TokenDeployment {
363            chain_reference: Eip155ChainReference::new(43113),
364            address: alloy_primitives::address!("0x5425890298aed601595a70AB815c96711a31Bc65"),
365            decimals: 6,
366            eip712: Some(TokenDeploymentEip712 {
367                name: "USD Coin".into(),
368                version: "2".into(),
369            }),
370        },
371        // Celo — native Circle USDC
372        // Verify: https://celoscan.io/token/0xcebA9300f2b948710d2653dD7B07f33A8B32118C
373        Eip155TokenDeployment {
374            chain_reference: Eip155ChainReference::new(42220),
375            address: alloy_primitives::address!("0xcebA9300f2b948710d2653dD7B07f33A8B32118C"),
376            decimals: 6,
377            eip712: Some(TokenDeploymentEip712 {
378                name: "USDC".into(),
379                version: "2".into(),
380            }),
381        },
382        // Celo Sepolia — native Circle USDC testnet
383        // Verify: https://celo-sepolia.blockscout.com/token/0x01C5C0122039549AD1493B8220cABEdD739BC44E
384        Eip155TokenDeployment {
385            chain_reference: Eip155ChainReference::new(11_142_220),
386            address: alloy_primitives::address!("0x01C5C0122039549AD1493B8220cABEdD739BC44E"),
387            decimals: 6,
388            eip712: Some(TokenDeploymentEip712 {
389                name: "USDC".into(),
390                version: "2".into(),
391            }),
392        },
393        // Sei — native Circle USDC
394        // Verify: https://seitrace.com/address/0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392?chain=pacific-1
395        Eip155TokenDeployment {
396            chain_reference: Eip155ChainReference::new(1329),
397            address: alloy_primitives::address!("0xe15fC38F6D8c56aF07bbCBe3BAf5708A2Bf42392"),
398            decimals: 6,
399            eip712: Some(TokenDeploymentEip712 {
400                name: "USDC".into(),
401                version: "2".into(),
402            }),
403        },
404        // Sei Testnet — native Circle USDC testnet
405        // Verify: https://seitrace.com/address/0x4fCF1784B31630811181f670Aea7A7bEF803eaED?chain=atlantic-2
406        Eip155TokenDeployment {
407            chain_reference: Eip155ChainReference::new(1328),
408            address: alloy_primitives::address!("0x4fCF1784B31630811181f670Aea7A7bEF803eaED"),
409            decimals: 6,
410            eip712: Some(TokenDeploymentEip712 {
411                name: "USDC".into(),
412                version: "2".into(),
413            }),
414        },
415        // Sonic — native Circle USDC
416        // Verify: https://sonicscan.org/token/0x29219dd400f2bf60e5a23d13be72b486d4038894
417        Eip155TokenDeployment {
418            chain_reference: Eip155ChainReference::new(146),
419            address: alloy_primitives::address!("0x29219dd400f2Bf60E5a23d13Be72B486D4038894"),
420            decimals: 6,
421            eip712: Some(TokenDeploymentEip712 {
422                name: "USDC".into(),
423                version: "2".into(),
424            }),
425        },
426        // Sonic Blaze Testnet — native Circle USDC testnet
427        // Verify: https://blaze.soniclabs.com/address/0xA4879Fed32Ecbef99399e5cbC247E533421C4eC6
428        Eip155TokenDeployment {
429            chain_reference: Eip155ChainReference::new(57054),
430            address: alloy_primitives::address!("0xA4879Fed32Ecbef99399e5cbC247E533421C4eC6"),
431            decimals: 6,
432            eip712: Some(TokenDeploymentEip712 {
433                name: "USDC".into(),
434                version: "2".into(),
435            }),
436        },
437        // Unichain — native Circle USDC
438        // Verify: https://uniscan.xyz/token/0x078d782b760474a361dda0af3839290b0ef57ad6
439        Eip155TokenDeployment {
440            chain_reference: Eip155ChainReference::new(130),
441            address: alloy_primitives::address!("0x078D782b760474a361dDA0AF3839290b0EF57AD6"),
442            decimals: 6,
443            eip712: Some(TokenDeploymentEip712 {
444                name: "USDC".into(),
445                version: "2".into(),
446            }),
447        },
448        // Unichain Sepolia — native Circle USDC testnet
449        // Verify: https://unichain-sepolia.blockscout.com/token/0x31d0220469e10c4E71834a79b1f276d740d3768F
450        Eip155TokenDeployment {
451            chain_reference: Eip155ChainReference::new(1301),
452            address: alloy_primitives::address!("0x31d0220469e10c4E71834a79b1f276d740d3768F"),
453            decimals: 6,
454            eip712: Some(TokenDeploymentEip712 {
455                name: "USDC".into(),
456                version: "2".into(),
457            }),
458        },
459        // World Chain — native Circle USDC
460        // Verify: https://worldscan.org/address/0x79A02482A880bCe3F13E09da970dC34dB4cD24D1
461        Eip155TokenDeployment {
462            chain_reference: Eip155ChainReference::new(480),
463            address: alloy_primitives::address!("0x79A02482A880bCe3F13E09da970dC34dB4cD24D1"),
464            decimals: 6,
465            eip712: Some(TokenDeploymentEip712 {
466                name: "USDC".into(),
467                version: "2".into(),
468            }),
469        },
470        // World Chain Sepolia — native Circle USDC testnet
471        // Verify: https://sepolia.worldscan.org/address/0x66145f38cBAC35Ca6F1Dfb4914dF98F1614aeA88
472        Eip155TokenDeployment {
473            chain_reference: Eip155ChainReference::new(4801),
474            address: alloy_primitives::address!("0x66145f38cBAC35Ca6F1Dfb4914dF98F1614aeA88"),
475            decimals: 6,
476            eip712: Some(TokenDeploymentEip712 {
477                name: "USDC".into(),
478                version: "2".into(),
479            }),
480        },
481        // ZKsync Era — native Circle USDC
482        // Verify: https://explorer.zksync.io/address/0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4
483        Eip155TokenDeployment {
484            chain_reference: Eip155ChainReference::new(324),
485            address: alloy_primitives::address!("0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4"),
486            decimals: 6,
487            eip712: Some(TokenDeploymentEip712 {
488                name: "USDC".into(),
489                version: "2".into(),
490            }),
491        },
492        // ZKsync Era Sepolia — native Circle USDC testnet
493        // Verify: https://sepolia.explorer.zksync.io/address/0xAe045DE5638162fa134807Cb558E15A3F5A7F853
494        Eip155TokenDeployment {
495            chain_reference: Eip155ChainReference::new(300),
496            address: alloy_primitives::address!("0xAe045DE5638162fa134807Cb558E15A3F5A7F853"),
497            decimals: 6,
498            eip712: Some(TokenDeploymentEip712 {
499                name: "USDC".into(),
500                version: "2".into(),
501            }),
502        },
503        // Linea — Circle USDC (upgraded from bridged to native via CCTP)
504        // Verify: https://lineascan.build/token/0x176211869ca2b568f2a7d4ee941e073a821ee1ff
505        Eip155TokenDeployment {
506            chain_reference: Eip155ChainReference::new(59144),
507            address: alloy_primitives::address!("0x176211869cA2b568f2A7D4EE941E073a821EE1ff"),
508            decimals: 6,
509            eip712: Some(TokenDeploymentEip712 {
510                name: "USDC".into(),
511                version: "2".into(),
512            }),
513        },
514        // Linea Sepolia — Circle USDC testnet
515        // Verify: https://sepolia.lineascan.build/address/0xFEce4462D57bD51A6A552365A011b95f0E16d9B7
516        Eip155TokenDeployment {
517            chain_reference: Eip155ChainReference::new(59141),
518            address: alloy_primitives::address!("0xFEce4462D57bD51A6A552365A011b95f0E16d9B7"),
519            decimals: 6,
520            eip712: Some(TokenDeploymentEip712 {
521                name: "USDC".into(),
522                version: "2".into(),
523            }),
524        },
525        // Ink (by Kraken) — native Circle USDC
526        // Verify: https://explorer.inkonchain.com/address/0x2D270e6886d130D724215A266106e6832161EAEd
527        Eip155TokenDeployment {
528            chain_reference: Eip155ChainReference::new(57073),
529            address: alloy_primitives::address!("0x2D270e6886d130D724215A266106e6832161EAEd"),
530            decimals: 6,
531            eip712: Some(TokenDeploymentEip712 {
532                name: "USDC".into(),
533                version: "2".into(),
534            }),
535        },
536        // Ink Sepolia — native Circle USDC testnet
537        // Verify: https://explorer-sepolia.inkonchain.com/address/0xFabab97dCE620294D2B0b0e46C68964e326300Ac
538        Eip155TokenDeployment {
539            chain_reference: Eip155ChainReference::new(763_373),
540            address: alloy_primitives::address!("0xFabab97dCE620294D2B0b0e46C68964e326300Ac"),
541            decimals: 6,
542            eip712: Some(TokenDeploymentEip712 {
543                name: "USDC".into(),
544                version: "2".into(),
545            }),
546        },
547        // HyperEVM (Hyperliquid) — native Circle USDC
548        // Verify: https://hyperscan.com/token/0xb88339CB7199b77E23DB6E890353E22632Ba630f
549        Eip155TokenDeployment {
550            chain_reference: Eip155ChainReference::new(999),
551            address: alloy_primitives::address!("0xb88339CB7199b77E23DB6E890353E22632Ba630f"),
552            decimals: 6,
553            eip712: Some(TokenDeploymentEip712 {
554                name: "USDC".into(),
555                version: "2".into(),
556            }),
557        },
558        // HyperEVM Testnet — native Circle USDC testnet
559        // Verify: https://testnet.purrsec.com/address/0x2B3370eE501B4a559b57D449569354196457D8Ab
560        Eip155TokenDeployment {
561            chain_reference: Eip155ChainReference::new(998),
562            address: alloy_primitives::address!("0x2B3370eE501B4a559b57D449569354196457D8Ab"),
563            decimals: 6,
564            eip712: Some(TokenDeploymentEip712 {
565                name: "USDC".into(),
566                version: "2".into(),
567            }),
568        },
569        // Monad — native Circle USDC
570        // Verify: https://monadvision.com/token/0x754704Bc059F8C67012fEd69BC8A327a5aafb603
571        Eip155TokenDeployment {
572            chain_reference: Eip155ChainReference::new(143),
573            address: alloy_primitives::address!("0x754704Bc059F8C67012fEd69BC8A327a5aafb603"),
574            decimals: 6,
575            eip712: Some(TokenDeploymentEip712 {
576                name: "USDC".into(),
577                version: "2".into(),
578            }),
579        },
580        // Monad Testnet — native Circle USDC testnet
581        // Verify: https://testnet.monadvision.com/token/0x534b2f3A21130d7a60830c2Df862319e593943A3
582        Eip155TokenDeployment {
583            chain_reference: Eip155ChainReference::new(10143),
584            address: alloy_primitives::address!("0x534b2f3A21130d7a60830c2Df862319e593943A3"),
585            decimals: 6,
586            eip712: Some(TokenDeploymentEip712 {
587                name: "USDC".into(),
588                version: "2".into(),
589            }),
590        },
591        // Plume — native Circle USDC
592        // Verify: https://explorer.plume.org/address/0x222365EF19F7947e5484218551B56bb3965Aa7aF
593        Eip155TokenDeployment {
594            chain_reference: Eip155ChainReference::new(98866),
595            address: alloy_primitives::address!("0x222365EF19F7947e5484218551B56bb3965Aa7aF"),
596            decimals: 6,
597            eip712: Some(TokenDeploymentEip712 {
598                name: "USDC".into(),
599                version: "2".into(),
600            }),
601        },
602        // Plume Testnet — native Circle USDC testnet
603        // Verify: https://testnet-explorer.plume.org/address/0xcB5f30e335672893c7eb944B374c196392C19D18
604        Eip155TokenDeployment {
605            chain_reference: Eip155ChainReference::new(98867),
606            address: alloy_primitives::address!("0xcB5f30e335672893c7eb944B374c196392C19D18"),
607            decimals: 6,
608            eip712: Some(TokenDeploymentEip712 {
609                name: "USDC".into(),
610                version: "2".into(),
611            }),
612        },
613        // Codex — native Circle USDC
614        // Verify: https://explorer.codex.xyz/address/0xd996633a415985DBd7D6D12f4A4343E31f5037cf
615        Eip155TokenDeployment {
616            chain_reference: Eip155ChainReference::new(81224),
617            address: alloy_primitives::address!("0xd996633a415985DBd7D6D12f4A4343E31f5037cf"),
618            decimals: 6,
619            eip712: Some(TokenDeploymentEip712 {
620                name: "USDC".into(),
621                version: "2".into(),
622            }),
623        },
624        // Codex Testnet — native Circle USDC testnet
625        // Verify: https://explorer.codex-stg.xyz/address/0x6d7f141b6819C2c9CC2f818e6ad549E7Ca090F8f
626        Eip155TokenDeployment {
627            chain_reference: Eip155ChainReference::new(812_242),
628            address: alloy_primitives::address!("0x6d7f141b6819C2c9CC2f818e6ad549E7Ca090F8f"),
629            decimals: 6,
630            eip712: Some(TokenDeploymentEip712 {
631                name: "USDC".into(),
632                version: "2".into(),
633            }),
634        },
635        // XDC Network — native Circle USDC
636        // Verify: https://xdcscan.com/address/0xfA2958CB79b0491CC627c1557F441eF849Ca8eb1
637        Eip155TokenDeployment {
638            chain_reference: Eip155ChainReference::new(50),
639            address: alloy_primitives::address!("0xfA2958CB79b0491CC627c1557F441eF849Ca8eb1"),
640            decimals: 6,
641            eip712: Some(TokenDeploymentEip712 {
642                name: "USDC".into(),
643                version: "2".into(),
644            }),
645        },
646        // XDC Apothem Testnet — native Circle USDC testnet
647        // Verify: https://testnet.xdcscan.com/address/0xb5AB69F7bBada22B28e79C8FFAECe55eF1c771D4
648        Eip155TokenDeployment {
649            chain_reference: Eip155ChainReference::new(51),
650            address: alloy_primitives::address!("0xb5AB69F7bBada22B28e79C8FFAECe55eF1c771D4"),
651            decimals: 6,
652            eip712: Some(TokenDeploymentEip712 {
653                name: "USDC".into(),
654                version: "2".into(),
655            }),
656        },
657        // XRPL EVM sidechain — community deployment, not on Circle official page
658        // EIP-3009 support unverified (eip712: None)
659        Eip155TokenDeployment {
660            chain_reference: Eip155ChainReference::new(1_440_000),
661            address: alloy_primitives::address!("0xDaF4556169c4F3f2231d8ab7BC8772Ddb7D4c84C"),
662            decimals: 6,
663            eip712: None,
664        },
665        // Peaq — community deployment, not on Circle official page
666        // EIP-3009 support unverified
667        Eip155TokenDeployment {
668            chain_reference: Eip155ChainReference::new(3338),
669            address: alloy_primitives::address!("0xbbA60da06c2c5424f03f7434542280FCAd453d10"),
670            decimals: 6,
671            eip712: Some(TokenDeploymentEip712 {
672                name: "USDC".into(),
673                version: "2".into(),
674            }),
675        },
676        // IoTeX — community deployment, not on Circle official page
677        // EIP-3009 support unverified
678        Eip155TokenDeployment {
679            chain_reference: Eip155ChainReference::new(4689),
680            address: alloy_primitives::address!("0xcdf79194c6c285077a58da47641d4dbe51f63542"),
681            decimals: 6,
682            eip712: Some(TokenDeploymentEip712 {
683                name: "Bridged USDC".into(),
684                version: "2".into(),
685            }),
686        },
687    ]
688});
689
690/// Well-known USDM token deployments on EVM (EIP-155) networks.
691///
692/// Use [`usdm_evm_deployment()`] for per-chain lookups.
693static USDM_DEPLOYMENTS: LazyLock<Vec<Eip155TokenDeployment>> = LazyLock::new(|| {
694    vec![
695        // MegaETH — MegaUSD (USDM), the chain's endorsed default stablecoin
696        // Matches Go SDK: eip155:4326, name "MegaUSD", version "1", decimals 18
697        Eip155TokenDeployment {
698            chain_reference: Eip155ChainReference::new(4326),
699            address: alloy_primitives::address!("0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7"),
700            decimals: 18,
701            eip712: Some(TokenDeploymentEip712 {
702                name: "MegaUSD".into(),
703                version: "1".into(),
704            }),
705        },
706    ]
707});
708
709/// Returns all known USDC deployments on EVM chains.
710#[must_use]
711pub fn usdc_evm_deployments() -> &'static [Eip155TokenDeployment] {
712    &USDC_DEPLOYMENTS
713}
714
715/// Returns the USDC deployment for a specific EVM chain, if known.
716#[must_use]
717pub fn usdc_evm_deployment(chain: &Eip155ChainReference) -> Option<&'static Eip155TokenDeployment> {
718    USDC_DEPLOYMENTS
719        .iter()
720        .find(|d| d.chain_reference == *chain)
721}
722
723/// Returns all known USDM deployments on EVM chains.
724#[must_use]
725pub fn usdm_evm_deployments() -> &'static [Eip155TokenDeployment] {
726    &USDM_DEPLOYMENTS
727}
728
729/// Returns the USDM deployment for a specific EVM chain, if known.
730#[must_use]
731pub fn usdm_evm_deployment(chain: &Eip155ChainReference) -> Option<&'static Eip155TokenDeployment> {
732    USDM_DEPLOYMENTS
733        .iter()
734        .find(|d| d.chain_reference == *chain)
735}
736
737/// Ergonomic accessors for USDC token deployments on well-known EVM chains.
738///
739/// Provides named methods for each supported chain, returning a static
740/// reference to the deployment metadata. Combine with
741/// [`Eip155TokenDeployment::amount`] for a fluent pricing API:
742///
743/// ```ignore
744/// use r402_evm::{Eip155Exact, USDC};
745///
746/// let tag = Eip155Exact::price_tag(pay_to, USDC::base().amount(1_000_000u64), None);
747/// ```
748#[derive(Debug, Clone, Copy)]
749pub struct USDC;
750
751#[allow(clippy::doc_markdown, clippy::missing_panics_doc)]
752impl USDC {
753    /// Looks up a USDC deployment by chain reference.
754    ///
755    /// Returns `None` if the chain is not in the built-in deployment table.
756    #[must_use]
757    pub fn on(chain: &Eip155ChainReference) -> Option<&'static Eip155TokenDeployment> {
758        usdc_evm_deployment(chain)
759    }
760
761    /// Returns all known USDC deployments.
762    #[must_use]
763    pub fn all() -> &'static [Eip155TokenDeployment] {
764        usdc_evm_deployments()
765    }
766
767    /// USDC on Ethereum mainnet (eip155:1).
768    #[must_use]
769    pub fn ethereum() -> &'static Eip155TokenDeployment {
770        usdc_evm_deployment(&Eip155ChainReference::new(1))
771            .expect("built-in USDC deployment for Ethereum missing")
772    }
773
774    /// USDC on Ethereum Sepolia testnet (eip155:11155111).
775    #[must_use]
776    pub fn ethereum_sepolia() -> &'static Eip155TokenDeployment {
777        usdc_evm_deployment(&Eip155ChainReference::new(11_155_111))
778            .expect("built-in USDC deployment for Ethereum Sepolia missing")
779    }
780
781    /// USDC on Base mainnet (eip155:8453).
782    #[must_use]
783    pub fn base() -> &'static Eip155TokenDeployment {
784        usdc_evm_deployment(&Eip155ChainReference::new(8453))
785            .expect("built-in USDC deployment for Base missing")
786    }
787
788    /// USDC on Base Sepolia testnet (eip155:84532).
789    #[must_use]
790    pub fn base_sepolia() -> &'static Eip155TokenDeployment {
791        usdc_evm_deployment(&Eip155ChainReference::new(84532))
792            .expect("built-in USDC deployment for Base Sepolia missing")
793    }
794
795    /// USDC on Arbitrum One (eip155:42161).
796    #[must_use]
797    pub fn arbitrum() -> &'static Eip155TokenDeployment {
798        usdc_evm_deployment(&Eip155ChainReference::new(42161))
799            .expect("built-in USDC deployment for Arbitrum missing")
800    }
801
802    /// USDC on Arbitrum Sepolia testnet (eip155:421614).
803    #[must_use]
804    pub fn arbitrum_sepolia() -> &'static Eip155TokenDeployment {
805        usdc_evm_deployment(&Eip155ChainReference::new(421_614))
806            .expect("built-in USDC deployment for Arbitrum Sepolia missing")
807    }
808
809    /// USDC on OP Mainnet (eip155:10).
810    #[must_use]
811    pub fn optimism() -> &'static Eip155TokenDeployment {
812        usdc_evm_deployment(&Eip155ChainReference::new(10))
813            .expect("built-in USDC deployment for Optimism missing")
814    }
815
816    /// USDC on OP Sepolia testnet (eip155:11155420).
817    #[must_use]
818    pub fn optimism_sepolia() -> &'static Eip155TokenDeployment {
819        usdc_evm_deployment(&Eip155ChainReference::new(11_155_420))
820            .expect("built-in USDC deployment for OP Sepolia missing")
821    }
822
823    /// USDC on Polygon PoS (eip155:137).
824    #[must_use]
825    pub fn polygon() -> &'static Eip155TokenDeployment {
826        usdc_evm_deployment(&Eip155ChainReference::new(137))
827            .expect("built-in USDC deployment for Polygon missing")
828    }
829
830    /// USDC on Polygon Amoy testnet (eip155:80002).
831    #[must_use]
832    pub fn polygon_amoy() -> &'static Eip155TokenDeployment {
833        usdc_evm_deployment(&Eip155ChainReference::new(80002))
834            .expect("built-in USDC deployment for Polygon Amoy missing")
835    }
836
837    /// USDC on Avalanche C-Chain (eip155:43114).
838    #[must_use]
839    pub fn avalanche() -> &'static Eip155TokenDeployment {
840        usdc_evm_deployment(&Eip155ChainReference::new(43114))
841            .expect("built-in USDC deployment for Avalanche missing")
842    }
843
844    /// USDC on Avalanche Fuji testnet (eip155:43113).
845    #[must_use]
846    pub fn avalanche_fuji() -> &'static Eip155TokenDeployment {
847        usdc_evm_deployment(&Eip155ChainReference::new(43113))
848            .expect("built-in USDC deployment for Avalanche Fuji missing")
849    }
850
851    /// USDC on Celo (eip155:42220).
852    #[must_use]
853    pub fn celo() -> &'static Eip155TokenDeployment {
854        usdc_evm_deployment(&Eip155ChainReference::new(42220))
855            .expect("built-in USDC deployment for Celo missing")
856    }
857
858    /// USDC on Celo Sepolia testnet (eip155:11142220).
859    #[must_use]
860    pub fn celo_sepolia() -> &'static Eip155TokenDeployment {
861        usdc_evm_deployment(&Eip155ChainReference::new(11_142_220))
862            .expect("built-in USDC deployment for Celo Sepolia missing")
863    }
864
865    /// USDC on Sonic (eip155:146).
866    #[must_use]
867    pub fn sonic() -> &'static Eip155TokenDeployment {
868        usdc_evm_deployment(&Eip155ChainReference::new(146))
869            .expect("built-in USDC deployment for Sonic missing")
870    }
871
872    /// USDC on Sonic Blaze testnet (eip155:57054).
873    #[must_use]
874    pub fn sonic_blaze() -> &'static Eip155TokenDeployment {
875        usdc_evm_deployment(&Eip155ChainReference::new(57054))
876            .expect("built-in USDC deployment for Sonic Blaze missing")
877    }
878
879    /// USDC on Unichain (eip155:130).
880    #[must_use]
881    pub fn unichain() -> &'static Eip155TokenDeployment {
882        usdc_evm_deployment(&Eip155ChainReference::new(130))
883            .expect("built-in USDC deployment for Unichain missing")
884    }
885
886    /// USDC on Unichain Sepolia testnet (eip155:1301).
887    #[must_use]
888    pub fn unichain_sepolia() -> &'static Eip155TokenDeployment {
889        usdc_evm_deployment(&Eip155ChainReference::new(1301))
890            .expect("built-in USDC deployment for Unichain Sepolia missing")
891    }
892
893    /// USDC on World Chain (eip155:480).
894    #[must_use]
895    pub fn world_chain() -> &'static Eip155TokenDeployment {
896        usdc_evm_deployment(&Eip155ChainReference::new(480))
897            .expect("built-in USDC deployment for World Chain missing")
898    }
899
900    /// USDC on World Chain Sepolia testnet (eip155:4801).
901    #[must_use]
902    pub fn world_chain_sepolia() -> &'static Eip155TokenDeployment {
903        usdc_evm_deployment(&Eip155ChainReference::new(4801))
904            .expect("built-in USDC deployment for World Chain Sepolia missing")
905    }
906
907    /// USDC on ZKsync Era (eip155:324).
908    #[must_use]
909    pub fn zksync() -> &'static Eip155TokenDeployment {
910        usdc_evm_deployment(&Eip155ChainReference::new(324))
911            .expect("built-in USDC deployment for ZKsync missing")
912    }
913
914    /// USDC on ZKsync Era Sepolia testnet (eip155:300).
915    #[must_use]
916    pub fn zksync_sepolia() -> &'static Eip155TokenDeployment {
917        usdc_evm_deployment(&Eip155ChainReference::new(300))
918            .expect("built-in USDC deployment for ZKsync Sepolia missing")
919    }
920
921    /// USDC on Linea (eip155:59144).
922    #[must_use]
923    pub fn linea() -> &'static Eip155TokenDeployment {
924        usdc_evm_deployment(&Eip155ChainReference::new(59144))
925            .expect("built-in USDC deployment for Linea missing")
926    }
927
928    /// USDC on Linea Sepolia testnet (eip155:59141).
929    #[must_use]
930    pub fn linea_sepolia() -> &'static Eip155TokenDeployment {
931        usdc_evm_deployment(&Eip155ChainReference::new(59141))
932            .expect("built-in USDC deployment for Linea Sepolia missing")
933    }
934
935    /// USDC on Ink (eip155:57073).
936    #[must_use]
937    pub fn ink() -> &'static Eip155TokenDeployment {
938        usdc_evm_deployment(&Eip155ChainReference::new(57073))
939            .expect("built-in USDC deployment for Ink missing")
940    }
941
942    /// USDC on Ink Sepolia testnet (eip155:763373).
943    #[must_use]
944    pub fn ink_sepolia() -> &'static Eip155TokenDeployment {
945        usdc_evm_deployment(&Eip155ChainReference::new(763_373))
946            .expect("built-in USDC deployment for Ink Sepolia missing")
947    }
948
949    /// USDC on Sei (eip155:1329).
950    #[must_use]
951    pub fn sei() -> &'static Eip155TokenDeployment {
952        usdc_evm_deployment(&Eip155ChainReference::new(1329))
953            .expect("built-in USDC deployment for Sei missing")
954    }
955
956    /// USDC on Sei testnet (eip155:1328).
957    #[must_use]
958    pub fn sei_testnet() -> &'static Eip155TokenDeployment {
959        usdc_evm_deployment(&Eip155ChainReference::new(1328))
960            .expect("built-in USDC deployment for Sei testnet missing")
961    }
962
963    /// USDC on HyperEVM (eip155:999).
964    #[must_use]
965    pub fn hyperevm() -> &'static Eip155TokenDeployment {
966        usdc_evm_deployment(&Eip155ChainReference::new(999))
967            .expect("built-in USDC deployment for HyperEVM missing")
968    }
969
970    /// USDC on HyperEVM testnet (eip155:998).
971    #[must_use]
972    pub fn hyperevm_testnet() -> &'static Eip155TokenDeployment {
973        usdc_evm_deployment(&Eip155ChainReference::new(998))
974            .expect("built-in USDC deployment for HyperEVM testnet missing")
975    }
976
977    /// USDC on Monad (eip155:143).
978    #[must_use]
979    pub fn monad() -> &'static Eip155TokenDeployment {
980        usdc_evm_deployment(&Eip155ChainReference::new(143))
981            .expect("built-in USDC deployment for Monad missing")
982    }
983
984    /// USDC on Monad testnet (eip155:10143).
985    #[must_use]
986    pub fn monad_testnet() -> &'static Eip155TokenDeployment {
987        usdc_evm_deployment(&Eip155ChainReference::new(10143))
988            .expect("built-in USDC deployment for Monad testnet missing")
989    }
990
991    /// USDC on Plume (eip155:98866).
992    #[must_use]
993    pub fn plume() -> &'static Eip155TokenDeployment {
994        usdc_evm_deployment(&Eip155ChainReference::new(98866))
995            .expect("built-in USDC deployment for Plume missing")
996    }
997
998    /// USDC on Plume testnet (eip155:98867).
999    #[must_use]
1000    pub fn plume_testnet() -> &'static Eip155TokenDeployment {
1001        usdc_evm_deployment(&Eip155ChainReference::new(98867))
1002            .expect("built-in USDC deployment for Plume testnet missing")
1003    }
1004
1005    /// USDC on Codex (eip155:81224).
1006    #[must_use]
1007    pub fn codex() -> &'static Eip155TokenDeployment {
1008        usdc_evm_deployment(&Eip155ChainReference::new(81224))
1009            .expect("built-in USDC deployment for Codex missing")
1010    }
1011
1012    /// USDC on Codex testnet (eip155:812242).
1013    #[must_use]
1014    pub fn codex_testnet() -> &'static Eip155TokenDeployment {
1015        usdc_evm_deployment(&Eip155ChainReference::new(812_242))
1016            .expect("built-in USDC deployment for Codex testnet missing")
1017    }
1018
1019    /// USDC on XDC Network (eip155:50).
1020    #[must_use]
1021    pub fn xdc() -> &'static Eip155TokenDeployment {
1022        usdc_evm_deployment(&Eip155ChainReference::new(50))
1023            .expect("built-in USDC deployment for XDC missing")
1024    }
1025
1026    /// USDC on XDC Apothem testnet (eip155:51).
1027    #[must_use]
1028    pub fn xdc_apothem() -> &'static Eip155TokenDeployment {
1029        usdc_evm_deployment(&Eip155ChainReference::new(51))
1030            .expect("built-in USDC deployment for XDC Apothem missing")
1031    }
1032}
1033
1034/// Ergonomic accessors for USDM (`MegaUSD`) token deployments on EVM chains.
1035///
1036/// ```ignore
1037/// use r402_evm::{Eip155Exact, USDM};
1038///
1039/// let tag = Eip155Exact::price_tag(pay_to, USDM::megaeth().amount(1_000_000_000_000_000_000u128), None);
1040/// ```
1041#[derive(Debug, Clone, Copy)]
1042pub struct USDM;
1043
1044#[allow(clippy::doc_markdown, clippy::missing_panics_doc)]
1045impl USDM {
1046    /// Looks up a USDM deployment by chain reference.
1047    #[must_use]
1048    pub fn on(chain: &Eip155ChainReference) -> Option<&'static Eip155TokenDeployment> {
1049        usdm_evm_deployment(chain)
1050    }
1051
1052    /// Returns all known USDM deployments.
1053    #[must_use]
1054    pub fn all() -> &'static [Eip155TokenDeployment] {
1055        usdm_evm_deployments()
1056    }
1057
1058    /// USDM (MegaUSD) on MegaETH (eip155:4326).
1059    #[must_use]
1060    pub fn megaeth() -> &'static Eip155TokenDeployment {
1061        usdm_evm_deployment(&Eip155ChainReference::new(4326))
1062            .expect("built-in USDM deployment for MegaETH missing")
1063    }
1064}