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

fix get_coin_amount and add test #343

Merged
merged 2 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 23 additions & 18 deletions onchain/cairo/launchpad/src/launchpad/calcul/linear.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -25,23 +26,25 @@ 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;
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);
let res = fast_sqrt(reduced_i_cast, SQRT_ITER.try_into().unwrap());
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;
Expand All @@ -52,23 +55,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 / DECIMAL_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 / 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 = term1 + term2 + term3;
let amount_out = term0 - term1 + term2;
amount_out
}

Expand Down
55 changes: 54 additions & 1 deletion onchain/cairo/launchpad/src/tests/linear_tests.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ mod linear_tests {
token_launch
}


#[test]
fn test_get_meme_amount_on_curve_with_different_supplies() {

Expand Down Expand Up @@ -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(
Expand Down
Loading