Skip to content

Commit

Permalink
stable pool - fixes the math
Browse files Browse the repository at this point in the history
  • Loading branch information
gangov committed Jan 8, 2025
1 parent 4c5a1c8 commit e97b5fc
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 25 deletions.
11 changes: 4 additions & 7 deletions contracts/pool_stable/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ pub(crate) fn compute_current_amp(env: &Env, amp_params: &AmplifierParameters) -
/// A * sum(x_i) * n**n + D = A * D * n**n + D**(n+1) / (n**n * prod(x_i))
pub fn compute_d(env: &Env, amp: u128, pools: &[u128]) -> U256 {
let leverage = U256::from_u128(env, (amp / AMP_PRECISION as u128) * N_COINS_PRECISION);
let amount_a_times_coins = pools[0] * N_COINS;
let amount_b_times_coins = pools[1] * N_COINS;

let amount_a_times_coins = U256::from_u128(env, pools[0]).mul(&U256::from_u128(env, N_COINS));
let amount_b_times_coins = U256::from_u128(env, pools[1]).mul(&U256::from_u128(env, N_COINS));
let sum_x = U256::from_u128(env, pools[0] + pools[1]); // sum(x_i), a.k.a S
let zero = U256::from_u128(env, 0u128);
if sum_x == zero {
Expand All @@ -88,10 +87,8 @@ pub fn compute_d(env: &Env, amp: u128, pools: &[u128]) -> U256 {

// Newton's method to approximate D
for _ in 0..ITERATIONS {
let d_product = d.pow(3).div(&U256::from_u128(
env,
amount_a_times_coins * amount_b_times_coins,
));
let a_times_b_product = amount_a_times_coins.mul(&amount_b_times_coins);
let d_product = d.pow(3).div(&a_times_b_product);
d_previous = d.clone();
d = calculate_step(env, &d, &leverage, &sum_x, &d_product);
// Equality with the precision of 1e-6
Expand Down
44 changes: 26 additions & 18 deletions contracts/pool_stable/src/tests/liquidity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ fn provide_liqudity() {

let mut token1 = deploy_token_contract(&env, &admin);
let mut token2 = deploy_token_contract(&env, &admin);

if token2.address < token1.address {
std::mem::swap(&mut token1, &mut token2);
}
Expand All @@ -45,14 +46,21 @@ fn provide_liqudity() {
let share_token_address = pool.query_share_token_address();
let token_share = token_contract::Client::new(&env, &share_token_address);

token1.mint(&user1, &1000);
assert_eq!(token1.balance(&user1), 1000);
token1.mint(&user1, &100000000000);
assert_eq!(token1.balance(&user1), 100000000000);

token2.mint(&user1, &1000);
assert_eq!(token2.balance(&user1), 1000);
token2.mint(&user1, &100000000000);
assert_eq!(token2.balance(&user1), 100000000000);

// tokens 1 & 2 have 7 decimal digits, meaning those values are 0.0001 of token
pool.provide_liquidity(&user1, &1000, &1000, &None, &None::<u64>, &None::<u128>);
pool.provide_liquidity(
&user1,
&2000000000,
&2000000000,
&None,
&None::<u64>,
&None::<u128>,
);

assert_eq!(
env.auths(),
Expand All @@ -64,8 +72,8 @@ fn provide_liqudity() {
Symbol::new(&env, "provide_liquidity"),
(
&user1,
1000i128,
1000i128,
2000000000i128,
2000000000i128,
None::<i64>,
None::<u64>,
None::<u128>
Expand All @@ -77,15 +85,15 @@ fn provide_liqudity() {
function: AuthorizedFunction::Contract((
token1.address.clone(),
symbol_short!("transfer"),
(&user1, &pool.address, 1000_i128).into_val(&env)
(&user1, &pool.address, 2000000000_i128).into_val(&env)
)),
sub_invocations: std::vec![],
},
AuthorizedInvocation {
function: AuthorizedFunction::Contract((
token2.address.clone(),
symbol_short!("transfer"),
(&user1, &pool.address, 1000_i128).into_val(&env)
(&user1, &pool.address, 2000000000_i128).into_val(&env)
)),
sub_invocations: std::vec![],
},
Expand All @@ -94,34 +102,34 @@ fn provide_liqudity() {
),]
);

assert_eq!(token_share.balance(&user1), 1000);
assert_eq!(token_share.balance(&user1), 3999999000);
assert_eq!(token_share.balance(&pool.address), 0);
assert_eq!(token1.balance(&user1), 0);
assert_eq!(token1.balance(&pool.address), 1000);
assert_eq!(token2.balance(&user1), 0);
assert_eq!(token2.balance(&pool.address), 1000);
assert_eq!(token1.balance(&user1), 98000000000);
assert_eq!(token1.balance(&pool.address), 2000000000);
assert_eq!(token2.balance(&user1), 98000000000);
assert_eq!(token2.balance(&pool.address), 2000000000);

let result = pool.query_pool_info();
assert_eq!(
result,
PoolResponse {
asset_a: Asset {
address: token1.address,
amount: 1000i128
amount: 2000000000i128
},
asset_b: Asset {
address: token2.address,
amount: 1000i128
amount: 2000000000i128
},
asset_lp_share: Asset {
address: share_token_address,
amount: 1000i128
amount: 3999999000i128
},
stake_address: pool.query_stake_contract_address(),
}
);

assert_eq!(pool.query_total_issued_lp(), 1000);
assert_eq!(pool.query_total_issued_lp(), 3999999000);
}

#[test]
Expand Down

0 comments on commit e97b5fc

Please sign in to comment.