Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 93 additions & 39 deletions src/math/tick.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::math::uint::U256;
use crate::{math::uint::u256_to_float_base_x128, math::uint::U256};

const ONE_X128: U256 = U256([0, 0, 1, 0]);

Expand Down Expand Up @@ -76,50 +76,104 @@ pub fn to_sqrt_ratio(tick: i32) -> Option<U256> {
Some(ratio)
}

const SQRT_TICK_SIZE: f64 =
1.00000049999987500006249996093752734372949220361326815796989439990616646_f64;

pub fn approximate_sqrt_ratio_to_tick(sqrt_ratio: U256) -> i32 {
u256_to_float_base_x128(sqrt_ratio)
.log(SQRT_TICK_SIZE)
.round() as i32
}

#[cfg(test)]
mod tests {
use super::{to_sqrt_ratio, MAX_SQRT_RATIO, MAX_TICK, MIN_SQRT_RATIO, MIN_TICK};
use crate::math::uint::U256;

#[test]
fn test_tick_examples() {
assert_eq!(
to_sqrt_ratio(1000000).unwrap(),
U256::from_str_radix("561030636129153856579134353873645338624", 10).unwrap(),
);
assert_eq!(
to_sqrt_ratio(10000000).unwrap(),
U256::from_str_radix("50502254805927926084423855178401471004672", 10).unwrap(),
);
assert_eq!(
to_sqrt_ratio(-1000000).unwrap(),
U256::from_str_radix("206391740095027370700312310528859963392", 10).unwrap(),
);
assert_eq!(
to_sqrt_ratio(-10000000).unwrap(),
U256::from_str_radix("2292810285051363400276741630355046400", 10).unwrap(),
);
}
mod to_sqrt_ratio {
use super::super::{to_sqrt_ratio, MAX_SQRT_RATIO, MAX_TICK, MIN_SQRT_RATIO, MIN_TICK};
use crate::math::uint::U256;

#[test]
fn test_tick_examples() {
assert_eq!(
to_sqrt_ratio(1000000).unwrap(),
U256::from_str_radix("561030636129153856579134353873645338624", 10).unwrap(),
);
assert_eq!(
to_sqrt_ratio(10000000).unwrap(),
U256::from_str_radix("50502254805927926084423855178401471004672", 10).unwrap(),
);
assert_eq!(
to_sqrt_ratio(-1000000).unwrap(),
U256::from_str_radix("206391740095027370700312310528859963392", 10).unwrap(),
);
assert_eq!(
to_sqrt_ratio(-10000000).unwrap(),
U256::from_str_radix("2292810285051363400276741630355046400", 10).unwrap(),
);
}

#[test]
fn test_tick_too_small() {
assert!(to_sqrt_ratio(MIN_TICK - 1).is_none());
assert!(to_sqrt_ratio(i32::MIN).is_none());
}
#[test]
fn test_tick_too_small() {
assert!(to_sqrt_ratio(MIN_TICK - 1).is_none());
assert!(to_sqrt_ratio(i32::MIN).is_none());
}

#[test]
fn test_min_tick() {
assert_eq!(to_sqrt_ratio(MIN_TICK).unwrap(), MIN_SQRT_RATIO,);
}
#[test]
fn test_min_tick() {
assert_eq!(to_sqrt_ratio(MIN_TICK).unwrap(), MIN_SQRT_RATIO,);
}

#[test]
fn test_max_tick() {
assert_eq!(to_sqrt_ratio(MAX_TICK).unwrap(), MAX_SQRT_RATIO,);
#[test]
fn test_max_tick() {
assert_eq!(to_sqrt_ratio(MAX_TICK).unwrap(), MAX_SQRT_RATIO,);
}

#[test]
fn test_tick_too_large() {
assert!(to_sqrt_ratio(MAX_TICK + 1).is_none());
assert!(to_sqrt_ratio(i32::MAX).is_none());
}
}

#[test]
fn test_tick_too_large() {
assert!(to_sqrt_ratio(MAX_TICK + 1).is_none());
assert!(to_sqrt_ratio(i32::MAX).is_none());
mod approximate_sqrt_ratio_to_tick {
use crate::math::tick::{MAX_TICK, MIN_TICK};

use super::super::{approximate_sqrt_ratio_to_tick, to_sqrt_ratio};

#[test]
fn test_tick_examples() {
assert_eq!(approximate_sqrt_ratio_to_tick(to_sqrt_ratio(0).unwrap()), 0,);
assert_eq!(
approximate_sqrt_ratio_to_tick(to_sqrt_ratio(1000000).unwrap()),
1000000,
);
assert_eq!(
approximate_sqrt_ratio_to_tick(to_sqrt_ratio(10000000).unwrap()),
10000000
);
assert_eq!(
approximate_sqrt_ratio_to_tick(to_sqrt_ratio(-1000000).unwrap()),
-1000000,
);
assert_eq!(
approximate_sqrt_ratio_to_tick(to_sqrt_ratio(-10000000).unwrap()),
-10000000,
);
}

#[test]
fn test_min_tick() {
assert_eq!(
approximate_sqrt_ratio_to_tick(to_sqrt_ratio(MIN_TICK).unwrap()),
MIN_TICK,
);
}

#[test]
fn test_max_tick() {
assert_eq!(
approximate_sqrt_ratio_to_tick(to_sqrt_ratio(MAX_TICK).unwrap()),
MAX_TICK,
);
}
}
}
7 changes: 7 additions & 0 deletions src/math/uint.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
uint::construct_uint! {
pub struct U256(4);
}

pub fn u256_to_float_base_x128(x128: U256) -> f64 {
x128.0[0] as f64 / 340282366920938463463374607431768211456f64
+ (x128.0[1] as f64 / 18446744073709551616f64)
+ x128.0[2] as f64
+ (x128.0[3] as f64 * 18446744073709551616f64)
}
4 changes: 4 additions & 0 deletions src/quoting/base_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,10 @@ impl Pool for BasePool {
fn min_tick_with_liquidity(&self) -> Option<i32> {
self.sorted_ticks.first().map(|t| t.index)
}

fn is_path_dependent(&self) -> bool {
false
}
}

#[cfg(test)]
Expand Down
12 changes: 9 additions & 3 deletions src/quoting/full_range_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub struct FullRangePool {
pub enum FullRangePoolError {
/// Token0 must be less than token1.
TokenOrderInvalid,
SqrtRatioInvalid,
}

impl FullRangePool {
Expand All @@ -61,13 +62,14 @@ impl FullRangePool {
return Err(FullRangePoolError::TokenOrderInvalid);
}

// Ensure sqrt_ratio is within valid bounds
let sqrt_ratio = state.sqrt_ratio.clamp(MIN_SQRT_RATIO, MAX_SQRT_RATIO);
if state.sqrt_ratio < MIN_SQRT_RATIO || state.sqrt_ratio > MAX_SQRT_RATIO {
return Err(FullRangePoolError::SqrtRatioInvalid);
}

Ok(Self {
key,
state: FullRangePoolState {
sqrt_ratio,
sqrt_ratio: state.sqrt_ratio,
liquidity: state.liquidity,
},
})
Expand Down Expand Up @@ -220,6 +222,10 @@ impl Pool for FullRangePool {
None
}
}

fn is_path_dependent(&self) -> bool {
false
}
}

#[cfg(test)]
Expand Down
Loading