Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor create pool #107

Merged
merged 10 commits into from
Dec 12, 2023
5 changes: 5 additions & 0 deletions src/contracts/entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,18 +282,23 @@ pub trait Invariant {
/// - `token_0`: The address of the first token.
/// - `token_1`: The address of the second token.
/// - `fee_tier`: A struct identifying the pool fee and tick spacing.
/// - `init_sqrt_price`: The square root of the price for the initial pool related to `init_tick`.
/// - `init_tick`: The initial tick at which the pool will be created.
///
/// # Errors
/// - Fails if the specified fee tier cannot be found.
/// - Fails if the user attempts to create a pool for the same tokens.
/// - Fails if Pool with same tokens and fee tier already exist.
/// - Fails if the init tick is not divisible by the tick spacing.
/// - Fails if the init sqrt price is not related to the init tick.
///
#[ink(message)]
fn create_pool(
&mut self,
token_0: AccountId,
token_1: AccountId,
fee_tier: FeeTier,
init_sqrt_price: SqrtPrice,
init_tick: i32,
) -> Result<(), InvariantError>;

Expand Down
164 changes: 154 additions & 10 deletions src/contracts/storage/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use crate::{
math::{
clamm::*,
log::get_tick_at_sqrt_price,
sqrt_price::get_max_tick,
types::{
fee_growth::FeeGrowth,
liquidity::Liquidity,
percentage::Percentage,
sqrt_price::{calculate_sqrt_price, SqrtPrice},
token_amount::TokenAmount,
fee_growth::FeeGrowth, liquidity::Liquidity, percentage::Percentage,
sqrt_price::SqrtPrice, token_amount::TokenAmount,
},
MAX_TICK,
},
InvariantError,
};

use decimal::*;
Expand Down Expand Up @@ -58,15 +58,36 @@ impl Default for Pool {
}

impl Pool {
pub fn create(init_tick: i32, current_timestamp: u64, fee_receiver: AccountId) -> Self {
Self {
sqrt_price: unwrap!(calculate_sqrt_price(init_tick)),
pub fn create(
Sniezka1927 marked this conversation as resolved.
Show resolved Hide resolved
init_sqrt_price: SqrtPrice,
init_tick: i32,
current_timestamp: u64,
tick_spacing: u16,
fee_receiver: AccountId,
) -> Result<Self, InvariantError> {
if init_tick + tick_spacing as i32 > MAX_TICK {
let max_tick = get_max_tick(tick_spacing);
let max_sqrt_price = unwrap!(SqrtPrice::from_tick(max_tick));
if init_sqrt_price != max_sqrt_price {
return Err(InvariantError::InvalidInitSqrtPrice);
}
} else {
let lower_bound = unwrap!(SqrtPrice::from_tick(init_tick));
let upper_bound = unwrap!(SqrtPrice::from_tick(init_tick + tick_spacing as i32));

if init_sqrt_price >= upper_bound || init_sqrt_price < lower_bound {
return Err(InvariantError::InvalidInitSqrtPrice);
}
}

Ok(Self {
sqrt_price: init_sqrt_price,
current_tick_index: init_tick,
start_timestamp: current_timestamp,
last_timestamp: current_timestamp,
fee_receiver,
..Self::default()
}
})
}

pub fn add_fee(
Expand Down Expand Up @@ -195,6 +216,7 @@ impl Pool {

#[cfg(test)]
mod tests {
use crate::math::types::sqrt_price::calculate_sqrt_price;
use decimal::Factories;

use super::*;
Expand All @@ -204,14 +226,136 @@ mod tests {
let init_tick = 100;
let current_timestamp = 100;
let fee_receiver = AccountId::from([1; 32]);
let init_sqrt_price = calculate_sqrt_price(init_tick).unwrap();

let pool = Pool::create(init_tick, current_timestamp, fee_receiver);
let pool = Pool::create(
init_sqrt_price,
init_tick,
current_timestamp,
1,
fee_receiver,
)
.unwrap();

assert_eq!(pool.sqrt_price, calculate_sqrt_price(init_tick).unwrap());
assert_eq!(pool.current_tick_index, init_tick);
assert_eq!(pool.start_timestamp, current_timestamp);
assert_eq!(pool.last_timestamp, current_timestamp);
assert_eq!(pool.fee_receiver, fee_receiver);

{
let init_tick = 0;
Sniezka1927 marked this conversation as resolved.
Show resolved Hide resolved
let init_sqrt_price = calculate_sqrt_price(init_tick).unwrap() + SqrtPrice::new(1);
let tick_spacing = 3;
let pool = Pool::create(
init_sqrt_price,
init_tick,
current_timestamp,
tick_spacing,
fee_receiver,
)
.unwrap();
assert_eq!(pool.current_tick_index, init_tick);
}
{
let init_tick = 2;
let init_sqrt_price = SqrtPrice::new(1000175003749000000000000);
let tick_spacing = 1;
let pool = Pool::create(
init_sqrt_price,
init_tick,
current_timestamp,
tick_spacing,
fee_receiver,
);
assert_eq!(pool, Err(InvariantError::InvalidInitSqrtPrice));
let correct_init_tick = 3;
let pool = Pool::create(
init_sqrt_price,
correct_init_tick,
current_timestamp,
tick_spacing,
fee_receiver,
)
.unwrap();
assert_eq!(pool.current_tick_index, correct_init_tick);
}
{
let init_tick = 0;
let init_sqrt_price = SqrtPrice::new(1000225003749000000000000);
let tick_spacing = 3;
let pool = Pool::create(
init_sqrt_price,
init_tick,
current_timestamp,
tick_spacing,
fee_receiver,
);
assert_eq!(pool, Err(InvariantError::InvalidInitSqrtPrice));
let correct_init_tick = 3;
let pool = Pool::create(
init_sqrt_price,
correct_init_tick,
current_timestamp,
tick_spacing,
fee_receiver,
)
.unwrap();
assert_eq!(pool.current_tick_index, correct_init_tick);
}
{
let init_tick = MAX_TICK;
let init_sqrt_price = calculate_sqrt_price(init_tick).unwrap();
let tick_spacing = 1;
Pool::create(
init_sqrt_price,
init_tick,
current_timestamp,
tick_spacing,
fee_receiver,
)
.unwrap();
}
{
let init_tick = MAX_TICK;
let init_sqrt_price = calculate_sqrt_price(init_tick).unwrap() - SqrtPrice::new(1);
let tick_spacing = 1;
Pool::create(
init_sqrt_price,
init_tick,
current_timestamp,
tick_spacing,
fee_receiver,
)
.unwrap_err();
}
{
let init_tick = MAX_TICK;
let init_sqrt_price = SqrtPrice::from_integer(1);
let tick_spacing = 1;
Pool::create(
init_sqrt_price,
init_tick,
current_timestamp,
tick_spacing,
fee_receiver,
)
.unwrap_err();
}
{
let init_tick = MAX_TICK - 1;
let init_sqrt_price = calculate_sqrt_price(init_tick).unwrap();
let tick_spacing = 1;
let pool = Pool::create(
init_sqrt_price,
init_tick,
current_timestamp,
tick_spacing,
fee_receiver,
)
.unwrap();
assert_eq!(pool.current_tick_index, init_tick);
}
}

#[test]
Expand Down
5 changes: 5 additions & 0 deletions src/e2e/change_fee_receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod e2e_tests {
contract::ContractRef,
contracts::{entrypoints::Invariant, FeeTier, PoolKey},
math::types::percentage::Percentage,
math::types::sqrt_price::calculate_sqrt_price,
};
use decimal::*;
use ink_e2e::build_message;
Expand All @@ -23,6 +24,7 @@ pub mod e2e_tests {

let fee_tier = FeeTier::new(Percentage::from_scale(5, 1), 1).unwrap();
let init_tick = 0;
let init_sqrt_price = calculate_sqrt_price(init_tick).unwrap();

let alice = ink_e2e::alice();

Expand All @@ -35,6 +37,7 @@ pub mod e2e_tests {
token_x,
token_y,
fee_tier,
init_sqrt_price,
init_tick,
alice
);
Expand All @@ -59,6 +62,7 @@ pub mod e2e_tests {

let fee_tier = FeeTier::new(Percentage::from_scale(5, 1), 100).unwrap();
let init_tick = 0;
let init_sqrt_price = calculate_sqrt_price(init_tick).unwrap();

let admin = ink_e2e::alice();

Expand All @@ -71,6 +75,7 @@ pub mod e2e_tests {
token_x,
token_y,
fee_tier,
init_sqrt_price,
init_tick,
admin
);
Expand Down
7 changes: 5 additions & 2 deletions src/e2e/claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ pub mod e2e_tests {
contracts::{entrypoints::Invariant, FeeTier, PoolKey},
math::{
types::{
fee_growth::FeeGrowth, liquidity::Liquidity, percentage::Percentage,
sqrt_price::SqrtPrice, token_amount::TokenAmount,
fee_growth::FeeGrowth,
liquidity::Liquidity,
percentage::Percentage,
sqrt_price::{calculate_sqrt_price, SqrtPrice},
token_amount::TokenAmount,
},
MIN_SQRT_PRICE,
},
Expand Down
Loading
Loading