1#![allow(clippy::should_implement_trait)]
2
3use crate::{asm, primitives::Bytes32, storage::Value};
4use core::ops::Sub;
5
6#[repr(C)]
10#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
11pub struct U256(Bytes32);
12
13impl U256 {
14 pub const fn empty() -> Self {
16 U256(Bytes32::empty())
17 }
18
19 #[inline(always)]
21 pub fn add(self, other: Self) -> Self {
22 unsafe { asm::ext::u256_add(self, other) }
23 }
24
25 #[inline(always)]
27 pub fn lt(self, other: Self) -> bool {
28 unsafe { asm::ext::u256_lt(other, self) }
29 }
30
31 #[inline(always)]
33 pub fn eq(self, other: Self) -> bool {
34 self.0.eq(other.0)
35 }
36
37 #[inline(always)]
39 pub fn sub(self, other: Self) -> Self {
40 unsafe { asm::ext::u256_sub(other, self) }
41 }
42
43 #[inline(always)]
45 pub fn div(self, other: Self) -> Self {
46 unsafe { asm::ext::u256_div(self, other) }
47 }
48
49 #[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 }
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 #[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() }
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 let mut bytes = [0u8; 32];
117 bytes[24..32].copy_from_slice(&value.to_be_bytes());
118 U256(Bytes32(bytes))
119 }
120 }
121}