arb_precompiles/
arbstatistics.rs1use alloy_evm::precompiles::{DynPrecompile, PrecompileInput};
2use alloy_primitives::{Address, U256};
3use revm::precompile::{PrecompileError, PrecompileId, PrecompileOutput, PrecompileResult};
4
5pub const ARBSTATISTICS_ADDRESS: Address = Address::new([
7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8 0x00, 0x00, 0x00, 0x6f,
9]);
10
11const GET_STATS: [u8; 4] = [0xe1, 0x1b, 0x84, 0xd8]; const COPY_GAS: u64 = 3;
14const SLOAD_GAS: u64 = 800;
15
16pub fn create_arbstatistics_precompile() -> DynPrecompile {
17 DynPrecompile::new_stateful(PrecompileId::custom("arbstatistics"), handler)
18}
19
20fn handler(input: PrecompileInput<'_>) -> PrecompileResult {
21 let gas_limit = input.gas;
22 let data = input.data;
23 if data.len() < 4 {
24 return Err(PrecompileError::other("input too short"));
25 }
26
27 let selector: [u8; 4] = [data[0], data[1], data[2], data[3]];
28
29 let result = match selector {
30 GET_STATS => handle_get_stats(&input),
31 _ => Err(PrecompileError::other("unknown ArbStatistics selector")),
32 };
33 crate::gas_check(gas_limit, result)
34}
35
36fn handle_get_stats(input: &PrecompileInput<'_>) -> PrecompileResult {
37 let gas_limit = input.gas;
38
39 let block_number = U256::from(crate::arbsys::get_current_l2_block());
43 let mut out = Vec::with_capacity(192);
44 out.extend_from_slice(&block_number.to_be_bytes::<32>());
45 for _ in 0..5 {
46 out.extend_from_slice(&U256::ZERO.to_be_bytes::<32>());
47 }
48
49 let gas_cost = (SLOAD_GAS + 6 * COPY_GAS).min(gas_limit);
51 Ok(PrecompileOutput::new(gas_cost, out.into()))
52}