From aed0d1b8da56a5581b7c186b6c42e7bfe9b5ff6c Mon Sep 17 00:00:00 2001 From: delaaxe <1091900+delaaxe@users.noreply.github.com> Date: Thu, 12 Oct 2023 10:32:36 +0300 Subject: [PATCH 1/3] wip --- src/pricing/swap_pricing_utils.cairo | 4 +- src/utils/precision.cairo | 65 +++++++++------------ tests/pricing/test_swap_pricing_utils.cairo | 59 ++++++++++++++++--- 3 files changed, 82 insertions(+), 46 deletions(-) diff --git a/src/pricing/swap_pricing_utils.cairo b/src/pricing/swap_pricing_utils.cairo index 806aa032..6c633e81 100644 --- a/src/pricing/swap_pricing_utils.cairo +++ b/src/pricing/swap_pricing_utils.cairo @@ -5,7 +5,6 @@ // ************************************************************************* // Core lib imports. use starknet::ContractAddress; -use result::ResultTrait; // Local imports. use satoru::data::data_store::{IDataStoreDispatcher, IDataStoreDispatcherTrait}; @@ -19,7 +18,6 @@ use satoru::utils::calc; use satoru::utils::precision; use satoru::utils::i128::{I128Store, I128Serde, I128Div, I128Mul}; - /// Struct used in get_price_impact_usd. #[derive(Copy, Drop, starknet::Store, Serde)] struct GetPriceImpactUsdParams { @@ -321,3 +319,5 @@ fn get_swap_fees( ui_fee_amount, } } + +use debug::PrintTrait; \ No newline at end of file diff --git a/src/utils/precision.cairo b/src/utils/precision.cairo index 8fe1cc29..3eeeaecb 100644 --- a/src/utils/precision.cairo +++ b/src/utils/precision.cairo @@ -5,17 +5,15 @@ use alexandria_math::pow; use integer::{ i128_to_felt252, u128_to_felt252, u256_wide_mul, u512_safe_div_rem_by_u256, BoundedU256, - u256_try_as_non_zero + U256TryIntoNonZero }; -use core::traits::TryInto; -use core::option::Option; use satoru::utils::calc::{roundup_division, roundup_magnitude_division}; const FLOAT_PRECISION: u128 = 100_000_000_000_000_000_000; // 10^20 const FLOAT_PRECISION_SQRT: u128 = 10_000_000_000; // 10^10 const WEI_PRECISION: u128 = 1_000_000_000_000_000_000; // 10^18 -const BASIS_POINTS_DIVISOR: u128 = 10000; +const BASIS_POINTS_DIVISOR: u128 = 10_000; const FLOAT_TO_WEI_DIVISOR: u128 = 1_000_000_000_000; // 10^12 @@ -26,7 +24,7 @@ const FLOAT_TO_WEI_DIVISOR: u128 = 1_000_000_000_000; // 10^12 /// # Returns /// The result of applying the factor to the value. fn apply_factor_u128(value: u128, factor: u128) -> u128 { - return mul_div(value, factor, FLOAT_PRECISION); + mul_div(value, factor, FLOAT_PRECISION) } /// Applies the given factor to the given value and returns the result. @@ -36,7 +34,7 @@ fn apply_factor_u128(value: u128, factor: u128) -> u128 { /// # Returns /// The result of applying the factor to the value. fn apply_factor_i128(value: u128, factor: i128) -> i128 { - return mul_div_inum(value, factor, FLOAT_PRECISION); + mul_div_inum(value, factor, FLOAT_PRECISION) } /// Applies the given factor to the given value and returns the result. @@ -46,7 +44,7 @@ fn apply_factor_i128(value: u128, factor: i128) -> i128 { /// # Returns /// The result of applying the factor to the value. fn apply_factor_roundup_magnitude(value: u128, factor: i128, roundup_magnitude: bool) -> i128 { - return mul_div_inum_roundup(value, factor, FLOAT_PRECISION, roundup_magnitude); + mul_div_inum_roundup(value, factor, FLOAT_PRECISION, roundup_magnitude) } /// Apply multiplication then division to value. @@ -55,13 +53,10 @@ fn apply_factor_roundup_magnitude(value: u128, factor: i128, roundup_magnitude: /// * `numerator` - The numerator that multiplies value. /// * `divisor` - The denominator that divides value. fn mul_div(value: u128, numerator: u128, denominator: u128) -> u128 { - let value = u256 { low: value, high: 0 }; - let numerator = u256 { low: numerator, high: 0 }; - let denominator = u256 { low: denominator, high: 0 }; - let product = u256_wide_mul(value, numerator); - let (q, _) = u512_safe_div_rem_by_u256( - product, u256_try_as_non_zero(denominator).expect('MulDivByZero') - ); + let product = u256_wide_mul(value.into(), numerator.into()); + let denominator: u256 = denominator.into(); + let non_zero_denominator = denominator.try_into().expect('MulDivByZero'); + let (q, _) = u512_safe_div_rem_by_u256(product, non_zero_denominator); assert(q.limb1 == 0 && q.limb2 == 0 && q.limb3 == 0, 'MulDivOverflow'); q.limb0 } @@ -72,7 +67,7 @@ fn mul_div(value: u128, numerator: u128, denominator: u128) -> u128 { /// * `numerator` - The numerator that multiplies value. /// * `divisor` - The denominator that divides value. fn mul_div_ival(value: i128, numerator: u128, denominator: u128) -> i128 { - return mul_div_inum(numerator, value, denominator); + mul_div_inum(numerator, value, denominator) } /// Apply multiplication then division to value. @@ -86,15 +81,15 @@ fn mul_div_inum(value: u128, numerator: i128, denominator: u128) -> i128 { } else { numerator }; - let felt252_numerator: felt252 = i128_to_felt252(numerator_abs); + let felt252_numerator: felt252 = numerator_abs.into(); let u128_numerator = felt252_numerator.try_into().expect('felt252 into u128 failed'); let result: u128 = mul_div(value, u128_numerator, denominator); - let felt252_result: felt252 = u128_to_felt252(result); + let felt252_result: felt252 = result.into(); let i128_result: i128 = felt252_result.try_into().expect('felt252 into i128 failed'); if numerator > 0 { - return i128_result; + i128_result } else { - return -i128_result; + -i128_result } } @@ -111,15 +106,15 @@ fn mul_div_inum_roundup( } else { numerator }; - let felt252_numerator: felt252 = i128_to_felt252(numerator_abs); + let felt252_numerator: felt252 = numerator_abs.into(); let u128_numerator = felt252_numerator.try_into().expect('felt252 into u128 failed'); let result: u128 = mul_div_roundup(value, u128_numerator, denominator, roundup_magnitude); - let felt252_result: felt252 = u128_to_felt252(result); + let felt252_result: felt252 = result.into(); let i128_result: i128 = felt252_result.try_into().expect('felt252 into i128 failed'); if numerator > 0 { - return i128_result; + i128_result } else { - return -i128_result; + -i128_result } } @@ -131,13 +126,10 @@ fn mul_div_inum_roundup( fn mul_div_roundup( value: u128, numerator: u128, denominator: u128, roundup_magnitude: bool ) -> u128 { - let value = u256 { low: value, high: 0 }; - let numerator = u256 { low: numerator, high: 0 }; - let denominator = u256 { low: denominator, high: 0 }; - let product = u256_wide_mul(value, numerator); - let (q, r) = u512_safe_div_rem_by_u256( - product, u256_try_as_non_zero(denominator).expect('MulDivByZero') - ); + let product = u256_wide_mul(value.into(), numerator.into()); + let denominator: u256 = denominator.into(); + let non_zero_denominator = denominator.try_into().expect('MulDivByZero'); + let (q, r) = u512_safe_div_rem_by_u256(product, non_zero_denominator); if roundup_magnitude && r > 0 { let result = u256 { low: q.limb0, high: q.limb1 }; assert( @@ -182,9 +174,10 @@ fn to_factor_roundup(value: u128, divisor: u128, roundup_magnitude: bool) -> u12 } if (roundup_magnitude) { - return mul_div_roundup(value, FLOAT_PRECISION, divisor, roundup_magnitude); + mul_div_roundup(value, FLOAT_PRECISION, divisor, roundup_magnitude) + } else { + mul_div(value, FLOAT_PRECISION, divisor) } - return mul_div(value, FLOAT_PRECISION, divisor); } /// Compute factor from value and divisor. @@ -194,7 +187,7 @@ fn to_factor_roundup(value: u128, divisor: u128, roundup_magnitude: bool) -> u12 /// # Returns /// The factor between value and divisor. fn to_factor(value: u128, divisor: u128) -> u128 { - return to_factor_roundup(value, divisor, false); + to_factor_roundup(value, divisor, false) } /// Compute factor from integer value and divisor. @@ -227,7 +220,7 @@ fn to_factor_ival(value: i128, divisor: u128) -> i128 { /// # Returns /// The wei value. fn float_to_wei(value: u128) -> u128 { - return value / FLOAT_TO_WEI_DIVISOR; + value / FLOAT_TO_WEI_DIVISOR } /// Converts the given value from wei to float. @@ -236,7 +229,7 @@ fn float_to_wei(value: u128) -> u128 { /// # Returns /// The float value. fn wei_to_float(value: u128) -> u128 { - return value * FLOAT_TO_WEI_DIVISOR; + value * FLOAT_TO_WEI_DIVISOR } /// Converts the given value basis point to float. @@ -245,5 +238,5 @@ fn wei_to_float(value: u128) -> u128 { /// # Returns /// The float value. fn basis_points_to_float(basis_point: u128) -> u128 { - return basis_point * FLOAT_PRECISION / BASIS_POINTS_DIVISOR; + basis_point * FLOAT_PRECISION / BASIS_POINTS_DIVISOR } diff --git a/tests/pricing/test_swap_pricing_utils.cairo b/tests/pricing/test_swap_pricing_utils.cairo index fab17010..1d643c6a 100644 --- a/tests/pricing/test_swap_pricing_utils.cairo +++ b/tests/pricing/test_swap_pricing_utils.cairo @@ -1,15 +1,18 @@ +use debug::PrintTrait; use satoru::data::data_store::IDataStoreDispatcherTrait; use satoru::data::keys; use satoru::pricing::swap_pricing_utils::{ GetPriceImpactUsdParams, get_price_impact_usd_, get_price_impact_usd, get_next_pool_amount_usd, - get_swap_fees + get_swap_fees, PoolParams }; use satoru::market::market::Market; use satoru::utils::calc; use satoru::tests_lib::{setup, teardown}; +use satoru::utils::precision; +use satoru::utils::precision::{FLOAT_PRECISION}; #[test] -fn given_normal_conditions_when_swap_pricing_utils_functions_then_works() { +fn given_normal_conditions_when_get_price_impact_usd_then_works() { // ********************************************************************************************* // * SETUP * // ********************************************************************************************* @@ -48,6 +51,46 @@ fn given_normal_conditions_when_swap_pricing_utils_functions_then_works() { teardown(data_store.contract_address); } +#[test] +fn given_normal_conditions_when_get_price_impact_usd_inner_then_works() { + // ********************************************************************************************* + // * SETUP * + // ********************************************************************************************* + let (_, _, data_store) = setup(); + + let market_token = 'market_token'.try_into().unwrap(); + let index_token = 'index_token'.try_into().unwrap(); + let long_token = 'long_token'.try_into().unwrap(); + let short_token = 'short_token'.try_into().unwrap(); + + data_store.set_u128(keys::pool_amount_key(market_token, long_token), 1000); + data_store.set_u128(keys::pool_amount_key(market_token, short_token), 1000); + + // ********************************************************************************************* + // * TEST LOGIC * + // ********************************************************************************************* + + let market = Market { market_token, index_token, long_token, short_token }; + + let params = PoolParams { + pool_usd_for_token_a: 1000, + pool_usd_for_token_b: 1000, + next_pool_usd_for_token_a: 1001, + next_pool_usd_for_token_b: 999, + }; + + let impact = get_price_impact_usd_(data_store, market, params); + 'impact'.print(); + calc::to_signed(impact, true).print(); + + assert(impact == 0, 'foo'); + + // ********************************************************************************************* + // * TEARDOWN * + // ********************************************************************************************* + teardown(data_store.contract_address); +} + #[test] fn given_normal_conditions_when_get_next_pool_amount_usd_then_works() { // ********************************************************************************************* @@ -113,16 +156,16 @@ fn given_normal_conditions_when_get_swap_fees_then_works() { // * TEST LOGIC * // ********************************************************************************************* - let amount = 1000; + let amount = 1000 * FLOAT_PRECISION; let fees = get_swap_fees( data_store, market_token, amount, for_positive_impact, ui_fee_receiver ); - assert(fees.fee_receiver_amount == 0, 'invalid'); - assert(fees.fee_amount_for_pool == 0, 'invalid'); - assert(fees.amount_after_fees == 0x03e8, 'invalid'); - assert(fees.ui_fee_receiver_factor == 9, 'invalid'); - assert(fees.ui_fee_amount == 0, 'invalid'); + assert(fees.fee_receiver_amount == 0, 'invalid 1'); + assert(fees.fee_amount_for_pool == 5000, 'invalid 2'); + assert(fees.amount_after_fees == 1000 * FLOAT_PRECISION - 14000, 'invalid 3'); + assert(fees.ui_fee_receiver_factor == 9, 'invalid 4'); + assert(fees.ui_fee_amount == 9000, 'invalid 5'); // ********************************************************************************************* // * TEARDOWN * From a579fdc5b42026af8f257a8cec6d75fdd1290563 Mon Sep 17 00:00:00 2001 From: delaaxe <1091900+delaaxe@users.noreply.github.com> Date: Thu, 19 Oct 2023 20:26:23 +0300 Subject: [PATCH 2/3] Cleanup --- src/pricing/swap_pricing_utils.cairo | 2 -- tests/pricing/test_swap_pricing_utils.cairo | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/pricing/swap_pricing_utils.cairo b/src/pricing/swap_pricing_utils.cairo index 2d20db89..99f9206e 100644 --- a/src/pricing/swap_pricing_utils.cairo +++ b/src/pricing/swap_pricing_utils.cairo @@ -319,5 +319,3 @@ fn get_swap_fees( ui_fee_amount, } } - -use debug::PrintTrait; \ No newline at end of file diff --git a/tests/pricing/test_swap_pricing_utils.cairo b/tests/pricing/test_swap_pricing_utils.cairo index 12f963e6..3a896211 100644 --- a/tests/pricing/test_swap_pricing_utils.cairo +++ b/tests/pricing/test_swap_pricing_utils.cairo @@ -1,4 +1,3 @@ -use debug::PrintTrait; use satoru::data::data_store::IDataStoreDispatcherTrait; use satoru::data::keys; use satoru::pricing::swap_pricing_utils::{ @@ -81,10 +80,7 @@ fn given_normal_conditions_when_get_price_impact_usd_inner_then_works() { }; let impact = get_price_impact_usd_(data_store, market, params); - 'impact'.print(); - calc::to_signed(impact, true).print(); - - assert(impact == 0, 'foo'); + assert(impact == Zeroable::zero(), 'fail'); // ********************************************************************************************* // * TEARDOWN * From 91a774277ea7d8a5bf08baa248b2d2d740b5424e Mon Sep 17 00:00:00 2001 From: delaaxe <1091900+delaaxe@users.noreply.github.com> Date: Fri, 20 Oct 2023 01:35:26 +0300 Subject: [PATCH 3/3] Update precision.cairo --- src/utils/precision.cairo | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/utils/precision.cairo b/src/utils/precision.cairo index 3c37dfa2..05fee656 100644 --- a/src/utils/precision.cairo +++ b/src/utils/precision.cairo @@ -4,8 +4,7 @@ // Core lib imports. use alexandria_math::pow; use integer::{ - i128_to_felt252, u128_to_felt252, u256_wide_mul, u512_safe_div_rem_by_u256, BoundedU256, - U256TryIntoNonZero + u256_wide_mul, u512_safe_div_rem_by_u256, BoundedU256, U256TryIntoNonZero, U128IntoFelt252 }; use satoru::utils::i128::i128; use satoru::utils::calc::{roundup_division, roundup_magnitude_division}; @@ -206,7 +205,7 @@ fn to_factor_ival(value: i128, divisor: u128) -> i128 { let felt252_value: felt252 = value_abs.into(); let u128_value = felt252_value.try_into().expect('felt252 into u128 failed'); let result: u128 = to_factor(u128_value, divisor); - let felt252_result: felt252 = u128_to_felt252(result); + let felt252_result: felt252 = result.into(); let i128_result: i128 = felt252_result.try_into().expect('felt252 into i128 failed'); if value > Zeroable::zero() { i128_result