Skip to content

Commit

Permalink
feat(pool-manager): allow updating config
Browse files Browse the repository at this point in the history
  • Loading branch information
kaimen-sano committed Apr 14, 2024
1 parent 62a82ed commit 7d29f3c
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 91 deletions.
20 changes: 15 additions & 5 deletions contracts/liquidity_hub/pool-manager/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,7 @@ pub fn execute(
to,
pair_identifier,
} => {
let to_addr = if let Some(to_addr) = to {
Some(deps.api.addr_validate(&to_addr)?)
} else {
None
};
let to_addr = to.map(|addr| deps.api.addr_validate(&addr)).transpose()?;

swap::commands::swap(
deps,
Expand Down Expand Up @@ -152,6 +148,19 @@ pub fn execute(
// )
// }
ExecuteMsg::AddSwapRoutes { swap_routes: _ } => Ok(Response::new()),
ExecuteMsg::UpdateConfig {
whale_lair_addr,
owner_addr,
pool_creation_fee,
feature_toggle,
} => manager::update_config(
deps,
info,
owner_addr,
whale_lair_addr,
pool_creation_fee,
feature_toggle,
),
}
}

Expand All @@ -174,6 +183,7 @@ fn optional_addr_validate(
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<Binary, ContractError> {
match msg {
QueryMsg::Config {} => Ok(to_json_binary(&queries::query_config(deps)?)?),
QueryMsg::NativeTokenDecimals { denom } => Ok(to_json_binary(
&queries::query_native_token_decimal(deps, denom)?,
)?),
Expand Down
3 changes: 3 additions & 0 deletions contracts/liquidity_hub/pool-manager/src/manager/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
pub mod commands;

mod update_config;
pub use update_config::update_config;
42 changes: 42 additions & 0 deletions contracts/liquidity_hub/pool-manager/src/manager/update_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use cosmwasm_std::{Coin, DepsMut, MessageInfo, Response};
use white_whale_std::pool_network::pair::FeatureToggle;

use crate::{state::MANAGER_CONFIG, ContractError};

pub fn update_config(
deps: DepsMut,
info: MessageInfo,
owner_addr: Option<String>,
whale_lair_addr: Option<String>,
pool_creation_fee: Option<Coin>,
feature_toggle: Option<FeatureToggle>,
) -> Result<Response, ContractError> {
MANAGER_CONFIG.update(deps.storage, |mut config| {
// permission check
if info.sender != config.owner {
return Err(ContractError::Unauthorized {});
}

if let Some(owner) = owner_addr {
let owner_addr = deps.api.addr_validate(&owner)?;
config.owner = owner_addr;
}

if let Some(whale_lair_addr) = whale_lair_addr {
let whale_lair_addr = deps.api.addr_validate(&whale_lair_addr)?;
config.whale_lair_addr = whale_lair_addr;
}

if let Some(pool_creation_fee) = pool_creation_fee {
config.pool_creation_fee = pool_creation_fee;
}

if let Some(feature_toggle) = feature_toggle {
config.feature_toggle = feature_toggle;
}

Ok(config)
})?;

Ok(Response::new().add_attribute("action", "update_config"))
}
9 changes: 7 additions & 2 deletions contracts/liquidity_hub/pool-manager/src/queries.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
use std::cmp::Ordering;

use cosmwasm_std::{Coin, Decimal256, Deps, Env, Fraction, Order, StdResult, Uint128};
use white_whale_std::pool_manager::{SwapOperation, SwapRouteResponse};
use white_whale_std::pool_manager::{Config, SwapOperation, SwapRouteResponse};
use white_whale_std::pool_network::{
asset::PairType,
factory::NativeTokenDecimalsResponse,
pair::{ReverseSimulationResponse, SimulationResponse},
// router::SimulateSwapOperationsResponse,
};

use crate::state::NATIVE_TOKEN_DECIMALS;
use crate::state::{MANAGER_CONFIG, NATIVE_TOKEN_DECIMALS};
use crate::{
helpers::{self, calculate_stableswap_y, StableSwapDirection},
state::get_pair_by_identifier,
ContractError,
};
use crate::{math::Decimal256Helper, state::SWAP_ROUTES};

/// Query the config of the contract.
pub fn query_config(deps: Deps) -> Result<Config, ContractError> {
Ok(MANAGER_CONFIG.load(deps.storage)?)
}

/// Query the native token decimals
pub fn query_native_token_decimal(
deps: Deps,
Expand Down
15 changes: 2 additions & 13 deletions contracts/liquidity_hub/pool-manager/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Coin, Deps};
use cosmwasm_std::Deps;
use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, UniqueIndex};
use white_whale_std::pool_manager::{PairInfo, SwapOperation};
use white_whale_std::pool_network::pair::FeatureToggle;

use crate::ContractError;

Expand Down Expand Up @@ -40,15 +38,6 @@ pub const NATIVE_TOKEN_DECIMALS: Map<&[u8], u8> = Map::new("allow_native_token")
// Swap routes are used to establish defined routes for a given fee token to a desired fee token and is used for fee collection
pub const SWAP_ROUTES: Map<(&str, &str), Vec<SwapOperation>> = Map::new("swap_routes");

pub use white_whale_std::pool_manager::Config;
pub const MANAGER_CONFIG: Item<Config> = Item::new("manager_config");
pub const PAIR_COUNTER: Item<u64> = Item::new("vault_count");

#[cw_serde]
pub struct Config {
pub whale_lair_addr: Addr,
pub owner: Addr,
// We must set a creation fee on instantiation to prevent spamming of pools
pub pool_creation_fee: Coin,
// Whether or not swaps, deposits, and withdrawals are enabled
pub feature_toggle: FeatureToggle,
}
191 changes: 129 additions & 62 deletions contracts/liquidity_hub/pool-manager/src/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,68 +16,6 @@ fn instantiate_normal() {
suite.instantiate(suite.senders[0].to_string());
}

#[test]
fn verify_ownership() {
let mut suite = TestingSuite::default_with_balances(vec![]);
let creator = suite.creator();
let other = suite.senders[1].clone();
let unauthorized = suite.senders[2].clone();

suite
.instantiate_default()
.query_ownership(|result| {
let ownership = result.unwrap();
assert_eq!(Addr::unchecked(ownership.owner.unwrap()), creator);
})
.update_ownership(
unauthorized,
cw_ownable::Action::TransferOwnership {
new_owner: other.to_string(),
expiry: None,
},
|result| {
let err = result.unwrap_err().downcast::<ContractError>().unwrap();

match err {
ContractError::OwnershipError { .. } => {}
_ => panic!("Wrong error type, should return ContractError::OwnershipError"),
}
},
)
.update_ownership(
creator,
cw_ownable::Action::TransferOwnership {
new_owner: other.to_string(),
expiry: None,
},
|result| {
result.unwrap();
},
)
.update_ownership(
other.clone(),
cw_ownable::Action::AcceptOwnership,
|result| {
result.unwrap();
},
)
.query_ownership(|result| {
let ownership = result.unwrap();
assert_eq!(Addr::unchecked(ownership.owner.unwrap()), other);
})
.update_ownership(
other.clone(),
cw_ownable::Action::RenounceOwnership,
|result| {
result.unwrap();
},
)
.query_ownership(|result| {
let ownership = result.unwrap();
assert!(ownership.owner.is_none());
});
}

// add features `token_factory` so tests are compiled using the correct flag
#[test]
fn deposit_and_withdraw_sanity_check() {
Expand Down Expand Up @@ -1832,3 +1770,132 @@ mod swapping {
);
}
}

mod ownership {
use white_whale_std::pool_network::pair::FeatureToggle;

use super::*;

#[test]
fn verify_ownership() {
let mut suite = TestingSuite::default_with_balances(vec![]);
let creator = suite.creator();
let other = suite.senders[1].clone();
let unauthorized = suite.senders[2].clone();

suite
.instantiate_default()
.query_ownership(|result| {
let ownership = result.unwrap();
assert_eq!(Addr::unchecked(ownership.owner.unwrap()), creator);
})
.update_ownership(
unauthorized,
cw_ownable::Action::TransferOwnership {
new_owner: other.to_string(),
expiry: None,
},
|result| {
let err = result.unwrap_err().downcast::<ContractError>().unwrap();

match err {
ContractError::OwnershipError { .. } => {}
_ => {
panic!("Wrong error type, should return ContractError::OwnershipError")
}
}
},
)
.update_ownership(
creator,
cw_ownable::Action::TransferOwnership {
new_owner: other.to_string(),
expiry: None,
},
|result| {
result.unwrap();
},
)
.update_ownership(
other.clone(),
cw_ownable::Action::AcceptOwnership,
|result| {
result.unwrap();
},
)
.query_ownership(|result| {
let ownership = result.unwrap();
assert_eq!(Addr::unchecked(ownership.owner.unwrap()), other);
})
.update_ownership(
other.clone(),
cw_ownable::Action::RenounceOwnership,
|result| {
result.unwrap();
},
)
.query_ownership(|result| {
let ownership = result.unwrap();
assert!(ownership.owner.is_none());
});
}

#[test]
fn checks_ownership_when_updating_config() {
let mut suite = TestingSuite::default_with_balances(vec![]);
let unauthorized = suite.senders[2].clone();

suite.instantiate_default().update_config(
unauthorized.clone(),
None,
None,
None,
None,
|res| {
assert_eq!(
res.unwrap_err().downcast_ref::<ContractError>(),
Some(&ContractError::Unauthorized {})
)
},
);
}

#[test]
fn updates_config_fields() {
let mut suite = TestingSuite::default_with_balances(vec![]);
let creator = suite.creator();
let other = suite.senders[1].clone();

suite.instantiate_default();
let current_pool_creation_fee = suite.query_config().pool_creation_fee;
let initial_config = suite.query_config();

suite.update_config(
creator,
Some(other.clone()),
Some(other),
Some(coin(
current_pool_creation_fee
.amount
.checked_add(Uint128::from(1u32))
.unwrap()
.u128(),
current_pool_creation_fee.denom,
)),
Some(FeatureToggle {
deposits_enabled: false,
swaps_enabled: false,
withdrawals_enabled: false,
}),
|res| {
res.unwrap();
},
);

let config = suite.query_config();
assert_ne!(config.owner, initial_config.owner);
assert_ne!(config.whale_lair_addr, initial_config.whale_lair_addr);
assert_ne!(config.pool_creation_fee, initial_config.pool_creation_fee);
assert_ne!(config.feature_toggle, initial_config.feature_toggle);
}
}
Loading

0 comments on commit 7d29f3c

Please sign in to comment.