From 00bd2f3118d9f07f406eb890965d4c911f73486e Mon Sep 17 00:00:00 2001 From: genjieth Date: Tue, 10 Dec 2024 04:16:54 +0000 Subject: [PATCH 1/2] fix get_coin_amount and add test --- .../src/launchpad/calcul/linear.cairo | 30 +++++----- .../launchpad/src/tests/linear_tests.cairo | 55 ++++++++++++++++++- 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/onchain/cairo/launchpad/src/launchpad/calcul/linear.cairo b/onchain/cairo/launchpad/src/launchpad/calcul/linear.cairo index 72e34621..a4b42e4f 100644 --- a/onchain/cairo/launchpad/src/launchpad/calcul/linear.cairo +++ b/onchain/cairo/launchpad/src/launchpad/calcul/linear.cairo @@ -25,6 +25,8 @@ pub fn get_meme_amount(pool_coin: TokenLaunch, amount_in: u256) -> u256 { let threshold_liquidity = pool_coin.threshold_liquidity.clone(); assert!(sellable_supply > 0, "Sellable supply == 0"); + assert!(amount_in > 0, "Amount in == 0"); + assert!(amount_in <= threshold_liquidity, "Amount in > threshold liquidity"); let scaled_threshold_liquidity = threshold_liquidity * SCALE_FACTOR; let sellable_supply_squared = sellable_supply * sellable_supply / SCALE_FACTOR; @@ -52,23 +54,25 @@ pub fn get_coin_amount(pool_coin: TokenLaunch, amount_in: u256) -> u256 { let total_supply = pool_coin.total_supply.clone(); let current_supply = pool_coin.available_supply.clone(); let sellable_supply = total_supply.clone() - (total_supply.clone() / LIQUIDITY_RATIO); - let threshold_liquidity = pool_coin.threshold_liquidity.clone(); let amount_sold = sellable_supply.clone() - current_supply.clone(); - assert(sellable_supply.clone() > 0, 'Sellable supply == 0 '); - let slope = (threshold_liquidity * SCALE_FACTOR) / (sellable_supply * sellable_supply); - let intercept = (threshold_liquidity * SCALE_FACTOR) / (2 * sellable_supply); - // let amount_out = slope * amount_sold * amount_in - // + slope / 2 * amount_in * amount_in - // + intercept * amount_in; - // amount_out + assert!(sellable_supply > 0, "Sellable supply == 0"); + assert!(amount_in > 0, "Amount in == 0"); + assert!(amount_in <= amount_sold, "Amount to sell > amount sold"); + + let threshold_liquidity = pool_coin.threshold_liquidity.clone(); + assert!(sellable_supply > 0, "Sellable supply == 0"); + + let scaled_threshold_liquidity = threshold_liquidity * SCALE_FACTOR; + let sellable_supply_squared = sellable_supply * sellable_supply / SCALE_FACTOR; + let scaled_slope = scaled_threshold_liquidity / sellable_supply_squared; + let scaled_intercept = scaled_threshold_liquidity / (2 * sellable_supply); - // Calculate amount out - let term1 = (slope * amount_sold * amount_in) / SCALE_FACTOR; - let term2 = (slope / 2 * amount_in * amount_in) / SCALE_FACTOR; - let term3 = (intercept * amount_in) / SCALE_FACTOR; + let term0 = scaled_slope * amount_sold / SCALE_FACTOR * amount_in / SCALE_FACTOR; + let term1 = scaled_slope / 2 * amount_in / SCALE_FACTOR * amount_in / SCALE_FACTOR; + let term2 = scaled_intercept * amount_in / SCALE_FACTOR; - let amount_out = term1 + term2 + term3; + let amount_out = term0 - term1 + term2; amount_out } diff --git a/onchain/cairo/launchpad/src/tests/linear_tests.cairo b/onchain/cairo/launchpad/src/tests/linear_tests.cairo index 969adfb3..981cb9c1 100644 --- a/onchain/cairo/launchpad/src/tests/linear_tests.cairo +++ b/onchain/cairo/launchpad/src/tests/linear_tests.cairo @@ -68,7 +68,6 @@ mod linear_tests { token_launch } - #[test] fn test_get_meme_amount_on_curve_with_different_supplies() { @@ -738,6 +737,60 @@ mod linear_tests { ); } + #[test] + fn test_get_coin_amount_on_curve() { + + let mut available_supply = 60_000_000_000_000_000_000_000_000_u256; + let mut token_launch = get_token_launch( + DEFAULT_SUPPLY_2, THRESHOLD_LIQUIDITY_1, available_supply, + ); + let mut amount_in = 20_000_000_000_000_000_000_000_000_u256; + let mut amount_out = get_coin_amount(token_launch, amount_in); + assert!( + amount_out == 1_562_500_000_000_000_000_u256, "Amount_out should be 1.5625 coins" + ); + + available_supply = 40_000_000_000_000_000_000_000_000_u256; + token_launch = get_token_launch( + DEFAULT_SUPPLY_2, THRESHOLD_LIQUIDITY_1, available_supply, + ); + amount_in = 20_000_000_000_000_000_000_000_000_u256; + amount_out = get_coin_amount(token_launch, amount_in); + assert!( + amount_out == 2_187_500_000_000_000_000_u256, "Amount_out should be 2.1875 coins" + ); + + available_supply = 20_000_000_000_000_000_000_000_000_u256; + token_launch = get_token_launch( + DEFAULT_SUPPLY_2, THRESHOLD_LIQUIDITY_1, available_supply, + ); + amount_in = 20_000_000_000_000_000_000_000_000_u256; + amount_out = get_coin_amount(token_launch, amount_in); + assert!( + amount_out == 2_812_500_000_000_000_000_u256, "Amount_out should be 2.8125 coins" + ); + + available_supply = 0_u256; + token_launch = get_token_launch( + DEFAULT_SUPPLY_2, THRESHOLD_LIQUIDITY_1, available_supply, + ); + amount_in = 20_000_000_000_000_000_000_000_000_u256; + amount_out = get_coin_amount(token_launch, amount_in); + assert!( + amount_out == 3_437_500_000_000_000_000_u256, "Amount_out should be 3.4375 coins" + ); + + available_supply = 0_u256; + token_launch = get_token_launch( + DEFAULT_SUPPLY_2, THRESHOLD_LIQUIDITY_1, available_supply, + ); + amount_in = 80_000_000_000_000_000_000_000_000_u256; + amount_out = get_coin_amount(token_launch, amount_in); + assert!( + amount_out == 10_000_000_000_000_000_000_u256, "Amount_out should be 10.0000 coins" + ); + } + // #[test] // fn test_get_meme_amount_with_for_threshold() { // let mut token_launch = get_token_launch( From fd872b95231f65cffe3ebfdedd4b3b372314ec67 Mon Sep 17 00:00:00 2001 From: genjieth Date: Tue, 10 Dec 2024 05:03:59 +0000 Subject: [PATCH 2/2] improve scaling factor in calcul/linear --- .../launchpad/src/launchpad/calcul/linear.cairo | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/onchain/cairo/launchpad/src/launchpad/calcul/linear.cairo b/onchain/cairo/launchpad/src/launchpad/calcul/linear.cairo index a4b42e4f..90d66a6c 100644 --- a/onchain/cairo/launchpad/src/launchpad/calcul/linear.cairo +++ b/onchain/cairo/launchpad/src/launchpad/calcul/linear.cairo @@ -13,6 +13,7 @@ const BPS: u256 = 10_000; const SCALE_FACTOR: u256 = 1_000_000_000_000_000_000_000_000_000_000_u256; const SCALE_ROOT_FACTOR: u256 = 1_000_000_000_000_000_u256; +const DECIMAL_FACTOR: u256 = 1_000_000_000_000_000_000_u256; const MIN_PRICE: u256 = 1_u256; const LIQUIDITY_RATIO: u256 = 5; const SQRT_ITER: u256 = 1_000_u256; @@ -29,13 +30,13 @@ pub fn get_meme_amount(pool_coin: TokenLaunch, amount_in: u256) -> u256 { assert!(amount_in <= threshold_liquidity, "Amount in > threshold liquidity"); let scaled_threshold_liquidity = threshold_liquidity * SCALE_FACTOR; - let sellable_supply_squared = sellable_supply * sellable_supply / SCALE_FACTOR; + let sellable_supply_squared = sellable_supply * sellable_supply / DECIMAL_FACTOR; let scaled_slope = scaled_threshold_liquidity / sellable_supply_squared; let scaled_intercept = scaled_threshold_liquidity / (2 * sellable_supply); - let term0 = scaled_slope * amount_sold / SCALE_FACTOR + scaled_intercept; - let term1 = (scaled_slope * amount_sold / SCALE_FACTOR + scaled_intercept) * (scaled_slope * amount_sold / SCALE_FACTOR + scaled_intercept) / SCALE_FACTOR; - let term2 = 2 * scaled_slope * amount_in / SCALE_FACTOR; + let term0 = scaled_slope * amount_sold / DECIMAL_FACTOR + scaled_intercept; + let term1 = (scaled_slope * amount_sold / DECIMAL_FACTOR + scaled_intercept) * (scaled_slope * amount_sold / DECIMAL_FACTOR + scaled_intercept) / SCALE_FACTOR; + let term2 = 2 * scaled_slope * amount_in / DECIMAL_FACTOR; let i_cast = term1 + term2; let (reduced_i_cast, exp) = dynamic_reduce_u256_to_u128(i_cast); @@ -43,7 +44,7 @@ pub fn get_meme_amount(pool_coin: TokenLaunch, amount_in: u256) -> u256 { let i = dynamic_scale_u128_to_u256(res, exp) * SCALE_ROOT_FACTOR; let numerator = i - term0; - let scaled_numerator = numerator * SCALE_FACTOR; + let scaled_numerator = numerator * DECIMAL_FACTOR; let calculated_amount_out = scaled_numerator / scaled_slope; let amount_out = calculated_amount_out; @@ -64,12 +65,12 @@ pub fn get_coin_amount(pool_coin: TokenLaunch, amount_in: u256) -> u256 { assert!(sellable_supply > 0, "Sellable supply == 0"); let scaled_threshold_liquidity = threshold_liquidity * SCALE_FACTOR; - let sellable_supply_squared = sellable_supply * sellable_supply / SCALE_FACTOR; + let sellable_supply_squared = sellable_supply * sellable_supply / DECIMAL_FACTOR; let scaled_slope = scaled_threshold_liquidity / sellable_supply_squared; let scaled_intercept = scaled_threshold_liquidity / (2 * sellable_supply); - let term0 = scaled_slope * amount_sold / SCALE_FACTOR * amount_in / SCALE_FACTOR; - let term1 = scaled_slope / 2 * amount_in / SCALE_FACTOR * amount_in / SCALE_FACTOR; + let term0 = scaled_slope * amount_sold / SCALE_FACTOR * amount_in / DECIMAL_FACTOR; + let term1 = scaled_slope / 2 * amount_in / SCALE_FACTOR * amount_in / DECIMAL_FACTOR; let term2 = scaled_intercept * amount_in / SCALE_FACTOR; let amount_out = term0 - term1 + term2;