1use alloy_eips::eip1559::BaseFeeParams;
4
5use crate::{
6 BASE_MAINNET_CHAIN_ID, BASE_SEPOLIA_CHAIN_ID, OP_MAINNET_CHAIN_ID, OP_SEPOLIA_CHAIN_ID,
7};
8
9pub const OP_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 50;
12
13pub const OP_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON: u64 = 250;
16
17pub const OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u64 = 6;
20
21pub const OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 50;
24
25pub const OP_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON: u64 = 250;
28
29pub const OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u64 = 6;
32
33pub const BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u64 = 10;
36
37pub const BASE_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 50;
40
41pub const BASE_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON: u64 = 250;
44
45pub const BASE_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u64 = 6;
48
49pub const BASE_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 50;
52
53pub const BASE_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON: u64 = 250;
56
57pub const OP_SEPOLIA_BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams {
59 max_change_denominator: OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
60 elasticity_multiplier: OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER as u128,
61};
62
63pub const BASE_SEPOLIA_BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams {
65 max_change_denominator: OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
66 elasticity_multiplier: BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER as u128,
67};
68
69pub const OP_MAINNET_BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams {
71 max_change_denominator: OP_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
72 elasticity_multiplier: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER as u128,
73};
74
75pub const OP_SEPOLIA_BASE_FEE_PARAMS_CANYON: BaseFeeParams = BaseFeeParams {
77 max_change_denominator: OP_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON as u128,
78 elasticity_multiplier: OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER as u128,
79};
80
81pub const BASE_SEPOLIA_BASE_FEE_PARAMS_CANYON: BaseFeeParams = BaseFeeParams {
83 max_change_denominator: OP_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON as u128,
84 elasticity_multiplier: BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER as u128,
85};
86
87pub const OP_MAINNET_BASE_FEE_PARAMS_CANYON: BaseFeeParams = BaseFeeParams {
89 max_change_denominator: OP_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON as u128,
90 elasticity_multiplier: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER as u128,
91};
92
93pub const fn base_fee_params(chain_id: u64) -> BaseFeeParams {
95 match chain_id {
96 OP_MAINNET_CHAIN_ID => OP_MAINNET_BASE_FEE_PARAMS,
97 OP_SEPOLIA_CHAIN_ID => OP_SEPOLIA_BASE_FEE_PARAMS,
98 BASE_MAINNET_CHAIN_ID => OP_MAINNET_BASE_FEE_PARAMS,
99 BASE_SEPOLIA_CHAIN_ID => BASE_SEPOLIA_BASE_FEE_PARAMS,
100 _ => OP_MAINNET_BASE_FEE_PARAMS,
101 }
102}
103
104pub const fn base_fee_params_canyon(chain_id: u64) -> BaseFeeParams {
106 match chain_id {
107 OP_MAINNET_CHAIN_ID => OP_MAINNET_BASE_FEE_PARAMS_CANYON,
108 OP_SEPOLIA_CHAIN_ID => OP_SEPOLIA_BASE_FEE_PARAMS_CANYON,
109 BASE_MAINNET_CHAIN_ID => OP_MAINNET_BASE_FEE_PARAMS_CANYON,
110 BASE_SEPOLIA_CHAIN_ID => BASE_SEPOLIA_BASE_FEE_PARAMS_CANYON,
111 _ => OP_MAINNET_BASE_FEE_PARAMS_CANYON,
112 }
113}
114
115pub const fn base_fee_config(chain_id: u64) -> BaseFeeConfig {
117 match chain_id {
118 OP_MAINNET_CHAIN_ID => OP_MAINNET_BASE_FEE_CONFIG,
119 OP_SEPOLIA_CHAIN_ID => OP_SEPOLIA_BASE_FEE_CONFIG,
120 BASE_MAINNET_CHAIN_ID => BASE_MAINNET_BASE_FEE_CONFIG,
121 BASE_SEPOLIA_CHAIN_ID => BASE_SEPOLIA_BASE_FEE_CONFIG,
122 _ => OP_MAINNET_BASE_FEE_CONFIG,
123 }
124}
125
126pub const OP_SEPOLIA_BASE_FEE_CONFIG: BaseFeeConfig = BaseFeeConfig {
128 eip1559_elasticity: OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
129 eip1559_denominator: OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
130 eip1559_denominator_canyon: OP_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
131};
132
133pub const BASE_SEPOLIA_BASE_FEE_CONFIG: BaseFeeConfig = BaseFeeConfig {
135 eip1559_elasticity: BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
136 eip1559_denominator: BASE_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
137 eip1559_denominator_canyon: BASE_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
138};
139
140pub const OP_MAINNET_BASE_FEE_CONFIG: BaseFeeConfig = BaseFeeConfig {
142 eip1559_elasticity: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
143 eip1559_denominator: OP_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
144 eip1559_denominator_canyon: OP_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
145};
146
147pub const BASE_MAINNET_BASE_FEE_CONFIG: BaseFeeConfig = BaseFeeConfig {
149 eip1559_elasticity: BASE_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
150 eip1559_denominator: BASE_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
151 eip1559_denominator_canyon: BASE_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
152};
153
154#[derive(Debug, Copy, Clone, Eq, PartialEq)]
156#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
157#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
158pub struct BaseFeeConfig {
159 #[cfg_attr(
161 feature = "serde",
162 serde(rename = "eip1559Elasticity", alias = "eip1559_elasticity")
163 )]
164 pub eip1559_elasticity: u64,
165 #[cfg_attr(
167 feature = "serde",
168 serde(rename = "eip1559Denominator", alias = "eip1559_denominator")
169 )]
170 pub eip1559_denominator: u64,
171 #[cfg_attr(
173 feature = "serde",
174 serde(rename = "eip1559DenominatorCanyon", alias = "eip1559_denominator_canyon")
175 )]
176 pub eip1559_denominator_canyon: u64,
177}
178
179impl BaseFeeConfig {
180 pub const fn optimism() -> Self {
182 Self {
183 eip1559_elasticity: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
184 eip1559_denominator: OP_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
185 eip1559_denominator_canyon: OP_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
186 }
187 }
188
189 pub const fn as_base_fee_params(&self) -> BaseFeeParams {
191 BaseFeeParams {
192 max_change_denominator: self.eip1559_denominator as u128,
193 elasticity_multiplier: self.eip1559_elasticity as u128,
194 }
195 }
196
197 pub const fn as_canyon_base_fee_params(&self) -> BaseFeeParams {
199 BaseFeeParams {
200 max_change_denominator: self.eip1559_denominator_canyon as u128,
201 elasticity_multiplier: self.eip1559_elasticity as u128,
202 }
203 }
204}
205
206#[cfg(test)]
207mod tests {
208 use super::*;
209
210 #[test]
211 fn test_base_fee_params_from_chain_id() {
212 assert_eq!(base_fee_params(OP_MAINNET_CHAIN_ID), OP_MAINNET_BASE_FEE_PARAMS);
213 assert_eq!(base_fee_params(OP_SEPOLIA_CHAIN_ID), OP_SEPOLIA_BASE_FEE_PARAMS);
214 assert_eq!(base_fee_params(BASE_MAINNET_CHAIN_ID), OP_MAINNET_BASE_FEE_PARAMS);
215 assert_eq!(base_fee_params(BASE_SEPOLIA_CHAIN_ID), BASE_SEPOLIA_BASE_FEE_PARAMS);
216 assert_eq!(base_fee_params(0), OP_MAINNET_BASE_FEE_PARAMS);
217 }
218
219 #[test]
220 fn test_base_fee_params_canyon_from_chain_id() {
221 assert_eq!(base_fee_params_canyon(OP_MAINNET_CHAIN_ID), OP_MAINNET_BASE_FEE_PARAMS_CANYON);
222 assert_eq!(base_fee_params_canyon(OP_SEPOLIA_CHAIN_ID), OP_SEPOLIA_BASE_FEE_PARAMS_CANYON);
223 assert_eq!(
224 base_fee_params_canyon(BASE_MAINNET_CHAIN_ID),
225 OP_MAINNET_BASE_FEE_PARAMS_CANYON
226 );
227 assert_eq!(
228 base_fee_params_canyon(BASE_SEPOLIA_CHAIN_ID),
229 BASE_SEPOLIA_BASE_FEE_PARAMS_CANYON
230 );
231 assert_eq!(base_fee_params_canyon(0), OP_MAINNET_BASE_FEE_PARAMS_CANYON);
232 }
233
234 #[test]
235 #[cfg(feature = "serde")]
236 fn test_base_fee_config_ser() {
237 let config = OP_MAINNET_BASE_FEE_CONFIG;
238 let raw_str = serde_json::to_string(&config).unwrap();
239 assert_eq!(
240 raw_str,
241 r#"{"eip1559Elasticity":6,"eip1559Denominator":50,"eip1559DenominatorCanyon":250}"#
242 );
243 }
244
245 #[test]
246 #[cfg(feature = "serde")]
247 fn test_base_fee_config_deser() {
248 let raw_str: &'static str =
249 r#"{"eip1559Elasticity":6,"eip1559Denominator":50,"eip1559DenominatorCanyon":250}"#;
250 let config: BaseFeeConfig = serde_json::from_str(raw_str).unwrap();
251 assert_eq!(config, OP_MAINNET_BASE_FEE_CONFIG);
252 }
253}