arb_stylus/
pricing.rs

1use crate::ink::Ink;
2
3/// Base cost for hostios that may return something.
4pub const HOSTIO_INK: Ink = Ink(8400);
5
6/// Extra cost for hostios that include pointers.
7pub const PTR_INK: Ink = Ink(13440).sub(HOSTIO_INK);
8
9/// Extra cost for hostios that involve an API cost.
10pub const EVM_API_INK: Ink = Ink(59673);
11
12/// Extra cost for division/modulo operations.
13pub const DIV_INK: Ink = Ink(20000);
14
15/// Extra cost for mulmod.
16pub const MUL_MOD_INK: Ink = Ink(24100);
17
18/// Extra cost for addmod.
19pub const ADD_MOD_INK: Ink = Ink(21000);
20
21/// Per-hostio base ink costs.
22pub mod hostio {
23    use super::*;
24
25    pub const READ_ARGS_BASE_INK: Ink = HOSTIO_INK;
26    pub const WRITE_RESULT_BASE_INK: Ink = HOSTIO_INK;
27    pub const STORAGE_LOAD_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(2));
28    pub const STORAGE_CACHE_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(2));
29    pub const STORAGE_FLUSH_BASE_INK: Ink = HOSTIO_INK.add(EVM_API_INK);
30    pub const TRANSIENT_LOAD_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(2).add(EVM_API_INK));
31    pub const TRANSIENT_STORE_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(2).add(EVM_API_INK));
32    pub const CALL_CONTRACT_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(3).add(EVM_API_INK));
33    pub const CREATE1_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(3).add(EVM_API_INK));
34    pub const CREATE2_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(4).add(EVM_API_INK));
35    pub const READ_RETURN_DATA_BASE_INK: Ink = HOSTIO_INK.add(EVM_API_INK);
36    pub const RETURN_DATA_SIZE_BASE_INK: Ink = HOSTIO_INK;
37    pub const EMIT_LOG_BASE_INK: Ink = HOSTIO_INK.add(EVM_API_INK);
38    pub const ACCOUNT_BALANCE_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(2).add(EVM_API_INK));
39    pub const ACCOUNT_CODE_BASE_INK: Ink = HOSTIO_INK.add(EVM_API_INK);
40    pub const ACCOUNT_CODE_SIZE_BASE_INK: Ink = HOSTIO_INK.add(EVM_API_INK);
41    pub const ACCOUNT_CODE_HASH_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(2).add(EVM_API_INK));
42    pub const BLOCK_BASEFEE_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK);
43    pub const BLOCK_COINBASE_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK);
44    pub const BLOCK_GAS_LIMIT_BASE_INK: Ink = HOSTIO_INK;
45    pub const BLOCK_NUMBER_BASE_INK: Ink = HOSTIO_INK;
46    pub const BLOCK_TIMESTAMP_BASE_INK: Ink = HOSTIO_INK;
47    pub const CHAIN_ID_BASE_INK: Ink = HOSTIO_INK;
48    pub const ADDRESS_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK);
49    pub const EVM_GAS_LEFT_BASE_INK: Ink = HOSTIO_INK;
50    pub const EVM_INK_LEFT_BASE_INK: Ink = HOSTIO_INK;
51    pub const MATH_DIV_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(3).add(DIV_INK));
52    pub const MATH_MOD_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(3).add(DIV_INK));
53    pub const MATH_POW_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(3));
54    pub const MATH_ADD_MOD_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(4).add(ADD_MOD_INK));
55    pub const MATH_MUL_MOD_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK.mul(4).add(MUL_MOD_INK));
56    pub const MSG_REENTRANT_BASE_INK: Ink = HOSTIO_INK;
57    pub const MSG_SENDER_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK);
58    pub const MSG_VALUE_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK);
59    pub const TX_GAS_PRICE_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK);
60    pub const TX_INK_PRICE_BASE_INK: Ink = HOSTIO_INK;
61    pub const TX_ORIGIN_BASE_INK: Ink = HOSTIO_INK.add(PTR_INK);
62    pub const PAY_FOR_MEMORY_GROW_BASE_INK: Ink = HOSTIO_INK;
63}
64
65/// EVM gas constants used by host functions.
66pub mod evm_gas {
67    /// params.SstoreSentryGasEIP2200
68    pub const SSTORE_SENTRY_GAS: u64 = 2300;
69    /// params.ColdAccountAccessCostEIP2929
70    pub const COLD_ACCOUNT_GAS: u64 = 2600;
71    /// params.ColdSloadCostEIP2929
72    pub const COLD_SLOAD_GAS: u64 = 2100;
73    /// params.WarmStorageReadCostEIP2929
74    pub const WARM_SLOAD_GAS: u64 = 100;
75    /// params.WarmStorageReadCostEIP2929 (TLOAD cost)
76    pub const TLOAD_GAS: u64 = WARM_SLOAD_GAS;
77    /// params.WarmStorageReadCostEIP2929 (TSTORE cost)
78    pub const TSTORE_GAS: u64 = WARM_SLOAD_GAS;
79    /// params.LogGas
80    pub const LOG_TOPIC_GAS: u64 = 375;
81    /// params.LogDataGas
82    pub const LOG_DATA_GAS: u64 = 8;
83    /// Minimum gas the cache requires for SSTORE operations.
84    pub const STORAGE_CACHE_REQUIRED_ACCESS_GAS: u64 = 100;
85}
86
87/// Cost to read `bytes` from WASM memory.
88pub fn read_price(bytes: u32) -> Ink {
89    Ink(sat_add_mul(16381, 55, bytes.saturating_sub(32)))
90}
91
92/// Cost to write `bytes` to WASM memory.
93pub fn write_price(bytes: u32) -> Ink {
94    Ink(sat_add_mul(5040, 30, bytes.saturating_sub(32)))
95}
96
97/// Cost of keccak256 over `bytes`.
98pub fn keccak_price(bytes: u32) -> Ink {
99    let words = evm_words(bytes).saturating_sub(2);
100    Ink(sat_add_mul(121800, 21000, words))
101}
102
103/// Cost of exponentiation based on the exponent's byte size.
104pub fn pow_price(exponent: &[u8; 32]) -> Ink {
105    let mut exp = 33u64;
106    for byte in exponent.iter() {
107        match *byte == 0 {
108            true => exp -= 1,
109            false => break,
110        }
111    }
112    Ink(3000 + exp * 17500)
113}
114
115fn evm_words(bytes: u32) -> u32 {
116    bytes.div_ceil(32)
117}
118
119fn sat_add_mul(base: u64, per: u64, count: u32) -> u64 {
120    base.saturating_add(per.saturating_mul(count as u64))
121}