1use alloy_primitives::{Address, U256};
4use revm::primitives::bitvec::macros::internal::funty::Fundamental;
5
6pub fn address_from_hex(hx: &str) -> Address {
13 let address = hx
14 .strip_prefix("0x")
15 .expect("Addresses require '0x' prefix");
16 let address = hex::decode(address).expect("Decoding hex string failed");
17 Address::from_slice(address.as_slice())
18}
19
20pub fn data_bytes_from_hex(hx: &str) -> Vec<u8> {
27 hex::decode(hx).expect("Decoding hex failed")
28}
29
30pub trait Eth {
32 fn to_weth(x: u128) -> Self;
33}
34
35impl Eth for U256 {
37 fn to_weth(x: u128) -> Self {
38 let x: u128 = x * 10u128.pow(18);
39 Self::from(x)
40 }
41}
42
43pub fn scale_data_value(x: U256, decimals: usize, precision: usize) -> f64 {
53 let s1 = U256::from(decimals - precision);
54 let x = x / U256::from(10).pow(s1);
55 let x: u64 = x
58 .clamp(U256::ZERO, U256::from(u64::MAX))
59 .try_into()
60 .unwrap();
61 x.as_f64() / 10f64.powi(precision.as_i32())
62}
63
64pub fn clamp_u256_to_u128(x: U256) -> u128 {
71 x.clamp(U256::ZERO, U256::from(u128::MAX))
72 .try_into()
73 .unwrap()
74}
75
76pub fn div_u256(x: U256, y: U256, precision: i32) -> f64 {
85 let z = x * U256::from(10).pow(U256::from(precision)) / y;
86 let z: u64 = z
87 .clamp(U256::ZERO, U256::from(u64::MAX))
88 .try_into()
89 .unwrap();
90 z.as_f64() / 10f64.powi(precision)
91}
92
93pub fn constructor_data(bytecode_hex: &str, mut args: Option<Vec<u8>>) -> Vec<u8> {
101 let mut bytecode: Vec<u8> = data_bytes_from_hex(bytecode_hex);
102 match &mut args {
103 Some(a) => bytecode.append(a),
104 None => {}
105 }
106 bytecode
107}
108
109#[cfg(test)]
110mod tests {
111
112 use super::*;
113 use assert_approx_eq::assert_approx_eq;
114 use rstest::rstest;
115
116 #[rstest]
117 #[case(5, 17, 0.5)]
118 #[case(1, 15, 0.001)]
119 #[case(15, 17, 1.5)]
120 #[case(1000000005, 12, 1000.000005)]
121 fn scaling_values(#[case] a: u128, #[case] exp: u128, #[case] expected: f64) {
122 let x = U256::from(a) * U256::from(10).pow(U256::from(exp));
123 let y = scale_data_value(x, 18, 6);
124 assert_approx_eq!(y, expected);
125 }
126
127 #[test]
128 fn scaling_out_of_bounds() {
129 let x = U256::MAX;
131 let y = scale_data_value(x, 4, 0);
132 assert_approx_eq!(y, u64::MAX.as_f64());
133 }
134
135 #[rstest]
136 #[case(10, 5, 15, 15, 2.0, 0.5)]
137 #[case(1, 1, 20, 16, 10000.0, 0.0001)]
138 fn dividing_u256(
139 #[case] a: u128,
140 #[case] b: u128,
141 #[case] exp_a: u128,
142 #[case] exp_b: u128,
143 #[case] expected_a: f64,
144 #[case] expected_b: f64,
145 ) {
146 let x = U256::from(a) * U256::from(10).pow(U256::from(exp_a));
147 let y = U256::from(b) * U256::from(10).pow(U256::from(exp_b));
148
149 let z = div_u256(x, y, 6);
150 assert_approx_eq!(z, expected_a);
151
152 let z = div_u256(y, x, 6);
153 assert_approx_eq!(z, expected_b);
154 }
155
156 #[test]
157 fn div_out_of_bounds() {
158 let x = U256::from(10).pow(U256::from(30));
159 let y = U256::from(1);
160 let z = div_u256(x, y, 0);
161 assert_approx_eq!(z, u64::MAX.as_f64())
162 }
163}