From 8a4fc2a6a21a04e7e89a7198ba496b81f35a37a1 Mon Sep 17 00:00:00 2001 From: lemunozm Date: Mon, 15 Jul 2024 13:31:42 +0200 Subject: [PATCH] allow and disallow currency tests --- pallets/liquidity-pools/src/lib.rs | 8 +- pallets/liquidity-pools/src/tests.rs | 290 +++++++++++++ .../src/cases/liquidity_pools.rs | 390 ------------------ 3 files changed, 294 insertions(+), 394 deletions(-) diff --git a/pallets/liquidity-pools/src/lib.rs b/pallets/liquidity-pools/src/lib.rs index 7d78d97629..f9de3217c8 100644 --- a/pallets/liquidity-pools/src/lib.rs +++ b/pallets/liquidity-pools/src/lib.rs @@ -923,6 +923,10 @@ pub mod pallet { pub fn validate_investment_currency( currency_id: T::CurrencyId, ) -> Result<(u128, EVMChainId), DispatchError> { + let currency = Self::try_get_general_index(currency_id)?; + + let (chain_id, ..) = Self::try_get_wrapped_token(¤cy_id)?; + // Ensure the currency is enabled as pool_currency let metadata = T::AssetRegistry::metadata(¤cy_id).ok_or(Error::::AssetNotFound)?; @@ -931,10 +935,6 @@ pub mod pallet { Error::::AssetMetadataNotPoolCurrency ); - let currency = Self::try_get_general_index(currency_id)?; - - let (chain_id, ..) = Self::try_get_wrapped_token(¤cy_id)?; - Ok((currency, chain_id)) } diff --git a/pallets/liquidity-pools/src/tests.rs b/pallets/liquidity-pools/src/tests.rs index 2b3d462649..76fe5619e6 100644 --- a/pallets/liquidity-pools/src/tests.rs +++ b/pallets/liquidity-pools/src/tests.rs @@ -80,6 +80,16 @@ mod util { } } + pub fn pool_locatable_transferable_metadata() -> AssetMetadata { + AssetMetadata { + additional: CustomMetadata { + pool_currency: true, + ..transferable_metadata().additional + }, + ..locatable_transferable_metadata() + } + } + pub fn currency_index(currency_id: CurrencyId) -> u128 { GeneralCurrencyIndexOf::::try_from(currency_id) .unwrap() @@ -958,6 +968,286 @@ mod add_currency { } } +mod allow_investment_currency { + use super::*; + + #[test] + fn success() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| Some(util::pool_locatable_transferable_metadata())); + Permissions::mock_has(move |scope, who, role| { + assert_eq!(who, ALICE); + assert!(matches!(scope, PermissionScope::Pool(POOL_ID))); + assert!(matches!(role, Role::PoolRole(PoolRole::PoolAdmin))); + true + }); + Gateway::mock_submit(|sender, destination, msg| { + assert_eq!(sender, ALICE); + assert_eq!(destination, EVM_DOMAIN_ADDRESS.domain()); + assert_eq!( + msg, + Message::AllowInvestmentCurrency { + pool_id: POOL_ID, + currency: util::currency_index(CURRENCY_ID), + } + ); + Ok(()) + }); + + assert_ok!(LiquidityPools::allow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + )); + }) + } + + mod erroring_out { + use super::*; + + #[test] + fn with_wrong_permissions() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| false); + + assert_noop!( + LiquidityPools::allow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::NotPoolAdmin + ); + }) + } + + #[test] + fn with_no_metadata() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| None); + + assert_noop!( + LiquidityPools::allow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::AssetNotFound, + ); + }) + } + + #[test] + fn with_unsupported_token() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| Some(util::default_metadata())); + + assert_noop!( + LiquidityPools::allow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CurrencyId::Native + ), + TokenError::Unsupported, + ); + }) + } + + #[test] + fn with_no_transferible_asset() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| Some(util::default_metadata())); + + assert_noop!( + LiquidityPools::allow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::AssetNotLiquidityPoolsTransferable, + ); + }) + } + + #[test] + fn with_wrong_location() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| Some(util::transferable_metadata())); + + assert_noop!( + LiquidityPools::allow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::AssetNotLiquidityPoolsWrappedToken + ); + }) + } + + #[test] + fn with_wrong_pool_currency() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| Some(util::locatable_transferable_metadata())); + + assert_noop!( + LiquidityPools::allow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::AssetMetadataNotPoolCurrency + ); + }) + } + } +} + +mod disallow_investment_currency { + use super::*; + + #[test] + fn success() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| Some(util::pool_locatable_transferable_metadata())); + Permissions::mock_has(move |scope, who, role| { + assert_eq!(who, ALICE); + assert!(matches!(scope, PermissionScope::Pool(POOL_ID))); + assert!(matches!(role, Role::PoolRole(PoolRole::PoolAdmin))); + true + }); + Gateway::mock_submit(|sender, destination, msg| { + assert_eq!(sender, ALICE); + assert_eq!(destination, EVM_DOMAIN_ADDRESS.domain()); + assert_eq!( + msg, + Message::DisallowInvestmentCurrency { + pool_id: POOL_ID, + currency: util::currency_index(CURRENCY_ID), + } + ); + Ok(()) + }); + + assert_ok!(LiquidityPools::disallow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + )); + }) + } + + mod erroring_out { + use super::*; + + #[test] + fn with_wrong_permissions() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| false); + + assert_noop!( + LiquidityPools::disallow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::NotPoolAdmin + ); + }) + } + + #[test] + fn with_no_metadata() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| None); + + assert_noop!( + LiquidityPools::disallow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::AssetNotFound, + ); + }) + } + + #[test] + fn with_unsupported_token() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| Some(util::default_metadata())); + + assert_noop!( + LiquidityPools::disallow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CurrencyId::Native + ), + TokenError::Unsupported, + ); + }) + } + + #[test] + fn with_no_transferible_asset() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| Some(util::default_metadata())); + + assert_noop!( + LiquidityPools::disallow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::AssetNotLiquidityPoolsTransferable, + ); + }) + } + + #[test] + fn with_wrong_location() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| Some(util::transferable_metadata())); + + assert_noop!( + LiquidityPools::disallow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::AssetNotLiquidityPoolsWrappedToken + ); + }) + } + + #[test] + fn with_wrong_pool_currency() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + AssetRegistry::mock_metadata(|_| Some(util::locatable_transferable_metadata())); + + assert_noop!( + LiquidityPools::disallow_investment_currency( + RuntimeOrigin::signed(ALICE), + POOL_ID, + CURRENCY_ID + ), + Error::::AssetMetadataNotPoolCurrency + ); + }) + } + } +} + #[test] fn receiving_invalid_message() { System::externalities().execute_with(|| { diff --git a/runtime/integration-tests/src/cases/liquidity_pools.rs b/runtime/integration-tests/src/cases/liquidity_pools.rs index 43ca11a567..12158f4bda 100644 --- a/runtime/integration-tests/src/cases/liquidity_pools.rs +++ b/runtime/integration-tests/src/cases/liquidity_pools.rs @@ -665,396 +665,6 @@ use utils::*; mod add_allow_upgrade { use super::*; - #[test_runtimes([development])] - fn allow_investment_currency() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::tokens::(vec![( - GLMR_CURRENCY_ID, - DEFAULT_BALANCE_GLMR, - )])) - .storage(), - ); - - setup_test(&mut env); - - env.parachain_state_mut(|| { - let currency_id = AUSD_CURRENCY_ID; - let pool_id = POOL_ID; - let evm_chain_id: u64 = MOONBEAM_EVM_CHAIN_ID; - let evm_address = [1u8; 20]; - - // Create an AUSD pool - create_ausd_pool::(pool_id); - - enable_liquidity_pool_transferability::(currency_id); - - // Enable LiquidityPools transferability - assert_ok!(orml_asset_registry::Pallet::::update_asset( - ::RuntimeOrigin::root(), - currency_id, - None, - None, - None, - None, - // Changed: Add location which can be converted to LiquidityPoolsWrappedToken - Some(Some(liquidity_pools_transferable_multilocation::( - evm_chain_id, - evm_address, - ))), - Some(CustomMetadata { - // Changed: Allow liquidity_pools transferability - transferability: CrossChainTransferability::LiquidityPools, - pool_currency: true, - ..Default::default() - }) - )); - - assert_ok!( - pallet_liquidity_pools::Pallet::::allow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ) - ); - - assert_noop!( - pallet_liquidity_pools::Pallet::::allow_investment_currency( - RawOrigin::Signed(Keyring::Charlie.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::NotPoolAdmin - ); - }); - } - - #[test_runtimes([development])] - fn allow_investment_currency_should_fail() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::tokens::(vec![( - GLMR_CURRENCY_ID, - DEFAULT_BALANCE_GLMR, - )])) - .storage(), - ); - - setup_test(&mut env); - - env.parachain_state_mut(|| { - let pool_id = POOL_ID; - let currency_id = CurrencyId::ForeignAsset(42); - let ausd_currency_id = AUSD_CURRENCY_ID; - - // Should fail if pool does not exist - assert_noop!( - pallet_liquidity_pools::Pallet::::allow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::NotPoolAdmin - ); - - // Register currency_id with pool_currency set to true - assert_ok!(orml_asset_registry::Pallet::::register_asset( - ::RuntimeOrigin::root(), - AssetMetadata { - name: BoundedVec::default(), - symbol: BoundedVec::default(), - decimals: 12, - location: None, - existential_deposit: 1_000_000, - additional: CustomMetadata { - pool_currency: true, - ..Default::default() - }, - }, - Some(currency_id) - )); - - // Create pool - create_currency_pool::(pool_id, currency_id, 10_000 * decimals(12)); - - enable_liquidity_pool_transferability::(ausd_currency_id); - - // Should fail if currency is not liquidityPools transferable - assert_ok!(orml_asset_registry::Pallet::::update_asset( - ::RuntimeOrigin::root(), - currency_id, - None, - None, - None, - None, - None, - Some(CustomMetadata { - // Disallow any cross chain transferability - transferability: CrossChainTransferability::None, - // Changed: Allow to be usable as pool currency - pool_currency: true, - ..Default::default() - }), - )); - assert_noop!( - pallet_liquidity_pools::Pallet::::allow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::AssetNotLiquidityPoolsTransferable - ); - - // Should fail if currency does not have any Location in metadata - assert_ok!(orml_asset_registry::Pallet::::update_asset( - ::RuntimeOrigin::root(), - currency_id, - None, - None, - None, - None, - None, - Some(CustomMetadata { - // Changed: Allow liquidityPools transferability - transferability: CrossChainTransferability::LiquidityPools, - // Still allow to be pool currency - pool_currency: true, - ..Default::default() - }), - )); - assert_noop!( - pallet_liquidity_pools::Pallet::::allow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::AssetNotLiquidityPoolsWrappedToken - ); - - // Should fail if currency does not have LiquidityPoolsWrappedToken location in - // metadata - assert_ok!(orml_asset_registry::Pallet::::update_asset( - ::RuntimeOrigin::root(), - currency_id, - None, - None, - None, - None, - // Changed: Add some location which cannot be converted to - // LiquidityPoolsWrappedToken - Some(Some(VersionedLocation::V4(Default::default()))), - // No change for transferability required as it is already allowed for - // LiquidityPools - None, - )); - assert_noop!( - pallet_liquidity_pools::Pallet::::allow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::AssetNotLiquidityPoolsWrappedToken - ); - }); - } - - #[test_runtimes([development])] - fn disallow_investment_currency() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::tokens::(vec![( - GLMR_CURRENCY_ID, - DEFAULT_BALANCE_GLMR, - )])) - .storage(), - ); - - setup_test(&mut env); - - env.parachain_state_mut(|| { - let currency_id = AUSD_CURRENCY_ID; - let pool_id = POOL_ID; - let evm_chain_id: u64 = MOONBEAM_EVM_CHAIN_ID; - let evm_address = [1u8; 20]; - - // Create an AUSD pool - create_ausd_pool::(pool_id); - - enable_liquidity_pool_transferability::(currency_id); - - // Enable LiquidityPools transferability - assert_ok!(orml_asset_registry::Pallet::::update_asset( - ::RuntimeOrigin::root(), - currency_id, - None, - None, - None, - None, - // Changed: Add location which can be converted to LiquidityPoolsWrappedToken - Some(Some(liquidity_pools_transferable_multilocation::( - evm_chain_id, - evm_address, - ))), - Some(CustomMetadata { - // Changed: Allow liquidity_pools transferability - transferability: CrossChainTransferability::LiquidityPools, - pool_currency: true, - ..Default::default() - }) - )); - - assert_ok!( - pallet_liquidity_pools::Pallet::::disallow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ) - ); - - assert_noop!( - pallet_liquidity_pools::Pallet::::disallow_investment_currency( - RawOrigin::Signed(Keyring::Charlie.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::NotPoolAdmin - ); - }); - } - - #[test_runtimes([development])] - fn disallow_investment_currency_should_fail() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::tokens::(vec![( - GLMR_CURRENCY_ID, - DEFAULT_BALANCE_GLMR, - )])) - .storage(), - ); - - setup_test(&mut env); - - env.parachain_state_mut(|| { - let pool_id = POOL_ID; - let currency_id = CurrencyId::ForeignAsset(42); - let ausd_currency_id = AUSD_CURRENCY_ID; - - // Should fail if pool does not exist - assert_noop!( - pallet_liquidity_pools::Pallet::::disallow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::NotPoolAdmin - ); - - // Register currency_id with pool_currency set to true - assert_ok!(orml_asset_registry::Pallet::::register_asset( - ::RuntimeOrigin::root(), - AssetMetadata { - name: BoundedVec::default(), - symbol: BoundedVec::default(), - decimals: 12, - location: None, - existential_deposit: 1_000_000, - additional: CustomMetadata { - pool_currency: true, - ..Default::default() - }, - }, - Some(currency_id) - )); - - // Create pool - create_currency_pool::(pool_id, currency_id, 10_000 * decimals(12)); - - enable_liquidity_pool_transferability::(ausd_currency_id); - - // Should fail if currency is not liquidityPools transferable - assert_ok!(orml_asset_registry::Pallet::::update_asset( - ::RuntimeOrigin::root(), - currency_id, - None, - None, - None, - None, - None, - Some(CustomMetadata { - // Disallow any cross chain transferability - transferability: CrossChainTransferability::None, - // Changed: Allow to be usable as pool currency - pool_currency: true, - ..Default::default() - }), - )); - assert_noop!( - pallet_liquidity_pools::Pallet::::disallow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::AssetNotLiquidityPoolsTransferable - ); - - // Should fail if currency does not have any Location in metadata - assert_ok!(orml_asset_registry::Pallet::::update_asset( - ::RuntimeOrigin::root(), - currency_id, - None, - None, - None, - None, - None, - Some(CustomMetadata { - // Changed: Allow liquidityPools transferability - transferability: CrossChainTransferability::LiquidityPools, - // Still allow to be pool currency - pool_currency: true, - ..Default::default() - }), - )); - assert_noop!( - pallet_liquidity_pools::Pallet::::disallow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::AssetNotLiquidityPoolsWrappedToken - ); - - // Should fail if currency does not have LiquidityPoolsWrappedToken location in - // metadata - assert_ok!(orml_asset_registry::Pallet::::update_asset( - ::RuntimeOrigin::root(), - currency_id, - None, - None, - None, - None, - // Changed: Add some location which cannot be converted to - // LiquidityPoolsWrappedToken - Some(Some(VersionedLocation::V4(Default::default()))), - // No change for transferability required as it is already allowed for - // LiquidityPools - None, - )); - assert_noop!( - pallet_liquidity_pools::Pallet::::disallow_investment_currency( - RawOrigin::Signed(Keyring::Bob.into()).into(), - pool_id, - currency_id, - ), - pallet_liquidity_pools::Error::::AssetNotLiquidityPoolsWrappedToken - ); - }); - } - #[test_runtimes([development])] fn schedule_upgrade() { let mut env = FudgeEnv::::from_parachain_storage(