arb_storage/
extra_types.rs

1use alloy_primitives::{B256, U256};
2use arb_storage_errors::StorageError;
3
4use crate::{
5    backend::{StorageBackend, SystemStateBackend},
6    slot::storage_key_map,
7    state_ops::ARBOS_STATE_ADDRESS,
8};
9
10fn compute_slot(base_key: B256, offset: u64) -> U256 {
11    if base_key == B256::ZERO {
12        storage_key_map(&[], offset)
13    } else {
14        storage_key_map(base_key.as_slice(), offset)
15    }
16}
17
18/// Basis points stored as signed `i64`. 10000 bips = 100%.
19#[derive(Clone, Copy, Debug)]
20pub struct StorageBackedBips {
21    pub slot: U256,
22}
23
24impl StorageBackedBips {
25    pub fn new(base_key: B256, offset: u64) -> Self {
26        Self {
27            slot: compute_slot(base_key, offset),
28        }
29    }
30
31    pub fn get<B: SystemStateBackend>(&self, backend: &mut B) -> Result<i64, StorageError> {
32        let value = backend
33            .sload_system(ARBOS_STATE_ADDRESS, self.slot)
34            .map_err(Into::into)?;
35        let value_u64: u64 = value.try_into().unwrap_or(0);
36        Ok(value_u64 as i64)
37    }
38
39    pub fn set<B: StorageBackend>(&self, backend: &mut B, value: i64) -> Result<(), StorageError> {
40        backend
41            .sstore(ARBOS_STATE_ADDRESS, self.slot, U256::from(value as u64))
42            .map_err(Into::into)
43    }
44}
45
46/// Unsigned basis points stored as `u64`. 10000 ubips = 100%.
47#[derive(Clone, Copy, Debug)]
48pub struct StorageBackedUBips {
49    pub slot: U256,
50}
51
52impl StorageBackedUBips {
53    pub fn new(base_key: B256, offset: u64) -> Self {
54        Self {
55            slot: compute_slot(base_key, offset),
56        }
57    }
58
59    pub fn get<B: SystemStateBackend>(&self, backend: &mut B) -> Result<u64, StorageError> {
60        let value = backend
61            .sload_system(ARBOS_STATE_ADDRESS, self.slot)
62            .map_err(Into::into)?;
63        Ok(value.try_into().unwrap_or(0))
64    }
65
66    pub fn set<B: StorageBackend>(&self, backend: &mut B, value: u64) -> Result<(), StorageError> {
67        backend
68            .sstore(ARBOS_STATE_ADDRESS, self.slot, U256::from(value))
69            .map_err(Into::into)
70    }
71}
72
73/// Storage-backed 16-bit unsigned integer.
74#[derive(Clone, Copy, Debug)]
75pub struct StorageBackedUint16 {
76    pub slot: U256,
77}
78
79impl StorageBackedUint16 {
80    pub fn new(base_key: B256, offset: u64) -> Self {
81        Self {
82            slot: compute_slot(base_key, offset),
83        }
84    }
85
86    pub fn get<B: SystemStateBackend>(&self, backend: &mut B) -> Result<u16, StorageError> {
87        let value = backend
88            .sload_system(ARBOS_STATE_ADDRESS, self.slot)
89            .map_err(Into::into)?;
90        Ok(value.try_into().unwrap_or(0))
91    }
92
93    pub fn set<B: StorageBackend>(&self, backend: &mut B, value: u16) -> Result<(), StorageError> {
94        backend
95            .sstore(ARBOS_STATE_ADDRESS, self.slot, U256::from(value))
96            .map_err(Into::into)
97    }
98}
99
100/// Storage-backed 24-bit unsigned integer.
101#[derive(Clone, Copy, Debug)]
102pub struct StorageBackedUint24 {
103    pub slot: U256,
104}
105
106impl StorageBackedUint24 {
107    pub fn new(base_key: B256, offset: u64) -> Self {
108        Self {
109            slot: compute_slot(base_key, offset),
110        }
111    }
112
113    pub fn get<B: SystemStateBackend>(&self, backend: &mut B) -> Result<u32, StorageError> {
114        let value = backend
115            .sload_system(ARBOS_STATE_ADDRESS, self.slot)
116            .map_err(Into::into)?;
117        let raw: u32 = value.try_into().unwrap_or(0);
118        Ok(raw & 0xFF_FFFF)
119    }
120
121    pub fn set<B: StorageBackend>(&self, backend: &mut B, value: u32) -> Result<(), StorageError> {
122        backend
123            .sstore(
124                ARBOS_STATE_ADDRESS,
125                self.slot,
126                U256::from(value & 0xFF_FFFF),
127            )
128            .map_err(Into::into)
129    }
130}
131
132/// Storage-backed 32-bit unsigned integer.
133#[derive(Clone, Copy, Debug)]
134pub struct StorageBackedUint32 {
135    pub slot: U256,
136}
137
138impl StorageBackedUint32 {
139    pub fn new(base_key: B256, offset: u64) -> Self {
140        Self {
141            slot: compute_slot(base_key, offset),
142        }
143    }
144
145    pub fn get<B: SystemStateBackend>(&self, backend: &mut B) -> Result<u32, StorageError> {
146        let value = backend
147            .sload_system(ARBOS_STATE_ADDRESS, self.slot)
148            .map_err(Into::into)?;
149        Ok(value.try_into().unwrap_or(0))
150    }
151
152    pub fn set<B: StorageBackend>(&self, backend: &mut B, value: u32) -> Result<(), StorageError> {
153        backend
154            .sstore(ARBOS_STATE_ADDRESS, self.slot, U256::from(value))
155            .map_err(Into::into)
156    }
157
158    pub fn clear<B: StorageBackend>(&self, backend: &mut B) -> Result<(), StorageError> {
159        self.set(backend, 0)
160    }
161}