arb_precompiles/
arbstatistics.rs

1use alloy_evm::precompiles::{DynPrecompile, PrecompileInput};
2use alloy_primitives::{Address, U256};
3use revm::precompile::{PrecompileError, PrecompileId, PrecompileOutput, PrecompileResult};
4
5/// ArbStatistics precompile address (0x6f).
6pub 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]; // getStats()
12
13const 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    // Returns (blockNumber, 0, 0, 0, 0, 0).
40    // The five Classic-era stats are always zero (never populated post-migration).
41    // Use the L2 block number (block_env.number holds L1 in Arbitrum).
42    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    // OAS(800) + 0 body + resultCost = 6 words × 3 = 18.
50    let gas_cost = (SLOAD_GAS + 6 * COPY_GAS).min(gas_limit);
51    Ok(PrecompileOutput::new(gas_cost, out.into()))
52}