arbos/programs/
types.rs

1use alloy_primitives::{Address, B256};
2
3/// Outcome of executing a Stylus WASM program.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5#[repr(u8)]
6pub enum UserOutcome {
7    Success = 0,
8    Revert = 1,
9    Failure = 2,
10    OutOfInk = 3,
11    OutOfStack = 4,
12}
13
14impl UserOutcome {
15    /// Convert a raw status byte to a UserOutcome.
16    pub fn from_u8(status: u8) -> Option<Self> {
17        match status {
18            0 => Some(Self::Success),
19            1 => Some(Self::Revert),
20            2 => Some(Self::Failure),
21            3 => Some(Self::OutOfInk),
22            4 => Some(Self::OutOfStack),
23            _ => None,
24        }
25    }
26}
27
28/// EVM context data passed to the Stylus runtime during program execution.
29#[derive(Debug, Clone)]
30pub struct EvmData {
31    pub arbos_version: u64,
32    pub block_basefee: B256,
33    pub chain_id: u64,
34    pub block_coinbase: Address,
35    pub block_gas_limit: u64,
36    pub block_number: u64,
37    pub block_timestamp: u64,
38    pub contract_address: Address,
39    pub module_hash: B256,
40    pub msg_sender: Address,
41    pub msg_value: B256,
42    pub tx_gas_price: B256,
43    pub tx_origin: Address,
44    pub reentrant: u32,
45    pub cached: bool,
46    pub tracing: bool,
47}
48
49/// Parameters passed to the Stylus runtime for program execution.
50#[derive(Debug, Clone, Copy)]
51pub struct ProgParams {
52    pub version: u16,
53    pub max_depth: u32,
54    pub ink_price: u32,
55    pub debug_mode: bool,
56}
57
58/// Result of a Stylus program activation.
59#[derive(Debug, Clone)]
60pub struct ActivationResult {
61    pub module_hash: B256,
62    pub init_gas: u16,
63    pub cached_init_gas: u16,
64    pub asm_estimate: u32,
65    pub footprint: u16,
66}
67
68/// Compute EVM memory expansion cost (matches geth's memory.go).
69pub fn evm_memory_cost(size: u64) -> u64 {
70    let words = to_word_size(size);
71    const MEMORY_GAS: u64 = 3;
72    const QUAD_COEFF_DIV: u64 = 512;
73    let linear_cost = words.saturating_mul(MEMORY_GAS);
74    let square_cost = (words.saturating_mul(words)) / QUAD_COEFF_DIV;
75    linear_cost.saturating_add(square_cost)
76}
77
78/// Round up byte size to 32-byte word count.
79pub fn to_word_size(size: u64) -> u64 {
80    if size > u64::MAX - 31 {
81        return u64::MAX / 32 + 1;
82    }
83    size.div_ceil(32)
84}