arb_precompiles/
arbostest.rs1use std::sync::Arc;
2
3use alloy_evm::precompiles::{DynPrecompile, PrecompileInput};
4use alloy_primitives::{Address, U256};
5use alloy_sol_types::SolInterface;
6use arb_context::ArbPrecompileCtx;
7use revm::precompile::{PrecompileId, PrecompileOutput, PrecompileResult};
8
9use crate::interfaces::IArbosTest;
10
11pub const ARBOSTEST_ADDRESS: Address = Address::new([
13 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
14 0x00, 0x00, 0x00, 0x69,
15]);
16
17pub fn create_arbostest_precompile(ctx: Arc<ArbPrecompileCtx>) -> DynPrecompile {
18 DynPrecompile::new_stateful(PrecompileId::custom("arbostest"), move |input| {
19 handler(input, &ctx)
20 })
21}
22
23fn handler(input: PrecompileInput<'_>, ctx: &ArbPrecompileCtx) -> PrecompileResult {
24 let mut gas_used = 0u64;
25 let gas_limit = input.gas;
26 if !ctx.block.allow_debug_precompiles {
27 return crate::burn_all_revert(gas_limit);
28 }
29 crate::init_precompile_gas_pure(&mut gas_used, ctx, input.data.len());
31
32 let call = match IArbosTest::ArbosTestCalls::abi_decode(input.data) {
33 Ok(c) => c,
34 Err(_) => return crate::burn_all_revert(gas_limit),
35 };
36
37 if let Some(r) = crate::reject_nonpayable_value(input.value, input.data, gas_limit, &[]) {
38 return r;
39 }
40
41 use IArbosTest::ArbosTestCalls;
42 let result = match call {
43 ArbosTestCalls::burnArbGas(c) => {
44 handle_burn_arb_gas(&mut gas_used, ctx, gas_limit, c.gasAmount)
45 }
46 };
47 crate::gas_check(ctx, gas_limit, gas_used, result)
48}
49
50fn handle_burn_arb_gas(
51 gas_used: &mut u64,
52 ctx: &ArbPrecompileCtx,
53 gas_limit: u64,
54 amount: U256,
55) -> PrecompileResult {
56 let Ok(to_burn) = u64::try_from(amount) else {
57 return Ok(PrecompileOutput::new_reverted(
58 *gas_used,
59 Default::default(),
60 ));
61 };
62 let remaining = gas_limit.saturating_sub(*gas_used);
65 crate::charge_computation(gas_used, ctx, to_burn.min(remaining));
66 Ok(PrecompileOutput::new(*gas_used, Default::default()))
67}