diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index dca8286a..8034af5d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -36,7 +36,7 @@ jobs: uses: actions-rs/cargo@v1 with: command: clippy - # args: --all-targets -- --no-deps -D warnings (TODO: fix clippy warnings first) + args: --all-targets -- --no-deps -D warnings - name: Check if substrate-contracts-node exists id: check-substrate-contracts-node diff --git a/src/contracts/collections/pool_keys.rs b/src/contracts/collections/pool_keys.rs index f546c93f..2acdc464 100644 --- a/src/contracts/collections/pool_keys.rs +++ b/src/contracts/collections/pool_keys.rs @@ -17,6 +17,7 @@ impl PoolKeys { Ok(()) } + #[allow(dead_code)] pub fn remove(&mut self, pool_key: PoolKey) -> Result<(), InvariantError> { let index = self .pool_keys diff --git a/src/contracts/collections/pools.rs b/src/contracts/collections/pools.rs index 41dac7a1..14b59475 100644 --- a/src/contracts/collections/pools.rs +++ b/src/contracts/collections/pools.rs @@ -27,6 +27,7 @@ impl Pools { Ok(()) } + #[allow(dead_code)] pub fn remove(&mut self, pool_key: PoolKey) -> Result<(), InvariantError> { self.get(pool_key)?; diff --git a/src/contracts/entrypoints.rs b/src/contracts/entrypoints.rs index fa2e8316..36ae49fd 100644 --- a/src/contracts/entrypoints.rs +++ b/src/contracts/entrypoints.rs @@ -2,7 +2,7 @@ use crate::{ contract::{CalculateSwapResult, Hop, QuoteResult}, contracts::{FeeTier, Pool, PoolKey, Position, Tick}, math::{ - liquidity::Liquidity, percentage::Percentage, sqrt_price::sqrt_price::SqrtPrice, + liquidity::Liquidity, percentage::Percentage, sqrt_price::SqrtPrice, token_amount::TokenAmount, }, InvariantError, diff --git a/src/contracts/logic/math.rs b/src/contracts/logic/math.rs index 0ce62380..26186686 100644 --- a/src/contracts/logic/math.rs +++ b/src/contracts/logic/math.rs @@ -2,7 +2,7 @@ use decimal::*; use traceable_result::*; use crate::math::liquidity::Liquidity; -use crate::math::sqrt_price::sqrt_price::{calculate_sqrt_price, SqrtPrice}; +use crate::math::sqrt_price::{calculate_sqrt_price, SqrtPrice}; use crate::math::token_amount::TokenAmount; use crate::math::MAX_TICK; @@ -19,6 +19,7 @@ pub struct SingleTokenLiquidity { pub amount: TokenAmount, } +#[allow(dead_code)] pub fn get_liquidity( x: TokenAmount, y: TokenAmount, @@ -92,6 +93,7 @@ pub fn get_liquidity( }) } +#[allow(dead_code)] pub fn get_liquidity_by_x( x: TokenAmount, lower_tick: i32, @@ -164,6 +166,7 @@ pub fn get_liquidity_by_x_sqrt_price( }) } +#[allow(dead_code)] pub fn get_liquidity_by_y( y: TokenAmount, lower_tick: i32, @@ -187,6 +190,7 @@ pub fn get_liquidity_by_y( )) } +#[allow(dead_code)] pub fn get_liquidity_by_y_sqrt_price( y: TokenAmount, lower_sqrt_price: SqrtPrice, @@ -235,6 +239,7 @@ pub fn get_liquidity_by_y_sqrt_price( }) } +#[allow(dead_code)] pub fn calculate_x( nominator: SqrtPrice, denominator: SqrtPrice, diff --git a/src/contracts/storage/oracle.rs b/src/contracts/storage/oracle.rs index cf9ba1e2..1f1dfff3 100644 --- a/src/contracts/storage/oracle.rs +++ b/src/contracts/storage/oracle.rs @@ -1,4 +1,4 @@ -use crate::math::types::sqrt_price::sqrt_price::SqrtPrice; +use crate::math::types::sqrt_price::SqrtPrice; use ink::prelude::{vec, vec::Vec}; #[derive(Default, Debug, PartialEq, Clone, scale::Decode, scale::Encode)] diff --git a/src/contracts/storage/pool.rs b/src/contracts/storage/pool.rs index e2758655..0fe45fc7 100644 --- a/src/contracts/storage/pool.rs +++ b/src/contracts/storage/pool.rs @@ -1,18 +1,19 @@ -use super::{FeeTier, Oracle, Tick}; // Tickmap +use super::{FeeTier, Oracle, Tick}; use crate::{ contracts::PoolKey, math::{ - math::*, - sqrt_price::sqrt_price::calculate_sqrt_price, + clamm::*, + log::get_tick_at_sqrt_price, types::{ fee_growth::FeeGrowth, liquidity::Liquidity, percentage::Percentage, - sqrt_price::{log::get_tick_at_sqrt_price, sqrt_price::SqrtPrice}, + sqrt_price::{calculate_sqrt_price, SqrtPrice}, token_amount::TokenAmount, }, }, }; + use decimal::*; use ink::primitives::AccountId; use traceable_result::*; diff --git a/src/contracts/storage/position.rs b/src/contracts/storage/position.rs index 04916020..56e9ff93 100644 --- a/src/contracts/storage/position.rs +++ b/src/contracts/storage/position.rs @@ -1,11 +1,11 @@ -use super::{Pool, PoolKey, Tick}; // Tickmap +use super::{Pool, PoolKey, Tick}; use crate::{ math::{ - math::*, + clamm::*, types::{ fee_growth::{calculate_fee_growth_inside, FeeGrowth}, liquidity::Liquidity, - sqrt_price::sqrt_price::SqrtPrice, + sqrt_price::SqrtPrice, token_amount::TokenAmount, }, }, diff --git a/src/contracts/storage/tick.rs b/src/contracts/storage/tick.rs index 371dc1eb..bed4c420 100644 --- a/src/contracts/storage/tick.rs +++ b/src/contracts/storage/tick.rs @@ -1,13 +1,10 @@ +use super::Pool; use crate::math::types::{ - fee_growth::FeeGrowth, liquidity::Liquidity, sqrt_price::sqrt_price::calculate_sqrt_price, - sqrt_price::sqrt_price::SqrtPrice, + fee_growth::FeeGrowth, liquidity::Liquidity, sqrt_price::calculate_sqrt_price, + sqrt_price::SqrtPrice, }; - -use traceable_result::*; - use decimal::*; - -use super::Pool; +use traceable_result::*; #[derive(Debug, Copy, Clone, scale::Decode, scale::Encode, PartialEq)] #[cfg_attr( @@ -160,7 +157,7 @@ impl Tick { mod tests { use decimal::{Decimal, Factories}; - use crate::math::math::calculate_max_liquidity_per_tick; + use crate::math::clamm::calculate_max_liquidity_per_tick; use super::*; diff --git a/src/contracts/storage/tickmap.rs b/src/contracts/storage/tickmap.rs index 646af743..28a452b0 100644 --- a/src/contracts/storage/tickmap.rs +++ b/src/contracts/storage/tickmap.rs @@ -1,9 +1,10 @@ use crate::contracts::PoolKey; use crate::math::{ - types::sqrt_price::sqrt_price::{calculate_sqrt_price, SqrtPrice}, + types::sqrt_price::{calculate_sqrt_price, SqrtPrice}, MAX_TICK, }; use ink::storage::Mapping; + pub const TICK_SEARCH_RANGE: i32 = 256; pub const CHUNK_SIZE: i32 = 64; diff --git a/src/lib.rs b/src/lib.rs index db9728ec..1b64607f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ extern crate alloc; mod contracts; pub mod math; - #[derive(Debug, PartialEq, Eq, scale::Encode, scale::Decode)] #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] pub enum InvariantError { @@ -30,26 +29,27 @@ pub enum InvariantError { TokensAreTheSame, AmountUnderMinimumAmountOut, InvalidFee, + NotEmptyTickDeinitialization, } #[ink::contract] pub mod contract { use crate::InvariantError; - // use math::fee_growth::FeeGrowth; + use crate::contracts::state::State; use crate::contracts::Invariant; use crate::contracts::Pool; use crate::contracts::PoolKeys; use crate::contracts::Tick; use crate::contracts::Tickmap; - use crate::contracts::{FeeTier, FeeTiers, PoolKey, Pools, Position, Positions, Ticks}; // + use crate::contracts::{FeeTier, FeeTiers, PoolKey, Pools, Position, Positions, Ticks}; use crate::math::calculate_min_amount_out; use crate::math::check_tick; + use crate::math::log::get_tick_at_sqrt_price; 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::sqrt_price::SqrtPrice; use crate::math::token_amount::TokenAmount; - use crate::math::types::liquidity::Liquidity; - // use crate + use crate::math::types::liquidity::Liquidity; // + use crate::math::{compute_swap_step, MAX_SQRT_PRICE, MIN_SQRT_PRICE}; use decimal::*; use ink::contract_ref; @@ -189,7 +189,7 @@ pub mod contract { sqrt_price_limit: SqrtPrice, ) -> Result { let current_timestamp = self.env().block_timestamp(); - let caller = self.env().caller(); + if amount.is_zero() { return Err(InvariantError::AmountIsZero); } @@ -258,7 +258,7 @@ pub mod contract { if let Some((tick_index, is_initialized)) = limiting_tick { if is_initialized { - let mut tick = self.ticks.get(pool_key, tick_index).unwrap(); + let mut tick = self.ticks.get(pool_key, tick_index)?; let (amount_to_add, has_crossed) = pool.cross_tick( result, @@ -300,9 +300,14 @@ pub mod contract { }) } - fn remove_tick(&mut self, key: PoolKey, index: i32) -> Result<(), InvariantError> { - self.ticks.remove(key, index)?; + fn remove_tick(&mut self, key: PoolKey, tick: Tick) -> Result<(), InvariantError> { + if !tick.liquidity_gross.is_zero() { + return Err(InvariantError::NotEmptyTickDeinitialization); + } + self.tickmap + .flip(false, tick.index, key.fee_tier.tick_spacing, key); + self.ticks.remove(key, tick.index)?; Ok(()) } @@ -557,7 +562,7 @@ pub mod contract { crossed_tick_indexes.push(tick.index); } - if crossed_tick_indexes.len() > 0 { + if !crossed_tick_indexes.is_empty() { self.emit_cross_tick_event(caller, pool_key, crossed_tick_indexes); } @@ -796,41 +801,23 @@ pub mod contract { position.pool_key.fee_tier.tick_spacing, ); - self.pools.update(position.pool_key, pool).unwrap(); + self.pools.update(position.pool_key, pool)?; if deinitialize_lower_tick { - self.tickmap.flip( - false, - lower_tick.index, - position.pool_key.fee_tier.tick_spacing, - position.pool_key, - ); - self.ticks - .remove(position.pool_key, position.lower_tick_index) - .unwrap(); + self.remove_tick(position.pool_key, lower_tick)?; } else { self.ticks - .update(position.pool_key, position.lower_tick_index, &lower_tick) - .unwrap(); + .update(position.pool_key, position.lower_tick_index, &lower_tick)?; } if deinitialize_upper_tick { - self.tickmap.flip( - false, - upper_tick.index, - position.pool_key.fee_tier.tick_spacing, - position.pool_key, - ); - self.ticks - .remove(position.pool_key, position.upper_tick_index) - .unwrap(); + self.remove_tick(position.pool_key, upper_tick)?; } else { self.ticks - .update(position.pool_key, position.upper_tick_index, &upper_tick) - .unwrap(); + .update(position.pool_key, position.upper_tick_index, &upper_tick)?; } - self.positions.remove(caller, index).unwrap(); + self.positions.remove(caller, index)?; let mut token_x: contract_ref!(PSP22) = position.pool_key.token_x.into(); token_x @@ -1070,8 +1057,8 @@ pub mod contract { use crate::contracts::{get_liquidity, get_liquidity_by_x, get_liquidity_by_y}; use crate::math::fee_growth::FeeGrowth; use crate::math::get_delta_y; - use crate::math::sqrt_price::log::get_tick_at_sqrt_price; - use crate::math::sqrt_price::sqrt_price::{calculate_sqrt_price, get_max_tick}; + use crate::math::log::get_tick_at_sqrt_price; + use crate::math::sqrt_price::{calculate_sqrt_price, get_max_tick}; use crate::math::MAX_TICK; use ink::prelude::vec; use ink::prelude::vec::Vec; diff --git a/src/math/math.rs b/src/math/clamm.rs similarity index 99% rename from src/math/math.rs rename to src/math/clamm.rs index 482adc33..4bde8d35 100644 --- a/src/math/math.rs +++ b/src/math/clamm.rs @@ -2,7 +2,7 @@ use decimal::*; use traceable_result::*; use crate::math::consts::*; -use crate::math::types::{liquidity::*, percentage::*, sqrt_price::sqrt_price::*, token_amount::*}; +use crate::math::types::{liquidity::*, percentage::*, sqrt_price::*, token_amount::*}; #[derive(PartialEq, Debug, Copy, Clone)] pub struct SwapResult { @@ -1289,7 +1289,7 @@ mod tests { .get(); assert_eq!( cause, - "conversion to contract::math::types::sqrt_price::sqrt_price::SqrtPrice type failed" + "conversion to contract::math::types::sqrt_price::SqrtPrice type failed" ); assert_eq!(stack.len(), 2); } @@ -1343,7 +1343,7 @@ mod tests { .get(); assert_eq!( cause, - "conversion to contract::math::types::sqrt_price::sqrt_price::SqrtPrice type failed" + "conversion to contract::math::types::sqrt_price::SqrtPrice type failed" ); assert_eq!(stack.len(), 2); } @@ -1358,7 +1358,7 @@ mod tests { .get(); assert_eq!( cause, - "conversion to contract::math::types::sqrt_price::sqrt_price::SqrtPrice type failed" + "conversion to contract::math::types::sqrt_price::SqrtPrice type failed" ); assert_eq!(stack.len(), 2); } diff --git a/src/math/types/sqrt_price/log.rs b/src/math/log.rs similarity index 99% rename from src/math/types/sqrt_price/log.rs rename to src/math/log.rs index 648e16b5..824b5d16 100644 --- a/src/math/types/sqrt_price/log.rs +++ b/src/math/log.rs @@ -1,7 +1,7 @@ use traceable_result::*; use crate::math::consts::*; -use crate::math::types::sqrt_price::sqrt_price::SqrtPrice; +use crate::math::types::sqrt_price::SqrtPrice; const LOG2_SCALE: u8 = 32; const LOG2_DOUBLE_SCALE: u8 = 64; diff --git a/src/math/mod.rs b/src/math/mod.rs index f36ceabd..b2c345be 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -1,6 +1,9 @@ +pub mod clamm; pub mod consts; -pub mod math; +pub mod log; pub mod types; + +pub use clamm::*; pub use consts::*; -pub use math::*; +pub use log::*; pub use types::*; diff --git a/src/math/types/fee_growth.rs b/src/math/types/fee_growth.rs index 7799bc77..bebc4632 100644 --- a/src/math/types/fee_growth.rs +++ b/src/math/types/fee_growth.rs @@ -105,9 +105,7 @@ pub fn calculate_fee_growth_inside( mod tests { use super::*; use crate::math::consts::MAX_TICK; - // use crate::math::calculate_sqrt_price; - use crate::math::types::sqrt_price::sqrt_price::SqrtPrice; - // use decimal::{BetweenDecimals, Decimal, Factories}; + use crate::math::types::sqrt_price::SqrtPrice; #[test] fn test_unchecked_add() { diff --git a/src/math/types/sqrt_price/sqrt_price.rs b/src/math/types/sqrt_price.rs similarity index 100% rename from src/math/types/sqrt_price/sqrt_price.rs rename to src/math/types/sqrt_price.rs diff --git a/src/math/types/sqrt_price/mod.rs b/src/math/types/sqrt_price/mod.rs deleted file mode 100644 index 6edb8422..00000000 --- a/src/math/types/sqrt_price/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod log; -pub mod sqrt_price; diff --git a/src/math/types/token_amount.rs b/src/math/types/token_amount.rs index 8e912887..50ec685f 100644 --- a/src/math/types/token_amount.rs +++ b/src/math/types/token_amount.rs @@ -1,7 +1,7 @@ use decimal::*; use traceable_result::*; -use super::sqrt_price::sqrt_price::SqrtPrice; +use super::sqrt_price::SqrtPrice; #[decimal(0)] #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, scale::Decode, scale::Encode)] diff --git a/tests.sh b/tests.sh index d1c53ba8..46d4dd41 100755 --- a/tests.sh +++ b/tests.sh @@ -21,7 +21,7 @@ cd decimal_core cd ../../.. cargo fmt --all -- --check -cargo clippy +cargo clippy --all-targets -- --no-deps -D warnings cargo test --features e2e-tests