foundry_evm_networks/
lib.rs

1//! # foundry-evm-networks
2//!
3//! Foundry EVM network configuration.
4
5use crate::celo::transfer::{
6    CELO_TRANSFER_ADDRESS, CELO_TRANSFER_LABEL, PRECOMPILE_ID_CELO_TRANSFER,
7};
8use alloy_chains::{
9    NamedChain,
10    NamedChain::{Chiado, Gnosis, Moonbase, Moonbeam, MoonbeamDev, Moonriver, Rsk, RskTestnet},
11};
12use alloy_eips::eip1559::BaseFeeParams;
13use alloy_evm::precompiles::PrecompilesMap;
14use alloy_op_hardforks::{OpChainHardforks, OpHardforks};
15use alloy_primitives::{Address, map::AddressHashMap};
16use clap::Parser;
17use serde::{Deserialize, Serialize};
18use std::collections::BTreeMap;
19
20pub mod celo;
21
22#[derive(Clone, Debug, Default, Parser, Copy, Serialize, Deserialize, PartialEq)]
23pub struct NetworkConfigs {
24    /// Enable Optimism network features.
25    #[arg(help_heading = "Networks", long, conflicts_with = "celo")]
26    // Skipped from configs (forge) as there is no feature to be added yet.
27    #[serde(skip)]
28    optimism: bool,
29    /// Enable Celo network features.
30    #[arg(help_heading = "Networks", long, conflicts_with = "optimism")]
31    #[serde(default)]
32    celo: bool,
33    /// Whether to bypass prevrandao.
34    #[arg(skip)]
35    #[serde(default)]
36    bypass_prevrandao: bool,
37}
38
39impl NetworkConfigs {
40    pub fn with_optimism() -> Self {
41        Self { optimism: true, ..Default::default() }
42    }
43
44    pub fn with_celo() -> Self {
45        Self { celo: true, ..Default::default() }
46    }
47
48    pub fn is_optimism(&self) -> bool {
49        self.optimism
50    }
51
52    /// Returns the base fee parameters for the configured network.
53    ///
54    /// For Optimism networks, returns Canyon parameters if the Canyon hardfork is active
55    /// at the given timestamp, otherwise returns pre-Canyon parameters.
56    pub fn base_fee_params(&self, timestamp: u64) -> BaseFeeParams {
57        if self.is_optimism() {
58            let op_hardforks = OpChainHardforks::op_mainnet();
59            if op_hardforks.is_canyon_active_at_timestamp(timestamp) {
60                BaseFeeParams::optimism_canyon()
61            } else {
62                BaseFeeParams::optimism()
63            }
64        } else {
65            BaseFeeParams::ethereum()
66        }
67    }
68
69    pub fn bypass_prevrandao(&self, chain_id: u64) -> bool {
70        if let Ok(
71            Moonbeam | Moonbase | Moonriver | MoonbeamDev | Rsk | RskTestnet | Gnosis | Chiado,
72        ) = NamedChain::try_from(chain_id)
73        {
74            return true;
75        }
76        self.bypass_prevrandao
77    }
78
79    pub fn is_celo(&self) -> bool {
80        self.celo
81    }
82
83    pub fn with_chain_id(mut self, chain_id: u64) -> Self {
84        if let Ok(NamedChain::Celo | NamedChain::CeloSepolia) = NamedChain::try_from(chain_id) {
85            self.celo = true;
86        }
87        self
88    }
89
90    /// Inject precompiles for configured networks.
91    pub fn inject_precompiles(self, precompiles: &mut PrecompilesMap) {
92        if self.celo {
93            precompiles.apply_precompile(&CELO_TRANSFER_ADDRESS, move |_| {
94                Some(celo::transfer::precompile())
95            });
96        }
97    }
98
99    /// Returns precompiles label for configured networks, to be used in traces.
100    pub fn precompiles_label(self) -> AddressHashMap<String> {
101        let mut labels = AddressHashMap::default();
102        if self.celo {
103            labels.insert(CELO_TRANSFER_ADDRESS, CELO_TRANSFER_LABEL.to_string());
104        }
105        labels
106    }
107
108    /// Returns precompiles for configured networks.
109    pub fn precompiles(self) -> BTreeMap<String, Address> {
110        let mut precompiles = BTreeMap::new();
111        if self.celo {
112            precompiles
113                .insert(PRECOMPILE_ID_CELO_TRANSFER.name().to_string(), CELO_TRANSFER_ADDRESS);
114        }
115        precompiles
116    }
117}