alloy_eips/eip1559/
basefee.rs

1use crate::{
2    calc_next_block_base_fee,
3    eip1559::constants::{
4        BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
5        DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR, DEFAULT_ELASTICITY_MULTIPLIER,
6        OP_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
7        OP_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
8        OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
9        OP_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
10        OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
11        OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
12    },
13};
14
15/// BaseFeeParams contains the config parameters that control block base fee computation
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
20pub struct BaseFeeParams {
21    /// The base_fee_max_change_denominator from EIP-1559
22    #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
23    pub max_change_denominator: u128,
24    /// The elasticity multiplier from EIP-1559
25    #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))]
26    pub elasticity_multiplier: u128,
27}
28
29impl BaseFeeParams {
30    /// Create a new BaseFeeParams
31    pub const fn new(max_change_denominator: u128, elasticity_multiplier: u128) -> Self {
32        Self { max_change_denominator, elasticity_multiplier }
33    }
34
35    /// Get the base fee parameters for Ethereum mainnet
36    pub const fn ethereum() -> Self {
37        Self {
38            max_change_denominator: DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
39            elasticity_multiplier: DEFAULT_ELASTICITY_MULTIPLIER as u128,
40        }
41    }
42
43    /// Get the base fee parameters for Optimism Mainnet
44    pub const fn optimism() -> Self {
45        Self {
46            max_change_denominator: OP_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
47            elasticity_multiplier: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
48        }
49    }
50
51    /// Get the base fee parameters for Optimism Mainnet (post Canyon)
52    pub const fn optimism_canyon() -> Self {
53        Self {
54            max_change_denominator: OP_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
55            elasticity_multiplier: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
56        }
57    }
58
59    /// Get the base fee parameters for Optimism Sepolia
60    pub const fn optimism_sepolia() -> Self {
61        Self {
62            max_change_denominator: OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
63            elasticity_multiplier: OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
64        }
65    }
66
67    /// Get the base fee parameters for Optimism Sepolia (post Canyon)
68    pub const fn optimism_sepolia_canyon() -> Self {
69        Self {
70            max_change_denominator: OP_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
71            elasticity_multiplier: OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
72        }
73    }
74
75    /// Get the base fee parameters for Base Sepolia
76    pub const fn base_sepolia() -> Self {
77        Self {
78            max_change_denominator: OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
79            elasticity_multiplier: BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
80        }
81    }
82
83    /// Get the base fee parameters for Base Sepolia (post Canyon)
84    pub const fn base_sepolia_canyon() -> Self {
85        Self {
86            max_change_denominator: OP_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
87            elasticity_multiplier: BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
88        }
89    }
90
91    /// Calculate the base fee for the next block based on the EIP-1559 specification.
92    ///
93    /// See also [calc_next_block_base_fee]
94    #[inline]
95    pub fn next_block_base_fee(self, gas_used: u64, gas_limit: u64, base_fee: u64) -> u64 {
96        calc_next_block_base_fee(gas_used, gas_limit, base_fee, self)
97    }
98}
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103    use arbitrary::Arbitrary;
104    use rand::Rng;
105
106    #[test]
107    fn test_arbitrary_base_fee_params() {
108        let mut bytes = [0u8; 1024];
109        rand::thread_rng().fill(bytes.as_mut_slice());
110        BaseFeeParams::arbitrary(&mut arbitrary::Unstructured::new(&bytes)).unwrap();
111    }
112}