Skip to content

Commit

Permalink
will code
Browse files Browse the repository at this point in the history
  • Loading branch information
Will-Smith11 committed Jan 31, 2025
1 parent 8a13c04 commit 52fed4e
Showing 1 changed file with 133 additions and 1 deletion.
134 changes: 133 additions & 1 deletion crates/types/src/matching/uniswap/poolsnapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,17 +167,26 @@ impl PoolSnapshot {
let liq_range = self.ranges_for_ticks(start_tick, end_tick).ok()?;

let mut res = 0;
let iter = if is_bid { liq_range.into_iter().rev().collect() } else { liq_range };
// bid is zero for 1
for tick in liq_range {
for tick in iter {
// bid means that price moving down
let is_start_swap = (is_bid && tick.upper_tick == start_tick)
|| (!is_bid && tick.lower_tick == start_tick);

let is_end_swap =
(is_bid && tick.lower_tick <= end_tick && tick.upper_tick >= end_tick)
|| (!is_bid && tick.upper_tick >= end_tick && tick.lower_tick <= end_tick);

// grab ratio range
let (start, target) = if is_start_swap && is_bid {
(self.sqrt_price_x96, SqrtPriceX96::at_tick(tick.lower_tick).ok()?)
} else if is_start_swap && !is_bid {
(self.sqrt_price_x96, SqrtPriceX96::at_tick(tick.upper_tick).ok()?)
} else if is_end_swap && is_bid {
(SqrtPriceX96::at_tick(tick.upper_tick).ok()?, end_price)
} else if is_end_swap && !is_bid {
(SqrtPriceX96::at_tick(tick.lower_tick).ok()?, end_price)
} else if is_bid {
(
SqrtPriceX96::at_tick(tick.upper_tick).ok()?,
Expand Down Expand Up @@ -210,3 +219,126 @@ impl PoolSnapshot {
Some(res)
}
}

#[cfg(test)]
mod tests {
use super::*;

fn setup_basic_pool() -> PoolSnapshot {
// Create a simple pool with three tick ranges
let ranges = vec![
LiqRange { lower_tick: 0, upper_tick: 100, liquidity: 1000 },
LiqRange { lower_tick: 100, upper_tick: 200, liquidity: 2000 },
LiqRange { lower_tick: 200, upper_tick: 300, liquidity: 1500 },
];

// Start price in the middle range (tick 150)
let sqrt_price_x96 = SqrtPriceX96::at_tick(150).unwrap();
PoolSnapshot::new(ranges, sqrt_price_x96).unwrap()
}

#[test]
fn test_get_deltas_bid_direction() {
let pool = setup_basic_pool();

// Test moving from tick 150 to tick 250 (upward/bid movement)
let start_price = SqrtPriceX96::at_tick(150).unwrap();
let end_price = SqrtPriceX96::at_tick(250).unwrap();

let delta = pool.get_deltas(start_price, end_price).unwrap();

// We should get a non-zero amount
assert!(delta > 0, "Delta should be positive for bid direction");

// Test the reverse direction to ensure it's different
let reverse_delta = pool.get_deltas(end_price, start_price).unwrap();
assert_ne!(delta, reverse_delta, "Bid and ask deltas should differ");
}

#[test]
fn test_get_deltas_within_same_range() {
let pool = setup_basic_pool();

// Test movement within the same tick range (150 to 180)
let start_price = SqrtPriceX96::at_tick(150).unwrap();
let end_price = SqrtPriceX96::at_tick(180).unwrap();

let delta = pool.get_deltas(start_price, end_price).unwrap();
assert!(delta > 0, "Delta should be positive within same range");

// Test a smaller price movement
let small_end_price = SqrtPriceX96::at_tick(160).unwrap();
let small_delta = pool.get_deltas(start_price, small_end_price).unwrap();
assert!(small_delta < delta, "Smaller price movement should result in smaller delta");
}

#[test]
fn test_get_deltas_cross_multiple_ranges() {
let pool = setup_basic_pool();

// Test movement across multiple ranges (50 to 250)
let start_price = SqrtPriceX96::at_tick(50).unwrap();
let end_price = SqrtPriceX96::at_tick(250).unwrap();

let delta = pool.get_deltas(start_price, end_price).unwrap();

// Test movement within a single range
let single_range_start = SqrtPriceX96::at_tick(120).unwrap();
let single_range_end = SqrtPriceX96::at_tick(180).unwrap();
let single_range_delta = pool
.get_deltas(single_range_start, single_range_end)
.unwrap();

assert!(
delta > single_range_delta,
"Cross-range delta should be larger than single range delta"
);
}

#[test]
fn test_get_deltas_edge_cases() {
let pool = setup_basic_pool();

// Test movement at range boundaries
let start_price = SqrtPriceX96::at_tick(100).unwrap(); // Exactly at a range boundary
let end_price = SqrtPriceX96::at_tick(200).unwrap(); // Another range boundary

let delta = pool.get_deltas(start_price, end_price);
assert!(delta.is_some(), "Should handle range boundary movements");

// Test minimal movement
let tiny_move_end = SqrtPriceX96::at_tick(151).unwrap();
let tiny_delta = pool.get_deltas(start_price, tiny_move_end).unwrap();
assert!(tiny_delta > 0, "Should handle minimal price movements");
}

#[test]
fn test_get_deltas_liquidity_impact() {
// Create two pools with different liquidity profiles
let high_liq_ranges = vec![
LiqRange {
lower_tick: 0,
upper_tick: 100,
liquidity: 10000 // 10x more liquidity
},
LiqRange { lower_tick: 100, upper_tick: 200, liquidity: 20000 },
];

let low_liq_ranges = vec![
LiqRange { lower_tick: 0, upper_tick: 100, liquidity: 1000 },
LiqRange { lower_tick: 100, upper_tick: 200, liquidity: 2000 },
];

let sqrt_price_x96 = SqrtPriceX96::at_tick(50).unwrap();
let high_liq_pool = PoolSnapshot::new(high_liq_ranges, sqrt_price_x96).unwrap();
let low_liq_pool = PoolSnapshot::new(low_liq_ranges, sqrt_price_x96).unwrap();

let start_price = SqrtPriceX96::at_tick(50).unwrap();
let end_price = SqrtPriceX96::at_tick(150).unwrap();

let high_liq_delta = high_liq_pool.get_deltas(start_price, end_price).unwrap();
let low_liq_delta = low_liq_pool.get_deltas(start_price, end_price).unwrap();

assert!(high_liq_delta > low_liq_delta, "Higher liquidity should result in larger delta");
}
}

0 comments on commit 52fed4e

Please sign in to comment.