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: u128 = 50;
12
13pub const OP_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON: u128 = 250;
16
17pub const OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u128 = 6;
20
21pub const OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u128 = 50;
24
25pub const OP_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON: u128 = 250;
28
29pub const OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u128 = 6;
32
33pub const BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u128 = 10;
36
37pub const BASE_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u128 = 50;
40
41pub const BASE_SEPOLIA_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON: u128 = 250;
44
45pub const BASE_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER: u128 = 6;
48
49pub const BASE_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR: u128 = 50;
52
53pub const BASE_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON: u128 = 250;
56
57pub const OP_SEPOLIA_BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams {
59 max_change_denominator: OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
60 elasticity_multiplier: OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
61};
62
63pub const BASE_SEPOLIA_BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams {
65 max_change_denominator: OP_SEPOLIA_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
66 elasticity_multiplier: BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
67};
68
69pub const OP_MAINNET_BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams {
71 max_change_denominator: OP_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
72 elasticity_multiplier: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
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,
78 elasticity_multiplier: OP_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
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,
84 elasticity_multiplier: BASE_SEPOLIA_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
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,
90 elasticity_multiplier: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
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 #[cfg_attr(feature = "serde", serde(with = "kona_serde::quantity"))]
165 pub eip1559_elasticity: u128,
166 #[cfg_attr(
168 feature = "serde",
169 serde(rename = "eip1559Denominator", alias = "eip1559_denominator")
170 )]
171 #[cfg_attr(feature = "serde", serde(with = "kona_serde::quantity"))]
172 pub eip1559_denominator: u128,
173 #[cfg_attr(
175 feature = "serde",
176 serde(rename = "eip1559DenominatorCanyon", alias = "eip1559_denominator_canyon")
177 )]
178 #[cfg_attr(feature = "serde", serde(with = "kona_serde::quantity"))]
179 pub eip1559_denominator_canyon: u128,
180}
181
182impl BaseFeeConfig {
183 pub const fn optimism() -> Self {
185 Self {
186 eip1559_elasticity: OP_MAINNET_EIP1559_DEFAULT_ELASTICITY_MULTIPLIER,
187 eip1559_denominator: OP_MAINNET_EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR,
188 eip1559_denominator_canyon: OP_MAINNET_EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR_CANYON,
189 }
190 }
191
192 pub const fn as_base_fee_params(&self) -> BaseFeeParams {
194 BaseFeeParams {
195 max_change_denominator: self.eip1559_denominator,
196 elasticity_multiplier: self.eip1559_elasticity,
197 }
198 }
199
200 pub const fn as_canyon_base_fee_params(&self) -> BaseFeeParams {
202 BaseFeeParams {
203 max_change_denominator: self.eip1559_denominator_canyon,
204 elasticity_multiplier: self.eip1559_elasticity,
205 }
206 }
207}
208
209#[cfg(test)]
210mod tests {
211 use super::*;
212
213 #[test]
214 fn test_base_fee_params_from_chain_id() {
215 assert_eq!(base_fee_params(OP_MAINNET_CHAIN_ID), OP_MAINNET_BASE_FEE_PARAMS);
216 assert_eq!(base_fee_params(OP_SEPOLIA_CHAIN_ID), OP_SEPOLIA_BASE_FEE_PARAMS);
217 assert_eq!(base_fee_params(BASE_MAINNET_CHAIN_ID), OP_MAINNET_BASE_FEE_PARAMS);
218 assert_eq!(base_fee_params(BASE_SEPOLIA_CHAIN_ID), BASE_SEPOLIA_BASE_FEE_PARAMS);
219 assert_eq!(base_fee_params(0), OP_MAINNET_BASE_FEE_PARAMS);
220 }
221
222 #[test]
223 fn test_base_fee_params_canyon_from_chain_id() {
224 assert_eq!(base_fee_params_canyon(OP_MAINNET_CHAIN_ID), OP_MAINNET_BASE_FEE_PARAMS_CANYON);
225 assert_eq!(base_fee_params_canyon(OP_SEPOLIA_CHAIN_ID), OP_SEPOLIA_BASE_FEE_PARAMS_CANYON);
226 assert_eq!(
227 base_fee_params_canyon(BASE_MAINNET_CHAIN_ID),
228 OP_MAINNET_BASE_FEE_PARAMS_CANYON
229 );
230 assert_eq!(
231 base_fee_params_canyon(BASE_SEPOLIA_CHAIN_ID),
232 BASE_SEPOLIA_BASE_FEE_PARAMS_CANYON
233 );
234 assert_eq!(base_fee_params_canyon(0), OP_MAINNET_BASE_FEE_PARAMS_CANYON);
235 }
236
237 #[test]
238 #[cfg(feature = "serde")]
239 fn test_base_fee_config_ser() {
240 let config = OP_MAINNET_BASE_FEE_CONFIG;
241 let raw_str = serde_json::to_string(&config).unwrap();
242 assert_eq!(
243 raw_str,
244 r#"{"eip1559Elasticity":"0x6","eip1559Denominator":"0x32","eip1559DenominatorCanyon":"0xfa"}"#
245 );
246 }
247
248 #[test]
249 #[cfg(feature = "serde")]
250 fn test_base_fee_config_serde_strs() {
251 let raw_str: &'static str = r#"{"eip1559Elasticity":"6","eip1559Denominator":"50","eip1559DenominatorCanyon":"250"}"#;
252 let config: BaseFeeConfig = serde_json::from_str(raw_str).unwrap();
253 assert_eq!(config, OP_MAINNET_BASE_FEE_CONFIG);
254 }
255
256 #[test]
257 #[cfg(feature = "serde")]
258 fn test_base_fee_config_serde_raw_number() {
259 let raw_str: &'static str =
260 r#"{"eip1559Elasticity":6,"eip1559Denominator":50,"eip1559DenominatorCanyon":250}"#;
261 let config: BaseFeeConfig = serde_json::from_str(raw_str).unwrap();
262 assert_eq!(config, OP_MAINNET_BASE_FEE_CONFIG);
263 }
264
265 #[test]
266 #[cfg(feature = "serde")]
267 fn test_base_fee_config_serde_hex() {
268 let raw_str: &'static str = r#"{"eip1559Elasticity":"0x6","eip1559Denominator":"0x32","eip1559DenominatorCanyon":"0xfa"}"#;
269 let config: BaseFeeConfig = serde_json::from_str(raw_str).unwrap();
270 assert_eq!(config, OP_MAINNET_BASE_FEE_CONFIG);
271 }
272}