Skip to content

Commit

Permalink
Merge pull request #92 from invariant-labs/tick-refactor
Browse files Browse the repository at this point in the history
Refactored Tick in calculate_swap
  • Loading branch information
Sniezka1927 authored Dec 4, 2023
2 parents a12f3d3 + 4ea96da commit 159acca
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 67 deletions.
65 changes: 30 additions & 35 deletions src/contracts/storage/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,56 +134,51 @@ impl Pool {
&mut self,
result: SwapResult,
swap_limit: SqrtPrice,
limiting_tick: Option<(i32, Option<&mut Tick>)>,
tick: &mut Tick,
remaining_amount: &mut TokenAmount,
by_amount_in: bool,
x_to_y: bool,
current_timestamp: u64,
total_amount_in: &mut TokenAmount,
protocol_fee: Percentage,
fee_tier: FeeTier,
) -> bool {
) -> (TokenAmount, bool) {
let mut has_crossed = false;
if result.next_sqrt_price == swap_limit && limiting_tick.is_some() {
if let Some((tick_index, tick)) = limiting_tick {
let is_enough_amount_to_cross = unwrap!(is_enough_amount_to_change_price(
*remaining_amount,
result.next_sqrt_price,
self.liquidity,
fee_tier.fee,
by_amount_in,
x_to_y,
));

// crossing tick
if let Some(tick) = tick {
if !x_to_y || is_enough_amount_to_cross {
let _ = tick.cross(self, current_timestamp);
has_crossed = true;
} else if !remaining_amount.is_zero() {
if by_amount_in {
self.add_fee(*remaining_amount, x_to_y, protocol_fee)
.unwrap();
*total_amount_in += *remaining_amount
}
*remaining_amount = TokenAmount(0);
}
}
let mut total_amount = TokenAmount(0);
if result.next_sqrt_price == swap_limit {
let is_enough_amount_to_cross = unwrap!(is_enough_amount_to_change_price(
*remaining_amount,
result.next_sqrt_price,
self.liquidity,
fee_tier.fee,
by_amount_in,
x_to_y,
));

// set tick to limit (below if price is going down, because current tick should always be below price)
self.current_tick_index = if x_to_y && is_enough_amount_to_cross {
tick_index - fee_tier.tick_spacing as i32
} else {
tick_index
};
if !x_to_y || is_enough_amount_to_cross {
let _ = tick.cross(self, current_timestamp);
has_crossed = true;
} else if !remaining_amount.is_zero() {
if by_amount_in {
unwrap!(self.add_fee(*remaining_amount, x_to_y, protocol_fee));
total_amount = *remaining_amount;
}
*remaining_amount = TokenAmount(0);
}

// set tick to limit (below if price is going down, because current tick should always be below price)
self.current_tick_index = if x_to_y && is_enough_amount_to_cross {
tick.index - fee_tier.tick_spacing as i32
} else {
tick.index
};
} else {
self.current_tick_index = unwrap!(get_tick_at_sqrt_price(
result.next_sqrt_price,
fee_tier.tick_spacing
));
};
has_crossed

(total_amount, has_crossed)
}

pub fn withdraw_protocol_fee(&mut self, _pool_key: PoolKey) -> (TokenAmount, TokenAmount) {
Expand Down
68 changes: 37 additions & 31 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ pub mod contract {
use crate::math::calculate_min_amount_out;
use crate::math::check_tick;
use crate::math::percentage::Percentage;
use crate::math::sqrt_price::log::get_tick_at_sqrt_price;
use crate::math::sqrt_price::sqrt_price::SqrtPrice;
use crate::math::token_amount::TokenAmount;
use crate::math::types::liquidity::Liquidity;
// use crate
use crate::math::{compute_swap_step, MAX_SQRT_PRICE, MIN_SQRT_PRICE};
use decimal::*;
use ink::contract_ref;
Expand All @@ -73,7 +75,7 @@ pub mod contract {
timestamp: u64,
address: AccountId,
pool: PoolKey,
index: i32,
indexes: Vec<i32>,
}

#[ink(event)]
Expand Down Expand Up @@ -254,35 +256,32 @@ pub mod contract {
return Err(InvariantError::PriceLimitReached);
}

// TODO: refactor
let mut tick = Tick::default();

let update_limiting_tick = limiting_tick.map(|(index, bool)| {
if bool {
tick = self.ticks.get(pool_key, index).unwrap();
(index, Some(&mut tick))
} else {
(index, None)
if let Some((tick_index, is_initialized)) = limiting_tick {
if is_initialized {
let mut tick = self.ticks.get(pool_key, tick_index).unwrap();

let (amount_to_add, has_crossed) = pool.cross_tick(
result,
swap_limit,
&mut tick,
&mut remaining_amount,
by_amount_in,
x_to_y,
current_timestamp,
self.state.protocol_fee,
pool_key.fee_tier,
);

total_amount_in += amount_to_add;
if has_crossed {
ticks.push(tick);
}
}
});

let has_crossed = pool.cross_tick(
result,
swap_limit,
update_limiting_tick,
&mut remaining_amount,
by_amount_in,
x_to_y,
current_timestamp,
&mut total_amount_in,
self.state.protocol_fee,
pool_key.fee_tier,
);

if has_crossed {
self.emit_cross_tick_event(caller, pool_key, limiting_tick.unwrap().0);

ticks.push(tick);
} else {
pool.current_tick_index = unwrap!(get_tick_at_sqrt_price(
result.next_sqrt_price,
pool_key.fee_tier.tick_spacing
));
}
}

Expand Down Expand Up @@ -384,15 +383,15 @@ pub mod contract {
);
}

fn emit_cross_tick_event(&self, address: AccountId, pool: PoolKey, index: i32) {
fn emit_cross_tick_event(&self, address: AccountId, pool: PoolKey, indexes: Vec<i32>) {
let timestamp = self.get_timestamp();
ink::codegen::EmitEvent::<Contract>::emit_event(
self.env(),
CrossTickEvent {
timestamp,
address,
pool,
index,
indexes,
},
);
}
Expand Down Expand Up @@ -551,8 +550,15 @@ pub mod contract {
let calculate_swap_result =
self.calculate_swap(pool_key, x_to_y, amount, by_amount_in, sqrt_price_limit)?;

let mut crossed_tick_indexes: Vec<i32> = vec![];

for tick in calculate_swap_result.ticks.iter() {
self.ticks.update(pool_key, tick.index, tick)?;
crossed_tick_indexes.push(tick.index);
}

if crossed_tick_indexes.len() > 0 {
self.emit_cross_tick_event(caller, pool_key, crossed_tick_indexes);
}

self.pools.update(pool_key, &calculate_swap_result.pool)?;
Expand Down
2 changes: 1 addition & 1 deletion src/math/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use traceable_result::*;
use crate::math::consts::*;
use crate::math::types::{liquidity::*, percentage::*, sqrt_price::sqrt_price::*, token_amount::*};

#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct SwapResult {
pub next_sqrt_price: SqrtPrice,
pub amount_in: TokenAmount,
Expand Down

0 comments on commit 159acca

Please sign in to comment.