kabu_defi_uniswap_v3_math/
bit_math.rs

1use crate::error::UniswapV3MathError;
2use alloy::primitives::U256;
3
4pub fn most_significant_bit(x: U256) -> Result<u8, UniswapV3MathError> {
5    if x.is_zero() {
6        return Err(UniswapV3MathError::ZeroValue);
7    }
8    Ok(255 - x.leading_zeros() as u8)
9}
10
11pub fn least_significant_bit(x: U256) -> Result<u8, UniswapV3MathError> {
12    if x.is_zero() {
13        return Err(UniswapV3MathError::ZeroValue);
14    }
15    Ok(x.trailing_zeros() as u8)
16}
17
18#[cfg(test)]
19mod test {
20    use super::most_significant_bit;
21    use crate::{bit_math::least_significant_bit, U256_1};
22    use alloy::primitives::U256;
23    use std::str::FromStr;
24
25    #[test]
26    fn test_most_significant_bit() {
27        //0
28        let result = most_significant_bit(U256::ZERO);
29        assert_eq!(result.unwrap_err().to_string(), "Can not get most significant bit or least significant bit on zero value");
30
31        //1
32        let result = most_significant_bit(U256_1);
33        assert_eq!(result.unwrap(), 0);
34
35        //2
36        let result = most_significant_bit(U256::from(2));
37        assert_eq!(result.unwrap(), 1);
38
39        //all powers of 2
40        for i in 0..=255 {
41            let result = most_significant_bit(U256::from(2).pow(U256::from(i)));
42            assert_eq!(result.unwrap(), i as u8);
43        }
44
45        //uint256(-1)
46        let result = most_significant_bit(
47            //TODO:FIXME: might need to be from dec string
48            U256::from_str("115792089237316195423570985008687907853269984665640564039457584007913129639935").unwrap(),
49        );
50        assert_eq!(result.unwrap(), 255);
51    }
52
53    #[test]
54    fn test_least_significant_bit() {
55        //0
56        let result = least_significant_bit(U256::ZERO);
57        assert_eq!(result.unwrap_err().to_string(), "Can not get most significant bit or least significant bit on zero value");
58
59        //1
60        let result = least_significant_bit(U256_1);
61        assert_eq!(result.unwrap(), 0);
62
63        //2
64        let result = least_significant_bit(U256::from(2));
65        assert_eq!(result.unwrap(), 1);
66
67        //all powers of 2
68        for i in 0..=255 {
69            let result = least_significant_bit(U256::from(2).pow(U256::from(i)));
70            assert_eq!(result.unwrap(), i as u8);
71        }
72
73        //uint256(-1)
74        let result = least_significant_bit(
75            //TODO:FIXME: might need to be from dec string
76            U256::from_str("115792089237316195423570985008687907853269984665640564039457584007913129639935").unwrap(),
77        );
78        assert_eq!(result.unwrap(), 0);
79    }
80}