Skip to content

Commit

Permalink
Merge branch 'main' into 217-v-phx-vul-017-user-can-accidentally-swap…
Browse files Browse the repository at this point in the history
…-the-wrong-asset
  • Loading branch information
ueco-jb authored Feb 22, 2024
2 parents 2e2288e + 235c17e commit 297aef6
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to
- Multihop: changes total_commission_amount type in SimulateSwap and SimulateReverseSwap ([#236])
- Multihop: removes unnecessary unwrap of a value ([#240])
- Factory, Multihop, Pool, Pool_stable, Phoenix: adds lp_token decimal's as a const instead a user input ([#241])
- Factory, Multihop, Pool, Pool_stable: adds a new parameter for creating liquidity pool ([#243])

[#200]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/200
[#234]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/234
Expand All @@ -26,12 +27,15 @@ and this project adheres to
[#236]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/236
[#240]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/240
[#241]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/241
[#243]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/243

## Added

- Adds a new macro that validates the bps arguments value ([#199])
- Added test coverage for Decimal ([#244])

[#199]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/199
[#244]: https://github.com/Phoenix-Protocol-Group/phoenix-contracts/pull/244

## Bug fixes

Expand Down
13 changes: 10 additions & 3 deletions contracts/factory/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use crate::{
use phoenix::utils::{LiquidityPoolInitInfo, StakeInitInfo, TokenInitInfo};
use phoenix::validate_bps;
use soroban_sdk::{
contract, contractimpl, contractmeta, log, Address, BytesN, Env, IntoVal, Symbol, Val, Vec,
contract, contractimpl, contractmeta, log, Address, BytesN, Env, IntoVal, String, Symbol, Val,
Vec,
};

// Metadata that is added on to the WASM custom section
Expand All @@ -34,8 +35,10 @@ pub trait FactoryTrait {

fn create_liquidity_pool(
env: Env,
lp_init_info: LiquidityPoolInitInfo,
caller: Address,
lp_init_info: LiquidityPoolInitInfo,
share_token_name: String,
share_token_symbol: String,
) -> Address;

fn update_whitelisted_accounts(
Expand Down Expand Up @@ -105,8 +108,10 @@ impl FactoryTrait for Factory {

fn create_liquidity_pool(
env: Env,
lp_init_info: LiquidityPoolInitInfo,
caller: Address,
lp_init_info: LiquidityPoolInitInfo,
share_token_name: String,
share_token_symbol: String,
) -> Address {
caller.require_auth();
if !get_config(&env).whitelisted_accounts.contains(caller) {
Expand Down Expand Up @@ -148,6 +153,8 @@ impl FactoryTrait for Factory {
lp_init_info.clone(),
factory_addr,
config.lp_token_decimals,
share_token_name,
share_token_symbol,
)
.into_val(&env);

Expand Down
16 changes: 13 additions & 3 deletions contracts/factory/src/tests/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use phoenix::utils::{LiquidityPoolInitInfo, StakeInitInfo, TokenInitInfo};

use soroban_sdk::{
testutils::{arbitrary::std, Address as _},
vec, Address, Env,
vec, Address, Env, String,
};

#[test]
Expand Down Expand Up @@ -73,7 +73,12 @@ fn factory_successfully_inits_lp() {
stake_init_info,
};

factory.create_liquidity_pool(&lp_init_info, &admin);
factory.create_liquidity_pool(
&admin,
&lp_init_info,
&String::from_str(&env, "Pool"),
&String::from_str(&env, "PHO/BTC"),
);
let lp_contract_addr = factory.query_pools().get(0).unwrap();

let first_lp_contract = lp_contract::Client::new(&env, &lp_contract_addr);
Expand Down Expand Up @@ -145,7 +150,12 @@ fn factory_fails_to_init_lp_when_authorized_address_not_present() {

let unauthorized_addr = Address::generate(&env);

factory.create_liquidity_pool(&lp_init_info, &unauthorized_addr);
factory.create_liquidity_pool(
&unauthorized_addr,
&lp_init_info,
&String::from_str(&env, "Pool"),
&String::from_str(&env, "PHO/BTC"),
);
}

#[test]
Expand Down
46 changes: 37 additions & 9 deletions contracts/factory/src/tests/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use phoenix::utils::{LiquidityPoolInitInfo, StakeInitInfo, TokenInitInfo};
use soroban_sdk::{
contracttype,
testutils::{arbitrary::std, Address as _},
Address, Env, Symbol, Vec,
Address, Env, String, Symbol, Vec,
};

#[contracttype]
Expand Down Expand Up @@ -125,10 +125,24 @@ fn test_deploy_multiple_liquidity_pools() {
stake_init_info: third_stake_init_info,
};

let lp_contract_addr = factory.create_liquidity_pool(&first_lp_init_info, &admin.clone());
let second_lp_contract_addr =
factory.create_liquidity_pool(&second_lp_init_info, &admin.clone());
let third_lp_contract_addr = factory.create_liquidity_pool(&third_lp_init_info, &admin.clone());
let lp_contract_addr = factory.create_liquidity_pool(
&admin.clone(),
&first_lp_init_info,
&String::from_str(&env, "Pool"),
&String::from_str(&env, "PHO/BTC"),
);
let second_lp_contract_addr = factory.create_liquidity_pool(
&admin.clone(),
&second_lp_init_info,
&String::from_str(&env, "Pool #2"),
&String::from_str(&env, "PHO/ETH"),
);
let third_lp_contract_addr = factory.create_liquidity_pool(
&admin.clone(),
&third_lp_init_info,
&String::from_str(&env, "Pool #3"),
&String::from_str(&env, "PHO/XLM"),
);

let first_result = factory.query_pool_details(&lp_contract_addr);
let share_token_addr: Address = env.invoke_contract(
Expand Down Expand Up @@ -308,10 +322,24 @@ fn test_queries_by_tuple() {
stake_init_info: third_stake_init_info,
};

let lp_contract_addr = factory.create_liquidity_pool(&first_lp_init_info, &admin.clone());
let second_lp_contract_addr =
factory.create_liquidity_pool(&second_lp_init_info, &admin.clone());
let third_lp_contract_addr = factory.create_liquidity_pool(&third_lp_init_info, &admin.clone());
let lp_contract_addr = factory.create_liquidity_pool(
&admin.clone(),
&first_lp_init_info,
&String::from_str(&env, "Pool"),
&String::from_str(&env, "PHO/BTC"),
);
let second_lp_contract_addr = factory.create_liquidity_pool(
&admin.clone(),
&second_lp_init_info,
&String::from_str(&env, "Pool #2"),
&String::from_str(&env, "PHO/ETH"),
);
let third_lp_contract_addr = factory.create_liquidity_pool(
&admin.clone(),
&third_lp_init_info,
&String::from_str(&env, "Pool #3"),
&String::from_str(&env, "PHO/XLM"),
);

let first_result = factory.query_pool_details(&lp_contract_addr);

Expand Down
1 change: 1 addition & 0 deletions contracts/multihop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod storage;

mod utils;

#[allow(clippy::too_many_arguments)]
pub mod lp_contract {
// The import will code generate:
// - A ContractClient type that can be used to invoke functions on the contract.
Expand Down
7 changes: 6 additions & 1 deletion contracts/multihop/src/tests/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,12 @@ pub fn deploy_and_initialize_lp(
stake_init_info,
};

let lp = factory.create_liquidity_pool(&lp_init_info, &admin.clone());
let lp = factory.create_liquidity_pool(
&admin.clone(),
&lp_init_info,
&String::from_str(env, "Pool"),
&String::from_str(env, "PHO/XLM"),
);

let lp_client = lp_contract::Client::new(env, &lp);
lp_client.provide_liquidity(
Expand Down
11 changes: 9 additions & 2 deletions contracts/pool/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use soroban_sdk::{
contract, contractimpl, contractmeta, log, panic_with_error, Address, BytesN, Env, IntoVal,
String,
};

use num_integer::Roots;
Expand Down Expand Up @@ -33,13 +34,16 @@ pub struct LiquidityPool;
pub trait LiquidityPoolTrait {
// Sets the token contract addresses for this pool
// token_wasm_hash is the WASM hash of the deployed token contract for the pool share token
#[allow(clippy::too_many_arguments)]
fn initialize(
env: Env,
stake_wasm_hash: BytesN<32>,
token_wasm_hash: BytesN<32>,
lp_init_info: LiquidityPoolInitInfo,
factory_addr: Address,
share_token_decimals: u32,
share_token_name: String,
share_token_symbol: String,
);

// Deposits token_a and token_b. Also mints pool shares for the "to" Identifier. The amount minted
Expand Down Expand Up @@ -126,13 +130,16 @@ pub trait LiquidityPoolTrait {

#[contractimpl]
impl LiquidityPoolTrait for LiquidityPool {
#[allow(clippy::too_many_arguments)]
fn initialize(
env: Env,
stake_wasm_hash: BytesN<32>,
token_wasm_hash: BytesN<32>,
lp_init_info: LiquidityPoolInitInfo,
factory_addr: Address,
share_token_decimals: u32,
share_token_name: String,
share_token_symbol: String,
) {
if is_initialized(&env) {
panic!("Liquidity Pool: Initialize: initializing contract twice is not allowed");
Expand Down Expand Up @@ -186,9 +193,9 @@ impl LiquidityPoolTrait for LiquidityPool {
// number of decimals on the share token
&share_token_decimals,
// name
&"Pool Share Token".into_val(&env),
&share_token_name.into_val(&env),
// symbol
&"POOL".into_val(&env),
&share_token_symbol.into_val(&env),
);

let stake_contract_address = utils::deploy_stake_contract(&env, stake_wasm_hash);
Expand Down
4 changes: 3 additions & 1 deletion contracts/pool/src/tests/setup.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use soroban_sdk::{testutils::Address as _, Address, BytesN, Env};
use soroban_sdk::{testutils::Address as _, Address, BytesN, Env, String};

use crate::{
contract::{LiquidityPool, LiquidityPoolClient},
Expand Down Expand Up @@ -72,6 +72,8 @@ pub fn deploy_liquidity_pool_contract<'a>(
&lp_init_info,
&stake_owner,
&10u32,
&String::from_str(env, "Pool"),
&String::from_str(env, "PHOBTC"),
);
pool
}
6 changes: 5 additions & 1 deletion contracts/pool/src/tests/stake_deployment.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
extern crate std;
use phoenix::utils::{LiquidityPoolInitInfo, StakeInitInfo, TokenInitInfo};
use soroban_sdk::{testutils::Address as _, Address, Env};
use soroban_sdk::{testutils::Address as _, Address, Env, String};

use super::setup::{deploy_liquidity_pool_contract, deploy_token_contract};
use crate::{
Expand Down Expand Up @@ -130,6 +130,8 @@ fn second_pool_deployment_should_fail() {
&lp_init_info,
&Address::generate(&env),
&10u32,
&String::from_str(&env, "Pool"),
&String::from_str(&env, "PHOBTC"),
);

pool.initialize(
Expand All @@ -138,5 +140,7 @@ fn second_pool_deployment_should_fail() {
&lp_init_info,
&Address::generate(&env),
&10u32,
&String::from_str(&env, "Pool"),
&String::from_str(&env, "PHOBTC"),
);
}
10 changes: 8 additions & 2 deletions contracts/pool_stable/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub struct StableLiquidityPool;
pub trait StableLiquidityPoolTrait {
// Sets the token contract addresses for this pool
// token_wasm_hash is the WASM hash of the deployed token contract for the pool share token
#[allow(clippy::too_many_arguments)]
fn initialize(
env: Env,
stake_wasm_hash: BytesN<32>,
Expand All @@ -42,6 +43,8 @@ pub trait StableLiquidityPoolTrait {
lp_init_info: LiquidityPoolInitInfo,
factory_addr: Address,
share_token_decimals: u32,
share_token_name: String,
share_token_symbol: String,
);

// Deposits token_a and token_b. Also mints pool shares for the "to" Identifier. The amount minted
Expand Down Expand Up @@ -123,6 +126,7 @@ pub trait StableLiquidityPoolTrait {

#[contractimpl]
impl StableLiquidityPoolTrait for StableLiquidityPool {
#[allow(clippy::too_many_arguments)]
fn initialize(
env: Env,
stake_wasm_hash: BytesN<32>,
Expand All @@ -131,6 +135,8 @@ impl StableLiquidityPoolTrait for StableLiquidityPool {
lp_init_info: LiquidityPoolInitInfo,
factory_addr: Address,
share_token_decimals: u32,
share_token_name: String,
share_token_symbol: String,
) {
if is_initialized(&env) {
panic!("Pool stable: Initialize: initializing contract twice is not allowed");
Expand Down Expand Up @@ -183,9 +189,9 @@ impl StableLiquidityPoolTrait for StableLiquidityPool {
// number of decimals on the share token
&share_token_decimals,
// name
&"Pool Share Token".into_val(&env),
&share_token_name.into_val(&env),
// symbol
&"POOL".into_val(&env),
&share_token_symbol.into_val(&env),
);

let stake_contract_address = utils::deploy_stake_contract(&env, stake_wasm_hash);
Expand Down
49 changes: 49 additions & 0 deletions packages/decimal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ impl fmt::Display for Decimal {
#[cfg(test)]
mod tests {
use super::*;
use alloc::format;

#[test]
fn decimal_new() {
Expand Down Expand Up @@ -861,4 +862,52 @@ mod tests {
fn decimal_pow_overflow_panics() {
_ = Decimal::MAX.pow(2u32);
}

#[test]
fn decimal_abs_with_negative_number() {
let decimal = Decimal::new(128);

assert_eq!(decimal.abs(), Decimal { 0: 128 });
}

#[test]
fn decimal_abs_with_positive_number() {
let decimal = Decimal::new(128);

assert_eq!(decimal.abs(), Decimal { 0: 128 });
}

#[test]
fn decimal_displayed_as_string() {
let env = Env::default();
let decimal = Decimal::percent(128);

assert_eq!(decimal.to_string(&env), String::from_slice(&env, "128"));
}

#[test]
fn decimal_fmt_without_fractional_part() {
let value = Decimal::from_atomics(100, 0);
assert_eq!(format!("{}", value), "100");
}

#[test]
fn decimal_fmt_fractional_part() {
let value = Decimal::from_atomics(123456789, 5);
assert_eq!(format!("{}", value), "1234.56789");
}

#[test]
fn decimal_fmt_fractional_part_with_trailing_zeros() {
// 12345.6
let value = Decimal::from_atomics(123456, 1);
assert_eq!(format!("{}", value), "12345.6");
}

#[test]
fn decimal_fmt_only_fractional() {
// 0.0789
let value = Decimal::from_atomics(789, 4);
assert_eq!(format!("{}", value), "0.0789");
}
}

0 comments on commit 297aef6

Please sign in to comment.