Skip to main content

tempo_chainspec/
constants.rs

1//! Tempo constants shared by both the published surface and the reth-backed spec implementation.
2//!
3//! Gas-accounting constants are grouped under [`gas`].
4//! Hardfork activation schedules live in [`mainnet`] and [`moderato`].
5
6pub mod gas {
7    //! Gas-accounting constants shared with `spec.rs`.
8
9    use alloy_eips::eip1559::BaseFeeParams;
10
11    const COLD_SLOAD: u64 = 2100;
12    const WARM_SLOAD: u64 = 100;
13    const WARM_SSTORE_RESET: u64 = 2900;
14    const T1_SSTORE_SET: u64 = 20_000;
15
16    /// TIP-1000 storage creation component for a zero-to-nonzero SSTORE.
17    pub const SSTORE_CREATE_COST: u64 = 250_000;
18
19    /// TIP-1060 SSTORE residual: EVM `0→x` base cost paid even when a credit applies.
20    pub const SSTORE_SET_COST: u64 = 5_000;
21
22    /// TIP-1060 value credited for clearing one occupied storage slot.
23    pub const STORAGE_CREDIT_VALUE: u64 = SSTORE_CREATE_COST - SSTORE_SET_COST;
24
25    /// T0 base fee: 10 billion attodollars (1×10^10).
26    ///
27    /// Attodollars are the atomic gas accounting units at 10^-18 USD precision.
28    /// Basefee is denominated in attodollars.
29    pub const TEMPO_T0_BASE_FEE: u64 = 10_000_000_000;
30
31    /// T1 base fee: 20 billion attodollars (2×10^10).
32    ///
33    /// Attodollars are the atomic gas accounting units at 10^-18 USD precision.
34    /// Basefee is denominated in attodollars.
35    ///
36    /// At this basefee, a standard TIP-20 transfer (~50,000 gas) costs:
37    /// - Gas: 50,000 × 20 billion attodollars/gas = 1 quadrillion attodollars
38    /// - Tokens: 1 quadrillion attodollars / 10^12 = 1,000 microdollars
39    /// - Economic: 1,000 microdollars = 0.001 USD = 0.1 cents
40    pub const TEMPO_T1_BASE_FEE: u64 = 20_000_000_000;
41
42    /// TIP-1067 base fee cap: below the T1 fixed base fee.
43    pub const TEMPO_T7_BASE_FEE_CAP: u64 = 12_000_000_000;
44
45    /// TIP-1067 base fee floor: one twentieth of the TIP-1067 cap.
46    pub const TEMPO_T7_BASE_FEE_FLOOR: u64 = TEMPO_T7_BASE_FEE_CAP / 20;
47
48    /// TIP-1067 gas target for the dynamic base fee controller.
49    pub const TEMPO_T7_BASE_FEE_GAS_TARGET: u64 = 10_000_000;
50
51    /// TIP-1067 uses EIP-1559's base-fee update formula with a fixed 10M gas target.
52    ///
53    /// The params are `(max_change_denominator = 8, elasticity_multiplier = 1)`: `8` keeps the
54    /// standard EIP-1559 maximum 12.5% per-block base-fee delta, while `1` prevents EIP-1559's
55    /// usual target-halving because TIP-1067 supplies [`TEMPO_T7_BASE_FEE_GAS_TARGET`] directly.
56    ///
57    /// [TIP-1067]: <https://docs.tempo.xyz/protocol/tips/tip-1067>
58    pub const TEMPO_T7_BASE_FEE_PARAMS: BaseFeeParams = BaseFeeParams::new(8, 1);
59
60    /// Returns the TIP-1067 base fee for the child of a block.
61    ///
62    /// The update follows EIP-1559's integer formula against a fixed 10M gas target, then clamps the
63    /// result to `[TEMPO_T7_BASE_FEE_FLOOR, TEMPO_T7_BASE_FEE_CAP]`.
64    pub fn tempo_t7_next_block_base_fee(parent_base_fee: u64, parent_gas_used: u64) -> u64 {
65        TEMPO_T7_BASE_FEE_PARAMS
66            .next_block_base_fee(
67                parent_gas_used,
68                TEMPO_T7_BASE_FEE_GAS_TARGET,
69                parent_base_fee,
70            )
71            .clamp(TEMPO_T7_BASE_FEE_FLOOR, TEMPO_T7_BASE_FEE_CAP)
72    }
73    /// [TIP-1010] general (non-payment) gas limit: 30 million gas per block.
74    /// Cap for non-payment transactions.
75    ///
76    /// [TIP-1010]: <https://docs.tempo.xyz/protocol/tips/tip-1010>
77    pub const TEMPO_T1_GENERAL_GAS_LIMIT: u64 = 30_000_000;
78
79    /// TIP-1010 per-transaction gas limit cap: 30 million gas.
80    /// Allows maximum-sized contract deployments under [TIP-1000] state creation costs.
81    ///
82    /// [TIP-1000]: <https://docs.tempo.xyz/protocol/tips/tip-1000>
83    pub const TEMPO_T1_TX_GAS_LIMIT_CAP: u64 = 30_000_000;
84
85    /// Gas cost for using an existing 2D nonce key (cold SLOAD + warm SSTORE reset).
86    pub const TEMPO_T1_EXISTING_NONCE_KEY_GAS: u64 = COLD_SLOAD + WARM_SSTORE_RESET;
87    /// T2 adds 2 warm SLOADs for the extended nonce key lookup.
88    pub const TEMPO_T2_EXISTING_NONCE_KEY_GAS: u64 =
89        TEMPO_T1_EXISTING_NONCE_KEY_GAS + 2 * WARM_SLOAD;
90
91    /// Gas cost for using a new 2D nonce key (cold SLOAD + SSTORE set for 0 -> non-zero).
92    pub const TEMPO_T1_NEW_NONCE_KEY_GAS: u64 = COLD_SLOAD + T1_SSTORE_SET;
93    /// T2 adds 2 warm SLOADs for the extended nonce key lookup.
94    pub const TEMPO_T2_NEW_NONCE_KEY_GAS: u64 = TEMPO_T1_NEW_NONCE_KEY_GAS + 2 * WARM_SLOAD;
95
96    #[cfg(test)]
97    mod tests {
98        use super::*;
99
100        #[test]
101        fn tip1067_dynamic_base_fee_steady_state() {
102            assert_eq!(
103                tempo_t7_next_block_base_fee(
104                    TEMPO_T7_BASE_FEE_CAP / 2,
105                    TEMPO_T7_BASE_FEE_GAS_TARGET
106                ),
107                TEMPO_T7_BASE_FEE_CAP / 2
108            );
109        }
110
111        #[test]
112        fn tip1067_dynamic_base_fee_decays_to_floor() {
113            let mut base_fee = TEMPO_T7_BASE_FEE_CAP;
114            for _ in 0..64 {
115                base_fee = tempo_t7_next_block_base_fee(base_fee, 0);
116            }
117            assert_eq!(base_fee, TEMPO_T7_BASE_FEE_FLOOR);
118            assert_eq!(
119                tempo_t7_next_block_base_fee(base_fee, 0),
120                TEMPO_T7_BASE_FEE_FLOOR
121            );
122        }
123
124        #[test]
125        fn tip1067_dynamic_base_fee_rises_to_cap() {
126            let mut base_fee = TEMPO_T7_BASE_FEE_FLOOR;
127            for _ in 0..16 {
128                base_fee = tempo_t7_next_block_base_fee(base_fee, 500_000_000);
129            }
130            assert_eq!(base_fee, TEMPO_T7_BASE_FEE_CAP);
131            assert_eq!(
132                tempo_t7_next_block_base_fee(base_fee, 500_000_000),
133                TEMPO_T7_BASE_FEE_CAP
134            );
135        }
136
137        #[test]
138        fn tip1067_dynamic_base_fee_minimum_increase() {
139            assert_eq!(
140                tempo_t7_next_block_base_fee(
141                    TEMPO_T7_BASE_FEE_FLOOR,
142                    TEMPO_T7_BASE_FEE_GAS_TARGET + 1
143                ),
144                TEMPO_T7_BASE_FEE_FLOOR + 7
145            );
146        }
147
148        #[test]
149        fn tip1067_dynamic_base_fee_clamps_equal_branch() {
150            assert_eq!(
151                tempo_t7_next_block_base_fee(
152                    TEMPO_T7_BASE_FEE_FLOOR - 1,
153                    TEMPO_T7_BASE_FEE_GAS_TARGET
154                ),
155                TEMPO_T7_BASE_FEE_FLOOR
156            );
157            assert_eq!(
158                tempo_t7_next_block_base_fee(
159                    TEMPO_T7_BASE_FEE_CAP + 1,
160                    TEMPO_T7_BASE_FEE_GAS_TARGET
161                ),
162                TEMPO_T7_BASE_FEE_CAP
163            );
164        }
165    }
166}
167
168pub mod mainnet {
169    //! Tempo mainnet (Presto) chain id and hardfork activation constants.
170    pub const MAINNET_CHAIN_ID: u64 = 4217;
171
172    /// Genesis activation block.
173    pub const MAINNET_GENESIS_BLOCK: u64 = 0;
174    /// Genesis activation timestamp.
175    pub const MAINNET_GENESIS_TIMESTAMP: u64 = 0;
176
177    /// T0 activation block (active from genesis).
178    pub const MAINNET_T0_BLOCK: u64 = 0;
179    /// T0 activation timestamp (active from genesis).
180    pub const MAINNET_T0_TIMESTAMP: u64 = 0;
181
182    /// T1 activation block.
183    pub const MAINNET_T1_BLOCK: u64 = 4_494_230;
184    /// T1 activation timestamp (Feb 12th 2026 15:00 UTC).
185    pub const MAINNET_T1_TIMESTAMP: u64 = 1_770_908_400;
186
187    /// T1A activation block (same as T1 on mainnet).
188    pub const MAINNET_T1A_BLOCK: u64 = MAINNET_T1_BLOCK;
189    /// T1A activation timestamp (same as T1 on mainnet).
190    pub const MAINNET_T1A_TIMESTAMP: u64 = MAINNET_T1_TIMESTAMP;
191
192    /// T1B activation block.
193    pub const MAINNET_T1B_BLOCK: u64 = 6_253_936;
194    /// T1B activation timestamp (Feb 23rd 2026 15:00 UTC).
195    pub const MAINNET_T1B_TIMESTAMP: u64 = 1_771_858_800;
196
197    /// T1C activation block.
198    pub const MAINNET_T1C_BLOCK: u64 = 8_967_991;
199    /// T1C activation timestamp (Mar 12th 2026 15:00 UTC).
200    pub const MAINNET_T1C_TIMESTAMP: u64 = 1_773_327_600;
201
202    /// T2 activation block.
203    pub const MAINNET_T2_BLOCK: u64 = 12_286_033;
204    /// T2 activation timestamp (Mar 31st 2026 14:00 UTC).
205    pub const MAINNET_T2_TIMESTAMP: u64 = 1_774_965_600;
206
207    /// T3 activation timestamp (Apr 27th 2026 14:00 UTC).
208    pub const MAINNET_T3_TIMESTAMP: u64 = 1_777_298_400;
209
210    /// T4 activation timestamp (May 18th 2026 14:00 UTC).
211    pub const MAINNET_T4_TIMESTAMP: u64 = 1_779_112_800;
212
213    /// T5 activation timestamp (Jun 9th 2026 14:00 UTC).
214    pub const MAINNET_T5_TIMESTAMP: u64 = 1_781_013_600;
215
216    /// T6 activation timestamp (Jun 23rd 2026 14:00 UTC).
217    pub const MAINNET_T6_TIMESTAMP: u64 = 1_782_223_200;
218}
219
220pub mod moderato {
221    //! Moderato testnet chain id and hardfork activation constants.
222    pub const MODERATO_CHAIN_ID: u64 = 42431;
223
224    /// Genesis activation block.
225    pub const MODERATO_GENESIS_BLOCK: u64 = 0;
226    /// Genesis activation timestamp.
227    pub const MODERATO_GENESIS_TIMESTAMP: u64 = 0;
228
229    /// T0 activation block (same as T1 on moderato).
230    pub const MODERATO_T0_BLOCK: u64 = 3_767_359;
231    /// T0 activation timestamp (Feb 5th 2026 15:00 UTC).
232    pub const MODERATO_T0_TIMESTAMP: u64 = 1_770_303_600;
233
234    /// T1 activation block (same as T0 on moderato).
235    pub const MODERATO_T1_BLOCK: u64 = MODERATO_T0_BLOCK;
236    /// T1 activation timestamp (same as T0 on moderato).
237    pub const MODERATO_T1_TIMESTAMP: u64 = MODERATO_T0_TIMESTAMP;
238
239    /// T1A activation block (same as T1B on moderato).
240    pub const MODERATO_T1A_BLOCK: u64 = 6_033_587;
241    /// T1A activation timestamp (Feb 23rd 2026 15:00 UTC).
242    pub const MODERATO_T1A_TIMESTAMP: u64 = 1_771_858_800;
243
244    /// T1B activation block (same as T1A on moderato).
245    pub const MODERATO_T1B_BLOCK: u64 = MODERATO_T1A_BLOCK;
246    /// T1B activation timestamp (same as T1A on moderato).
247    pub const MODERATO_T1B_TIMESTAMP: u64 = MODERATO_T1A_TIMESTAMP;
248
249    /// T1C activation block.
250    pub const MODERATO_T1C_BLOCK: u64 = 7_768_256;
251    /// T1C activation timestamp (Mar 9th 2026 15:00 UTC).
252    pub const MODERATO_T1C_TIMESTAMP: u64 = 1_773_068_400;
253
254    /// T2 activation block.
255    pub const MODERATO_T2_BLOCK: u64 = 10_072_242;
256    /// T2 activation timestamp (Mar 26th 2026 14:00 UTC).
257    pub const MODERATO_T2_TIMESTAMP: u64 = 1_774_537_200;
258
259    /// T3 activation timestamp (Apr 21st 2026 14:00 UTC).
260    pub const MODERATO_T3_TIMESTAMP: u64 = 1_776_780_000;
261
262    /// T4 activation timestamp (May 14th 2026 14:00 UTC).
263    pub const MODERATO_T4_TIMESTAMP: u64 = 1_778_767_200;
264
265    /// T5 activation timestamp (Jun 3rd 2026 14:00 UTC).
266    pub const MODERATO_T5_TIMESTAMP: u64 = 1_780_495_200;
267
268    /// T6 activation timestamp (Jun 18th 2026 14:00 UTC).
269    pub const MODERATO_T6_TIMESTAMP: u64 = 1_781_791_200;
270}