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

Pool Stable: adds a new check if the tokens that are added to the stable pool are with up to 18 decimals #369

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to
- Stake rewards: Create a new contract and prepare first testcases ([#306])
- Trader: Adds a check if the contract has been already initialized ([#329])
- All: Adds more test that verify the authorization during execution ([#363])
- Pool Stable: adds a new check if the tokens that are added to the stable pool are with up to 18 decimals ([#369])

## Fixed

Expand All @@ -39,6 +40,7 @@ and this project adheres to
[#363]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/363
[#365]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/365
[#366]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/366
[#369]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/369

## [1.0.0] - 2024-05-08

Expand Down
5 changes: 3 additions & 2 deletions contracts/pool_stable/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Dex Stable Pool

## Main functionality
This contract is being used for managing stable coins within the Phoenix DEX. It offers liquidity provision, trading assets and pool management functionalities.
This contract is being used for managing stable coins (with up to 18 decimals of precision) within the Phoenix DEX. It offers liquidity provision, trading assets and pool management functionalities.

## Messages:
`initialize`
Expand All @@ -20,7 +20,8 @@ Return type:
void

Description:
Used for the initialization of the stable liquidity pool contract - this sets the admin in Config, initializes both token contracts, that will be in the pool and also initializes the staking contract needed for providing liquidity.
Used for the initialization of the stable liquidity pool contract - this sets the admin in Config, initializes both token contracts, that will be in the pool and also initializes the staking contract needed for providing liquidity.
N.B.: The stable pool supports tokens with up to 18 decimals

<hr>

Expand Down
16 changes: 14 additions & 2 deletions contracts/pool_stable/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use phoenix::utils::{convert_i128_to_u128, convert_u128_to_i128, LiquidityPoolInitInfo};
use soroban_sdk::{
contract, contractimpl, contractmeta, log, panic_with_error, Address, BytesN, Env, IntoVal,
String,
contract, contractimpl, contractmeta, log, panic_with_error, token, Address, BytesN, Env,
IntoVal, String,
};

use crate::{
Expand Down Expand Up @@ -189,6 +189,14 @@ impl StableLiquidityPoolTrait for StableLiquidityPool {

set_initialized(&env);

let token_a_decimals = token::Client::new(&env, &token_init_info.token_a).decimals();
let token_b_decimals = token::Client::new(&env, &token_init_info.token_b).decimals();

if token_a_decimals > 18 || token_b_decimals > 18 {
log!(env, "Stable Pool: Initialize: trying to initialize a stable pool with token with more than 18 decimals.");
panic_with_error!(&env, ContractError::InvalidNumberOfTokenDecimals);
}

// Token info
let token_a = token_init_info.token_a;
let token_b = token_init_info.token_b;
Expand Down Expand Up @@ -979,6 +987,7 @@ pub fn compute_swap(

let greatest_precision = get_greatest_precision(env);

// soroban_sdk::testutils::arbitrary::std::dbg!("DBG");
let new_ask_pool = calc_y(
env,
amp as u128,
Expand All @@ -994,6 +1003,8 @@ pub fn compute_swap(
greatest_precision,
);

// soroban_sdk::testutils::arbitrary::std::dbg!("SWAP", ask_pool, new_ask_pool);

let return_amount = ask_pool - new_ask_pool;
// We consider swap rate 1:1 in stable swap thus any difference is considered as spread.
let spread_amount = if offer_amount > return_amount {
Expand Down Expand Up @@ -1048,6 +1059,7 @@ pub fn compute_offer_amount(
],
greatest_precision,
);
// soroban_sdk::testutils::arbitrary::std::dbg!("REVERSE SWAP", new_offer_pool, offer_pool);

let offer_amount = new_offer_pool - offer_pool;

Expand Down
1 change: 1 addition & 0 deletions contracts/pool_stable/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ pub enum ContractError {
IssuedSharesLessThanUserRequested = 21,
SwapFeeBpsOverLimit = 22,
UserDeclinesPoolFee = 23,
InvalidNumberOfTokenDecimals = 24,
}
95 changes: 95 additions & 0 deletions contracts/pool_stable/src/tests/swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use soroban_sdk::{symbol_short, testutils::Address as _, Address, Env, IntoVal};

use super::setup::{deploy_stable_liquidity_pool_contract, deploy_token_contract};
use crate::storage::{Asset, PoolResponse, SimulateReverseSwapResponse, SimulateSwapResponse};
use crate::token_contract;
use soroban_decimal::Decimal;

#[test]
Expand Down Expand Up @@ -557,3 +558,97 @@ fn simple_swap_with_low_user_fee_should_panic() {
&Some(50), // user wants to swap for %.5
);
}

#[test]
fn simple_swap_with_two_tokens_both_with_7_decimals() {
let env = Env::default();
env.mock_all_auths();
env.budget().reset_unlimited();

let admin = Address::generate(&env);
let manager = Address::generate(&env);
let factory = Address::generate(&env);
let user = Address::generate(&env);

let mut token1 = token_contract::Client::new(
&env,
&env.register_contract_wasm(None, token_contract::WASM),
);

token1.initialize(
&admin,
&7,
&"name1".into_val(&env),
&"symbol1".into_val(&env),
);

let mut token2 = token_contract::Client::new(
&env,
&env.register_contract_wasm(None, token_contract::WASM),
);

token2.initialize(
&admin,
&7,
&"name2".into_val(&env),
&"symbol2".into_val(&env),
);

if token2.address < token1.address {
std::mem::swap(&mut token1, &mut token2);
}

let swap_fees = 0i64;
let pool = deploy_stable_liquidity_pool_contract(
&env,
None,
(&token1.address, &token2.address),
swap_fees,
None,
None,
None,
manager,
factory,
None,
);

token1.mint(&user, &1_100);
token2.mint(&user, &1_100);
pool.provide_liquidity(&user, &1_000, &1_000, &None, &None::<u64>, &None);

let spread = 100i64; // 1% maximum spread allowed
pool.simulate_reverse_swap(&token1.address, &1);
pool.swap(
&user,
&token1.address,
&1,
&None,
&Some(spread),
&None::<u64>,
&None,
);
//
// let share_token_address = pool.query_share_token_address();
// let result = pool.query_pool_info();
//
// assert_eq!(
// result,
// PoolResponse {
// asset_a: Asset {
// address: token1.address.clone(),
// amount: 1_001i128,
// },
// asset_b: Asset {
// address: token2.address.clone(),
// amount: 999i128,
// },
// asset_lp_share: Asset {
// address: share_token_address.clone(),
// amount: 1_000i128,
// },
// stake_address: pool.query_stake_contract_address(),
// }
// );
// assert_eq!(token1.balance(&user), 99);
// assert_eq!(token2.balance(&user), 101);
}
Loading