Skip to content

Commit

Permalink
fix update tick
Browse files Browse the repository at this point in the history
  • Loading branch information
none00y committed Apr 24, 2024
1 parent 2c24fba commit 3f29d4f
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 32 deletions.
62 changes: 38 additions & 24 deletions src/contracts/storage/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ pub struct Pool {
pub fee_receiver: Address,
}

#[derive(PartialEq, Eq, Debug, Clone)]
pub enum UpdatePoolTick {
NoTick,
TickInitialized(Tick),
TickUninitialized(i32),
}

impl Default for Pool {
fn default() -> Self {
Self {
Expand Down Expand Up @@ -155,7 +162,7 @@ impl Pool {
&mut self,
result: SwapResult,
swap_limit: SqrtPrice,
tick: Option<&mut Tick>,
tick: &mut UpdatePoolTick,
mut remaining_amount: TokenAmount,
by_amount_in: bool,
x_to_y: bool,
Expand All @@ -165,17 +172,27 @@ impl Pool {
) -> (TokenAmount, TokenAmount, bool) {
let mut has_crossed = false;
let mut total_amount = TokenAmount::new(U256::from(0));
match tick {
Some(tick) 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,
));

if UpdatePoolTick::NoTick == *tick || swap_limit != result.next_sqrt_price {
self.current_tick_index = unwrap!(get_tick_at_sqrt_price(
result.next_sqrt_price,
fee_tier.tick_spacing
));

return (total_amount, remaining_amount, has_crossed);
};

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,
));

let tick_index = match tick {
UpdatePoolTick::TickInitialized(tick) => {
if !x_to_y || is_enough_amount_to_cross {
let _ = tick.cross(self, current_timestamp);
has_crossed = true;
Expand All @@ -187,20 +204,17 @@ impl Pool {
remaining_amount = TokenAmount::new(U256::from(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
};
tick.index
}
_ => {
self.current_tick_index = unwrap!(get_tick_at_sqrt_price(
result.next_sqrt_price,
fee_tier.tick_spacing
));
}
}
UpdatePoolTick::TickUninitialized(index) => *index,
_ => panic!("Horrible things happened"),
};

self.current_tick_index = if x_to_y && is_enough_amount_to_cross {
tick_index - fee_tier.tick_spacing as i32
} else {
tick_index
};

(total_amount, remaining_amount, has_crossed)
}
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/storage/tick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use odra::types::{U128, U256};
use odra::OdraType;
use traceable_result::*;

#[derive(OdraType, PartialEq, Debug, Copy)]
#[derive(OdraType, PartialEq, Debug, Copy, Eq)]
pub struct Tick {
pub index: i32,
pub sign: bool,
Expand Down
20 changes: 13 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::math::{check_tick, percentage::Percentage, sqrt_price::SqrtPrice};
use contracts::{events::*, unwrap_invariant_result, InvariantConfig, InvariantErrorReturn};
use contracts::{
FeeTier, FeeTiers, Pool, PoolKey, PoolKeys, Pools, Position, Positions, Tick, Tickmap, Ticks,
UpdatePoolTick,
};
use decimal::*;
use math::clamm::{calculate_min_amount_out, compute_swap_step, SwapResult};
Expand Down Expand Up @@ -172,18 +173,23 @@ impl Invariant {
contract_env::revert(InvariantErrorReturn::PriceLimitReached);
}

let mut tick = None;

if let Some((tick_index, is_initialized)) = limiting_tick {
if is_initialized {
tick = self.ticks.get(pool_key, tick_index)?.into()
let mut tick_update = {
if let Some((tick_index, is_initialized)) = limiting_tick {
if is_initialized {
let tick = self.ticks.get(pool_key, tick_index)?;
UpdatePoolTick::TickInitialized(tick)
} else {
UpdatePoolTick::TickUninitialized(tick_index)
}
} else {
UpdatePoolTick::NoTick
}
};

let (amount_to_add, amount_after_tick_update, has_crossed) = pool.update_tick(
result,
swap_limit,
tick.as_mut(),
&mut tick_update,
remaining_amount,
by_amount_in,
x_to_y,
Expand All @@ -195,7 +201,7 @@ impl Invariant {
remaining_amount = amount_after_tick_update;
total_amount_in += amount_to_add;

if let Some(tick) = tick {
if let UpdatePoolTick::TickInitialized(tick) = tick_update {
if has_crossed {
ticks.push(tick)
}
Expand Down

0 comments on commit 3f29d4f

Please sign in to comment.