arb_precompiles/
arbfunctiontable.rs1use alloy_evm::precompiles::{DynPrecompile, PrecompileInput};
2use alloy_primitives::{Address, U256};
3use revm::precompile::{PrecompileError, PrecompileId, PrecompileOutput, PrecompileResult};
4
5pub const ARBFUNCTIONTABLE_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, 0x68,
9]);
10
11const UPLOAD: [u8; 4] = [0x88, 0x3c, 0x9d, 0x6b]; const SIZE: [u8; 4] = [0x17, 0x24, 0x56, 0x7f]; const GET: [u8; 4] = [0xa0, 0x69, 0xee, 0x85]; const COPY_GAS: u64 = 3;
16
17pub fn create_arbfunctiontable_precompile() -> DynPrecompile {
18 DynPrecompile::new_stateful(PrecompileId::custom("arbfunctiontable"), handler)
19}
20
21fn handler(input: PrecompileInput<'_>) -> PrecompileResult {
22 let gas_limit = input.gas;
23 let data = input.data;
24
25 if data.len() < 4 {
26 return Err(PrecompileError::other("input too short"));
27 }
28
29 let selector: [u8; 4] = [data[0], data[1], data[2], data[3]];
30
31 let result = match selector {
32 UPLOAD => {
33 let gas_cost = COPY_GAS.min(gas_limit);
35 Ok(PrecompileOutput::new(gas_cost, vec![].into()))
36 }
37 SIZE => {
38 let gas_cost = COPY_GAS.min(gas_limit);
40 Ok(PrecompileOutput::new(
41 gas_cost,
42 U256::ZERO.to_be_bytes::<32>().to_vec().into(),
43 ))
44 }
45 GET => Err(PrecompileError::other("table is empty")),
46 _ => Err(PrecompileError::other("unknown ArbFunctionTable selector")),
47 };
48 crate::gas_check(gas_limit, result)
49}