zink/primitives/
u256.rs

1#![allow(clippy::should_implement_trait)]
2
3use crate::{asm, primitives::Bytes32, storage::Value};
4use core::ops::Sub;
5
6/// Account address
7///
8/// TODO: impl Numeric trait for U256
9#[repr(C)]
10#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
11pub struct U256(Bytes32);
12
13impl U256 {
14    /// Returns empty value  
15    pub const fn empty() -> Self {
16        U256(Bytes32::empty())
17    }
18
19    /// u256 add
20    #[inline(always)]
21    pub fn add(self, other: Self) -> Self {
22        unsafe { asm::ext::u256_add(self, other) }
23    }
24
25    /// u256 less than
26    #[inline(always)]
27    pub fn lt(self, other: Self) -> bool {
28        unsafe { asm::ext::u256_lt(other, self) }
29    }
30
31    /// u256 eq
32    #[inline(always)]
33    pub fn eq(self, other: Self) -> bool {
34        self.0.eq(other.0)
35    }
36
37    /// u256 sub
38    #[inline(always)]
39    pub fn sub(self, other: Self) -> Self {
40        unsafe { asm::ext::u256_sub(other, self) }
41    }
42
43    /// u256 div
44    #[inline(always)]
45    pub fn div(self, other: Self) -> Self {
46        unsafe { asm::ext::u256_div(self, other) }
47    }
48
49    /// max of u256
50    #[inline(always)]
51    pub fn max() -> Self {
52        unsafe { asm::ext::u256_max() }
53    }
54
55    pub fn to_bytes32(&self) -> Bytes32 {
56        self.0
57    }
58
59    #[cfg(not(target_family = "wasm"))]
60    pub fn bytes32(&self) -> [u8; 32] {
61        self.0 .0 // [u8; 32] in non-WASM
62    }
63
64    #[inline(always)]
65    pub fn addmod(self, other: Self, modulus: Self) -> Self {
66        unsafe { asm::ext::u256_addmod(modulus, other, self) }
67    }
68
69    /// Mulmod for U256
70    #[inline(always)]
71    pub fn mulmod(self, other: Self, modulus: Self) -> Self {
72        unsafe { asm::ext::u256_mulmod(modulus, other, self) }
73    }
74}
75
76impl Sub for U256 {
77    type Output = Self;
78
79    #[inline(always)]
80    fn sub(self, other: Self) -> Self::Output {
81        unsafe { asm::ext::u256_sub(self, other) }
82    }
83}
84
85impl Value for U256 {
86    #[inline(always)]
87    fn tload() -> Self {
88        Self(unsafe { asm::bytes::tload_bytes32() })
89    }
90
91    #[inline(always)]
92    fn sload() -> Self {
93        Self(unsafe { asm::bytes::sload_bytes32() })
94    }
95
96    #[inline(always)]
97    fn push(self) {
98        unsafe { asm::bytes::push_bytes32(self.0) }
99    }
100
101    #[cfg(not(target_family = "wasm"))]
102    fn bytes32(&self) -> [u8; 32] {
103        self.bytes32() // Delegate to the instance method
104    }
105}
106
107impl From<u64> for U256 {
108    fn from(value: u64) -> Self {
109        #[cfg(target_family = "wasm")]
110        {
111            U256(Bytes32(value as i32))
112        }
113        #[cfg(not(target_family = "wasm"))]
114        {
115            // On non-WASM, Bytes32 is [u8; 32]
116            let mut bytes = [0u8; 32];
117            bytes[24..32].copy_from_slice(&value.to_be_bytes());
118            U256(Bytes32(bytes))
119        }
120    }
121}