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}