From 848f344ba0f1b0f133cf23ab87d4ac35d2e93de2 Mon Sep 17 00:00:00 2001 From: Supanat Potiwarakorn Date: Fri, 14 Jun 2024 13:10:58 +0700 Subject: [PATCH] prevent alloyed asset subdenom to contain extra parts (/) --- contracts/transmuter/src/contract.rs | 42 +++++++++++++++++++ contracts/transmuter/src/error.rs | 3 ++ .../src/test/cases/units/join_and_exit.rs | 10 ++--- .../src/test/cases/units/spot_price.rs | 8 ++-- .../src/test/cases/units/swap/mod.rs | 2 +- 5 files changed, 55 insertions(+), 10 deletions(-) diff --git a/contracts/transmuter/src/contract.rs b/contracts/transmuter/src/contract.rs index 302732a..344df49 100644 --- a/contracts/transmuter/src/contract.rs +++ b/contracts/transmuter/src/contract.rs @@ -112,6 +112,14 @@ impl Transmuter<'_> { // set active status to true self.active_status.save(deps.storage, &true)?; + // subdenom must not contain extra parts + ensure!( + !alloyed_asset_subdenom.contains('/'), + ContractError::SubDenomExtraPartsNotAllowed { + subdenom: alloyed_asset_subdenom + } + ); + // create alloyed denom let msg_create_alloyed_denom = SubMsg::reply_on_success( MsgCreateDenom { @@ -894,6 +902,40 @@ mod tests { }; use osmosis_std::types::osmosis::tokenfactory::v1beta1::MsgBurn; + #[test] + fn test_invalid_subdenom() { + let mut deps = mock_dependencies(); + + // make denom has non-zero total supply + deps.querier + .update_balance("someone", vec![Coin::new(1, "tbtc"), Coin::new(1, "nbtc")]); + + let admin = "admin"; + let moderator = "moderator"; + let init_msg = InstantiateMsg { + pool_asset_configs: vec![ + AssetConfig::from_denom_str("tbtc"), + AssetConfig::from_denom_str("nbtc"), + ], + alloyed_asset_subdenom: "all/btc".to_string(), + alloyed_asset_normalization_factor: Uint128::one(), + admin: Some(admin.to_string()), + moderator: moderator.to_string(), + }; + let env = mock_env(); + let info = mock_info(admin, &[]); + + // Instantiate the contract. + let err = instantiate(deps.as_mut(), env.clone(), info.clone(), init_msg).unwrap_err(); + + assert_eq!( + err, + ContractError::SubDenomExtraPartsNotAllowed { + subdenom: "all/btc".to_string() + } + ) + } + #[test] fn test_add_new_assets() { let mut deps = mock_dependencies(); diff --git a/contracts/transmuter/src/error.rs b/contracts/transmuter/src/error.rs index ae9c847..82d5c2b 100644 --- a/contracts/transmuter/src/error.rs +++ b/contracts/transmuter/src/error.rs @@ -26,6 +26,9 @@ pub enum ContractError { #[error("Denom has no supply, it might be an invalid denom: {denom}")] DenomHasNoSupply { denom: String }, + #[error("Subdenom must not contain extra parts (separated by '/'): {subdenom}")] + SubDenomExtraPartsNotAllowed { subdenom: String }, + #[error("Unable to join pool with denom: {denom}: expected one of: {expected_denom:?}")] InvalidJoinPoolDenom { denom: String, diff --git a/contracts/transmuter/src/test/cases/units/join_and_exit.rs b/contracts/transmuter/src/test/cases/units/join_and_exit.rs index d2ede97..1994f7e 100644 --- a/contracts/transmuter/src/test/cases/units/join_and_exit.rs +++ b/contracts/transmuter/src/test/cases/units/join_and_exit.rs @@ -94,7 +94,7 @@ fn test_join_pool_with_single_lp_should_update_shares_and_liquidity_properly() { AssetConfig::from_denom_str("denoma"), AssetConfig::from_denom_str("denomb"), ], - alloyed_asset_subdenom: "transmuter/poolshare".to_string(), + alloyed_asset_subdenom: "all".to_string(), alloyed_asset_normalization_factor: Uint128::one(), admin: None, moderator: "osmo1cyyzpxplxdzkeea7kwsydadg87357qnahakaks".to_string(), @@ -237,7 +237,7 @@ fn test_join_pool_should_update_shares_and_liquidity_properly() { AssetConfig::from_denom_str("denoma"), AssetConfig::from_denom_str("denomb"), ], - alloyed_asset_subdenom: "transmuter/poolshare".to_string(), + alloyed_asset_subdenom: "all".to_string(), alloyed_asset_normalization_factor: Uint128::one(), admin: None, moderator: "osmo1cyyzpxplxdzkeea7kwsydadg87357qnahakaks".to_string(), @@ -360,7 +360,7 @@ fn test_exit_pool_less_than_their_shares_should_update_shares_and_liquidity_prop AssetConfig::from_denom_str("denoma"), AssetConfig::from_denom_str("denomb"), ], - alloyed_asset_subdenom: "transmuter/poolshare".to_string(), + alloyed_asset_subdenom: "all".to_string(), alloyed_asset_normalization_factor: Uint128::one(), admin: None, moderator: "osmo1cyyzpxplxdzkeea7kwsydadg87357qnahakaks".to_string(), @@ -560,7 +560,7 @@ fn test_exit_pool_greater_than_their_shares_should_fail() { AssetConfig::from_denom_str("denoma"), AssetConfig::from_denom_str("denomb"), ], - alloyed_asset_subdenom: "transmuter/poolshare".to_string(), + alloyed_asset_subdenom: "all".to_string(), alloyed_asset_normalization_factor: Uint128::one(), admin: None, moderator: "osmo1cyyzpxplxdzkeea7kwsydadg87357qnahakaks".to_string(), @@ -612,7 +612,7 @@ fn test_exit_pool_within_shares_but_over_joined_denom_amount() { AssetConfig::from_denom_str("denoma"), AssetConfig::from_denom_str("denomb"), ], - alloyed_asset_subdenom: "transmuter/poolshare".to_string(), + alloyed_asset_subdenom: "all".to_string(), alloyed_asset_normalization_factor: Uint128::one(), admin: None, moderator: "osmo1cyyzpxplxdzkeea7kwsydadg87357qnahakaks".to_string(), diff --git a/contracts/transmuter/src/test/cases/units/spot_price.rs b/contracts/transmuter/src/test/cases/units/spot_price.rs index c020253..439c1e2 100644 --- a/contracts/transmuter/src/test/cases/units/spot_price.rs +++ b/contracts/transmuter/src/test/cases/units/spot_price.rs @@ -39,7 +39,7 @@ fn test_spot_price(liquidity: &[Coin]) { AssetConfig::from_denom_str("denom0"), AssetConfig::from_denom_str("denom1"), ], - "transmuter/poolshare".to_string(), + "all".to_string(), Uint128::one(), None, "osmo1cyyzpxplxdzkeea7kwsydadg87357qnahakaks".to_string(), @@ -50,7 +50,7 @@ fn test_spot_price(liquidity: &[Coin]) { .alloyed_asset .set_alloyed_denom( &mut deps.storage, - &"factory/contract_address/transmuter/poolshare".to_string(), + &"factory/contract_address/all".to_string(), ) .unwrap(); @@ -90,7 +90,7 @@ fn test_spot_price(liquidity: &[Coin]) { ) .unwrap_err(), ContractError::SpotPriceQueryFailed { - reason: "base_asset_denom is not in swappable assets: must be one of [\"denom0\", \"denom1\", \"factory/contract_address/transmuter/poolshare\"] but got random_denom".to_string() + reason: "base_asset_denom is not in swappable assets: must be one of [\"denom0\", \"denom1\", \"factory/contract_address/all\"] but got random_denom".to_string() } ); @@ -106,7 +106,7 @@ fn test_spot_price(liquidity: &[Coin]) { ) .unwrap_err(), ContractError::SpotPriceQueryFailed { - reason: "quote_asset_denom is not in swappable assets: must be one of [\"denom0\", \"denom1\", \"factory/contract_address/transmuter/poolshare\"] but got random_denom".to_string() + reason: "quote_asset_denom is not in swappable assets: must be one of [\"denom0\", \"denom1\", \"factory/contract_address/all\"] but got random_denom".to_string() } ); diff --git a/contracts/transmuter/src/test/cases/units/swap/mod.rs b/contracts/transmuter/src/test/cases/units/swap/mod.rs index 9c20839..ed93f62 100644 --- a/contracts/transmuter/src/test/cases/units/swap/mod.rs +++ b/contracts/transmuter/src/test/cases/units/swap/mod.rs @@ -508,7 +508,7 @@ fn pool_with_single_lp( .unwrap_or_else(|| AssetConfig::from_denom_str(c.denom.as_str())) }) .collect(), - alloyed_asset_subdenom: "transmuter/poolshare".to_string(), + alloyed_asset_subdenom: "all".to_string(), alloyed_asset_normalization_factor: Uint128::one(), admin: None, moderator: "osmo1cyyzpxplxdzkeea7kwsydadg87357qnahakaks".to_string(),