diff --git a/Cargo.lock b/Cargo.lock index 53eed1662..a4cbf797a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3937,7 +3937,7 @@ dependencies = [ [[package]] name = "hydradx-traits" -version = "2.7.0" +version = "3.0.0" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -6389,7 +6389,7 @@ dependencies = [ [[package]] name = "pallet-bonds" -version = "2.0.0" +version = "2.1.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -6600,7 +6600,7 @@ dependencies = [ [[package]] name = "pallet-dca" -version = "1.2.0" +version = "1.2.1" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-primitives-core", @@ -6940,7 +6940,7 @@ dependencies = [ [[package]] name = "pallet-liquidity-mining" -version = "4.2.4" +version = "4.3.0" dependencies = [ "fixed", "frame-support", @@ -7120,7 +7120,7 @@ dependencies = [ [[package]] name = "pallet-omnipool" -version = "3.2.3" +version = "3.3.0" dependencies = [ "bitflags", "frame-benchmarking", @@ -7147,9 +7147,8 @@ dependencies = [ [[package]] name = "pallet-omnipool-liquidity-mining" -version = "2.0.11" +version = "2.1.0" dependencies = [ - "bitflags", "frame-benchmarking", "frame-support", "frame-system", @@ -7176,7 +7175,7 @@ dependencies = [ [[package]] name = "pallet-otc" -version = "1.0.2" +version = "1.1.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -7389,7 +7388,7 @@ dependencies = [ [[package]] name = "pallet-stableswap" -version = "3.3.1" +version = "3.4.0" dependencies = [ "bitflags", "frame-benchmarking", @@ -7781,7 +7780,7 @@ dependencies = [ [[package]] name = "pallet-xyk" -version = "6.3.0" +version = "6.4.0" dependencies = [ "frame-benchmarking", "frame-support", diff --git a/integration-tests/src/bonds.rs b/integration-tests/src/bonds.rs index c3f4d2728..dfcd93a64 100644 --- a/integration-tests/src/bonds.rs +++ b/integration-tests/src/bonds.rs @@ -6,7 +6,7 @@ use crate::polkadot_test_net::*; use frame_support::storage::with_transaction; use frame_support::{assert_noop, assert_ok}; use frame_system::RawOrigin; -use hydradx_traits::CreateRegistry; +use hydradx_traits::registry::{AssetKind, Create}; use orml_traits::MultiCurrency; use sp_runtime::{DispatchResult, TransactionOutcome}; use xcm_emulator::TestExt; @@ -65,10 +65,15 @@ fn issue_bonds_should_work_when_issued_for_share_asset() { let maturity = NOW + MONTH; let name = b"SHARED".to_vec(); - let share_asset_id = AssetRegistry::create_asset( - &name, - pallet_asset_registry::AssetType::PoolShare(HDX, DOT).into(), - 1_000, + let share_asset_id = AssetRegistry::register_insufficient_asset( + None, + Some(&name), + AssetKind::XYK, + Some(1_000), + None, + None, + None, + None, ) .unwrap(); assert_ok!(Currencies::deposit(share_asset_id, &ALICE.into(), amount,)); @@ -119,9 +124,18 @@ fn issue_bonds_should_not_work_when_issued_for_bond_asset() { let maturity = NOW + MONTH; let name = b"BOND".to_vec(); - let underlying_asset_id = - AssetRegistry::create_asset(&name, pallet_asset_registry::AssetType::::Bond.into(), 1_000) - .unwrap(); + let underlying_asset_id = AssetRegistry::register_insufficient_asset( + None, + Some(&name), + AssetKind::Bond, + Some(1_000), + None, + None, + None, + None, + ) + .unwrap(); + assert_ok!(Currencies::deposit(underlying_asset_id, &ALICE.into(), amount,)); // Act & Assert diff --git a/integration-tests/src/dca.rs b/integration-tests/src/dca.rs index 6c288a2c2..7481e6501 100644 --- a/integration-tests/src/dca.rs +++ b/integration-tests/src/dca.rs @@ -11,11 +11,8 @@ use hydradx_runtime::{ AssetRegistry, Balances, Currencies, Omnipool, Router, Runtime, RuntimeEvent, RuntimeOrigin, Stableswap, Tokens, Treasury, DCA, }; +use hydradx_traits::registry::{AssetKind, Create}; use hydradx_traits::router::{PoolType, Trade}; -use hydradx_traits::{ - registry::{AssetKind, Create}, - Registry, -}; use orml_traits::MultiCurrency; use orml_traits::MultiReservableCurrency; use pallet_dca::types::{Order, Schedule}; @@ -2314,7 +2311,7 @@ pub fn init_stableswap() -> Result<(AssetId, AssetId, AssetId), DispatchError> { None, Some(name.as_ref()), AssetKind::Token, - Some(1u128), + 1u128, Some(b"xDUM".as_ref()), Some(18u8), None, @@ -2335,7 +2332,7 @@ pub fn init_stableswap() -> Result<(AssetId, AssetId, AssetId), DispatchError> { None, Some(b"pool".as_ref()), AssetKind::Token, - Some(1u128), + 1u128, None, None, None, @@ -2372,7 +2369,7 @@ pub fn init_stableswap_with_three_assets_having_different_decimals( None, Some(name.as_ref()), AssetKind::Token, - Some(1u128), + 1u128, Some(b"xDUM".as_ref()), Some(decimals_for_each_asset[idx as usize]), None, @@ -2395,7 +2392,16 @@ pub fn init_stableswap_with_three_assets_having_different_decimals( initial.push(AssetAmount::new(asset_id, initial_liquidity)); added_liquidity.push(AssetAmount::new(asset_id, liquidity_added)); } - let pool_id = AssetRegistry::create_asset(&b"pool".to_vec(), 1u128)?; + let pool_id = AssetRegistry::register_insufficient_asset( + None, + Some(&b"pool".to_vec()), + AssetKind::Token, + Some(1u128), + None, + None, + None, + None, + )?; let amplification = 100u16; let fee = Permill::from_percent(1); diff --git a/integration-tests/src/router.rs b/integration-tests/src/router.rs index 8231c8f3d..62cb21cbe 100644 --- a/integration-tests/src/router.rs +++ b/integration-tests/src/router.rs @@ -2314,7 +2314,7 @@ pub fn init_stableswap() -> Result<(AssetId, AssetId, AssetId), DispatchError> { None, Some(name.as_ref()), AssetKind::Token, - Some(1u128), + 1u128, Some(b"xDUM".as_ref()), Some(18u8), None, @@ -2342,7 +2342,7 @@ pub fn init_stableswap() -> Result<(AssetId, AssetId, AssetId), DispatchError> { None, Some(b"pool".as_ref()), AssetKind::Token, - Some(1u128), + 1u128, None, None, None, diff --git a/pallets/asset-registry/src/benchmarking.rs b/pallets/asset-registry/src/benchmarking.rs index 8f9f650e5..2ff460c26 100644 --- a/pallets/asset-registry/src/benchmarking.rs +++ b/pallets/asset-registry/src/benchmarking.rs @@ -64,7 +64,7 @@ benchmarks! { let _ = Pallet::::register(RawOrigin::Root.into(), Some(asset_id), Some(name), AssetType::Token, Some(ed), Some(symbol), Some(decimals), Some(location), Some(xcm_rate_limit), is_sufficient); let new_name= vec![98u8; T::StringLimit::get() as usize]; - let new_type = AssetType::PoolShare(T::AssetId::from(10u8),T::AssetId::from(20u8)); + let new_type = AssetType::XYK; let new_ed = 1_000_000_u128; let new_xcm_rate_limit = 1_000_u128; let new_is_sufficient = false; diff --git a/pallets/asset-registry/src/lib.rs b/pallets/asset-registry/src/lib.rs index 57a1ca6d5..79edea684 100644 --- a/pallets/asset-registry/src/lib.rs +++ b/pallets/asset-registry/src/lib.rs @@ -47,7 +47,7 @@ use frame_support::storage::with_transaction; use frame_support::BoundedVec; use hydradx_traits::{ registry::{Create, Inspect, Mutate}, - AssetKind, CreateRegistry, Registry, ShareTokenRegistry, + AssetKind, }; use sp_runtime::TransactionOutcome; @@ -62,7 +62,7 @@ pub mod pallet { use super::*; - pub type AssetDetailsT = AssetDetails<::AssetId, ::StringLimit>; + pub type AssetDetailsT = AssetDetails<::StringLimit>; #[pallet::config] pub trait Config: frame_system::Config { @@ -140,19 +140,19 @@ pub mod pallet { /// Incorrect number of assets provided to create shared asset. InvalidSharedAssetLen, - /// Cannot update asset location + /// Cannot update asset location. CannotUpdateLocation, /// Selected asset id is out of reserved range. NotInReservedRange, - /// Location already registered with different asset + /// Location already registered with different asset. LocationAlreadyRegistered, - /// Origin is forbidden to set/update value + /// Origin is forbidden to set/update value. Forbidden, - /// Balance too low + /// Balance too low. InsufficientBalance, //NOTE: This error is triggered from `SufficiencyCheck`. @@ -323,7 +323,7 @@ pub mod pallet { Registered { asset_id: T::AssetId, asset_name: Option>, - asset_type: AssetType, + asset_type: AssetType, existential_deposit: Balance, xcm_rate_limit: Option, symbol: Option>, @@ -335,7 +335,7 @@ pub mod pallet { Updated { asset_id: T::AssetId, asset_name: Option>, - asset_type: AssetType, + asset_type: AssetType, existential_deposit: Balance, xcm_rate_limit: Option, symbol: Option>, @@ -371,7 +371,7 @@ pub mod pallet { origin: OriginFor, asset_id: Option, name: Option>, - asset_type: AssetType, + asset_type: AssetType, existential_deposit: Option, symbol: Option>, decimals: Option, @@ -414,7 +414,7 @@ pub mod pallet { origin: OriginFor, asset_id: T::AssetId, name: Option>, - asset_type: Option>, + asset_type: Option, existential_deposit: Option, xcm_rate_limit: Option, is_sufficient: Option, @@ -526,7 +526,7 @@ impl Pallet { } /// Convert Vec to BoundedVec so it respects the max set limit, otherwise return TooLong error - fn try_into_bounded(name: Option>) -> Result>, Error> { + pub fn try_into_bounded(name: Option>) -> Result>, Error> { let Some(s) = name else { return Ok(None); }; @@ -551,7 +551,7 @@ impl Pallet { #[require_transactional] fn do_register_asset( selected_asset_id: Option, - details: &AssetDetails, + details: &AssetDetails, location: Option, ) -> Result { let asset_id = if let Some(id) = selected_asset_id { @@ -600,7 +600,7 @@ impl Pallet { /// Create asset for given name or return existing AssetId if such asset already exists. pub fn get_or_create_asset( name: Vec, - asset_type: AssetType, + asset_type: AssetType, existential_deposit: Balance, asset_id: Option, is_sufficient: bool, @@ -641,53 +641,6 @@ impl Pallet { } } -impl Registry, Balance, DispatchError> for Pallet { - fn exists(asset_id: T::AssetId) -> bool { - Assets::::contains_key(asset_id) - } - - fn retrieve_asset(name: &Vec) -> Result { - let bounded_name = Self::try_into_bounded(Some(name.clone()))? - .ok_or_else(|| -> pallet::Error { InconsistentStateError::BoundedConversionFailed.into() })?; - if let Some(asset_id) = AssetIds::::get(bounded_name) { - Ok(asset_id) - } else { - Err(Error::::AssetNotFound.into()) - } - } - - fn retrieve_asset_type(asset_id: T::AssetId) -> Result { - let asset_details = - Assets::::get(asset_id).ok_or_else(|| Into::::into(Error::::AssetNotFound))?; - Ok(asset_details.asset_type.into()) - } - - fn create_asset(name: &Vec, existential_deposit: Balance) -> Result { - Self::get_or_create_asset(name.clone(), AssetType::Token, existential_deposit, None, false) - } -} - -impl ShareTokenRegistry, Balance, DispatchError> for Pallet { - fn retrieve_shared_asset(name: &Vec, _assets: &[T::AssetId]) -> Result { - Self::retrieve_asset(name) - } - - fn create_shared_asset( - name: &Vec, - assets: &[T::AssetId], - existential_deposit: Balance, - ) -> Result { - ensure!(assets.len() == 2, Error::::InvalidSharedAssetLen); - Self::get_or_create_asset( - name.clone(), - AssetType::PoolShare(assets[0], assets[1]), - existential_deposit, - None, - false, - ) - } -} - use orml_traits::GetByKey; // Return Existential deposit of an asset @@ -712,23 +665,9 @@ impl GetByKey> for XcmRateLimitsInRegistr } } -impl CreateRegistry for Pallet { - type Error = DispatchError; - - fn create_asset(name: &[u8], kind: AssetKind, existential_deposit: Balance) -> Result { - let bounded_name = Self::try_into_bounded(Some(name.to_vec()))?; - - Pallet::::do_register_asset( - None, - &AssetDetails::new(bounded_name, kind.into(), existential_deposit, None, None, None, false), - None, - ) - } -} - impl Inspect for Pallet { - type Error = DispatchError; type AssetId = T::AssetId; + type Location = T::AssetNativeLocation; fn is_sufficient(id: Self::AssetId) -> bool { match Self::assets(id) { @@ -736,15 +675,33 @@ impl Inspect for Pallet { None => false, } } + + fn exists(id: Self::AssetId) -> bool { + Assets::::try_get(id).is_ok() + } + + fn decimals(id: Self::AssetId) -> Option { + Self::assets(id).and_then(|a| a.decimals) + } + + fn asset_type(id: Self::AssetId) -> Option { + Self::assets(id).map(|a| a.asset_type.into()) + } } -impl Mutate for Pallet { +impl Mutate for Pallet { + type Error = DispatchError; + fn set_location(asset_id: Self::AssetId, location: T::AssetNativeLocation) -> Result<(), Self::Error> { + ensure!(Self::exists(asset_id), Error::::AssetNotFound); + Self::do_set_location(asset_id, location) } } -impl Create for Pallet { +impl Create for Pallet { + type Error = DispatchError; + fn register_asset( asset_id: Option, name: Option<&[u8]>, @@ -752,7 +709,7 @@ impl Create for Pallet { existential_deposit: Option, symbol: Option<&[u8]>, decimals: Option, - location: Option, + location: Option, xcm_rate_limit: Option, is_sufficient: bool, ) -> Result { @@ -771,15 +728,40 @@ impl Create for Pallet { Self::do_register_asset(asset_id, &details, location) } -} -use hydradx_traits::InspectRegistry; -impl InspectRegistry for Pallet { - fn exists(asset_id: T::AssetId) -> bool { - Assets::::contains_key(asset_id) - } + fn get_or_register_asset( + name: &[u8], + kind: AssetKind, + existential_deposit: Option, + symbol: Option<&[u8]>, + decimals: Option, + location: Option, + xcm_rate_limit: Option, + is_sufficient: bool, + ) -> Result { + //NOTE: in this case `try_into_bounded()` should never return None. + let bounded_name = match Self::try_into_bounded(Some(name.to_vec()))? { + Some(n) => n, + None => return Err(Error::::InconsistentState(InconsistentStateError::BoundedConversionFailed).into()), + }; + + match Self::asset_ids(bounded_name.clone()) { + Some(id) => Ok(id), + None => { + let bounded_symbol = Self::try_into_bounded(symbol.map(|x| x.to_vec()))?; + + let details = AssetDetails::new( + Some(bounded_name), + kind.into(), + existential_deposit.unwrap_or(DEFAULT_ED), + bounded_symbol, + decimals, + xcm_rate_limit, + is_sufficient, + ); - fn decimals(asset_id: T::AssetId) -> Option { - Assets::::get(asset_id)?.decimals + Self::do_register_asset(None, &details, location) + } + } } } diff --git a/pallets/asset-registry/src/migration.rs b/pallets/asset-registry/src/migration.rs index b9db6dffb..2c2520e00 100644 --- a/pallets/asset-registry/src/migration.rs +++ b/pallets/asset-registry/src/migration.rs @@ -34,9 +34,9 @@ pub mod v1 { use sp_runtime::BoundedVec; #[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, TypeInfo)] - pub struct AssetDetails { + pub struct AssetDetails { pub name: BoundedString, - pub asset_type: AssetType, + pub asset_type: AssetType, pub existential_deposit: Balance, pub xcm_rate_limit: Option, } @@ -52,7 +52,7 @@ pub mod v1 { Pallet, Twox64Concat, ::AssetId, - AssetDetails<::AssetId, Balance, BoundedVec::StringLimit>>, + AssetDetails::StringLimit>>, OptionQuery, >; @@ -101,7 +101,7 @@ pub mod v2 { let mut i = 0; let mut v2_assets_details = Vec::<( ::AssetId, - AssetDetails<::AssetId, ::StringLimit>, + AssetDetails<::StringLimit>, )>::new(); for (k, v) in v1::Assets::::iter() { i += 1; diff --git a/pallets/asset-registry/src/tests/create_trait.rs b/pallets/asset-registry/src/tests/create_trait.rs new file mode 100644 index 000000000..0e00f17ca --- /dev/null +++ b/pallets/asset-registry/src/tests/create_trait.rs @@ -0,0 +1,521 @@ +use super::*; + +use hydradx_traits::registry::Create; +use mock::Registry; + +use frame_support::storage::with_transaction; +use polkadot_xcm::v3::{ + Junction::{self, Parachain}, + Junctions::X2, + MultiLocation, +}; +use sp_runtime::{DispatchResult, TransactionOutcome}; + +#[test] +fn register_asset_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = with_transaction(|| { + let asset_id = 1; + let name = b"Test asset".to_vec(); + let symbol = b"TKN".to_vec(); + let decimals = 12; + let xcm_rate_limit = 1_000; + let ed = 10_000; + let is_sufficient = true; + + let key = Junction::from(BoundedVec::try_from(asset_id.encode()).unwrap()); + let asset_location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + + //Act + assert_ok!(>::register_asset( + Some(asset_id), + Some(&name), + AssetKind::XYK, + Some(ed), + Some(&symbol), + Some(decimals), + Some(asset_location.clone()), + Some(xcm_rate_limit), + is_sufficient + )); + + //Assert + let bounded_name = Pallet::::try_into_bounded(Some(name)).unwrap(); + let bounded_symbol = Pallet::::try_into_bounded(Some(symbol)).unwrap(); + assert_eq!( + Registry::assets(asset_id), + Some(AssetDetails { + name: bounded_name.clone(), + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol.clone(), + decimals: Some(decimals), + is_sufficient + }) + ); + + assert_eq!(Registry::asset_ids(bounded_name.clone().unwrap()), Some(asset_id)); + + assert_eq!(Registry::location_assets(asset_location.clone()), Some(asset_id)); + assert_eq!(Registry::locations(asset_id), Some(asset_location.clone())); + + assert!(has_event( + Event::::Registered { + asset_id, + asset_name: bounded_name, + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol, + decimals: Some(decimals), + is_sufficient + } + .into() + )); + + assert!(has_event( + Event::::LocationSet { + asset_id, + location: asset_location + } + .into() + )); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); +} + +#[test] +fn register_insufficient_asset_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = with_transaction(|| { + let asset_id = 1; + let name = b"Test asset".to_vec(); + let symbol = b"TKN".to_vec(); + let decimals = 12; + let xcm_rate_limit = 1_000; + let ed = 10_000; + + let key = Junction::from(BoundedVec::try_from(asset_id.encode()).unwrap()); + let asset_location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + + //Act + assert_ok!(>::register_insufficient_asset( + Some(asset_id), + Some(&name), + AssetKind::XYK, + Some(ed), + Some(&symbol), + Some(decimals), + Some(asset_location.clone()), + Some(xcm_rate_limit), + )); + + //Assert + let bounded_name = Pallet::::try_into_bounded(Some(name)).unwrap(); + let bounded_symbol = Pallet::::try_into_bounded(Some(symbol)).unwrap(); + assert_eq!( + Registry::assets(asset_id), + Some(AssetDetails { + name: bounded_name.clone(), + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol.clone(), + decimals: Some(decimals), + is_sufficient: false + }) + ); + + assert_eq!(Registry::asset_ids(bounded_name.clone().unwrap()), Some(asset_id)); + + assert_eq!(Registry::location_assets(asset_location.clone()), Some(asset_id)); + assert_eq!(Registry::locations(asset_id), Some(asset_location.clone())); + + assert!(has_event( + Event::::Registered { + asset_id, + asset_name: bounded_name, + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol, + decimals: Some(decimals), + is_sufficient: false + } + .into() + )); + + assert!(has_event( + Event::::LocationSet { + asset_id, + location: asset_location + } + .into() + )); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); +} + +#[test] +fn register_sufficient_asset_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = with_transaction(|| { + let asset_id = 1; + let name = b"Test asset".to_vec(); + let symbol = b"TKN".to_vec(); + let decimals = 12; + let xcm_rate_limit = 1_000; + let ed = 10_000; + + let key = Junction::from(BoundedVec::try_from(asset_id.encode()).unwrap()); + let asset_location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + + //Act + assert_ok!(>::register_sufficient_asset( + Some(asset_id), + Some(&name), + AssetKind::XYK, + ed, + Some(&symbol), + Some(decimals), + Some(asset_location.clone()), + Some(xcm_rate_limit), + )); + + //Assert + let bounded_name = Pallet::::try_into_bounded(Some(name)).unwrap(); + let bounded_symbol = Pallet::::try_into_bounded(Some(symbol)).unwrap(); + assert_eq!( + Registry::assets(asset_id), + Some(AssetDetails { + name: bounded_name.clone(), + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol.clone(), + decimals: Some(decimals), + is_sufficient: true + }) + ); + + assert_eq!(Registry::asset_ids(bounded_name.clone().unwrap()), Some(asset_id)); + + assert_eq!(Registry::location_assets(asset_location.clone()), Some(asset_id)); + assert_eq!(Registry::locations(asset_id), Some(asset_location.clone())); + + assert!(has_event( + Event::::Registered { + asset_id, + asset_name: bounded_name, + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol, + decimals: Some(decimals), + is_sufficient: true + } + .into() + )); + + assert!(has_event( + Event::::LocationSet { + asset_id, + location: asset_location + } + .into() + )); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); +} + +#[test] +fn get_or_register_asset_should_register_asset_when_does_not_exists() { + ExtBuilder::default().build().execute_with(|| { + let _ = with_transaction(|| { + let new_asset_id = Registry::next_asset_id().unwrap(); + let name = b"Test asset".to_vec(); + let symbol = b"TKN".to_vec(); + let decimals = 12; + let xcm_rate_limit = 1_000; + let ed = 10_000; + let is_sufficient = true; + + let key = Junction::from(BoundedVec::try_from(new_asset_id.encode()).unwrap()); + let asset_location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + + //Act + assert_ok!( + >::get_or_register_asset( + &name, + AssetKind::XYK, + Some(ed), + Some(&symbol), + Some(decimals), + Some(asset_location.clone()), + Some(xcm_rate_limit), + is_sufficient + ), + new_asset_id + ); + + //Assert + let bounded_name = Pallet::::try_into_bounded(Some(name)).unwrap(); + let bounded_symbol = Pallet::::try_into_bounded(Some(symbol)).unwrap(); + assert_eq!( + Registry::assets(new_asset_id), + Some(AssetDetails { + name: bounded_name.clone(), + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol.clone(), + decimals: Some(decimals), + is_sufficient + }) + ); + + assert_eq!(Registry::asset_ids(bounded_name.clone().unwrap()), Some(new_asset_id)); + + assert_eq!(Registry::location_assets(asset_location.clone()), Some(new_asset_id)); + assert_eq!(Registry::locations(new_asset_id), Some(asset_location.clone())); + + assert!(has_event( + Event::::Registered { + asset_id: new_asset_id, + asset_name: bounded_name, + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol, + decimals: Some(decimals), + is_sufficient + } + .into() + )); + + assert!(has_event( + Event::::LocationSet { + asset_id: new_asset_id, + location: asset_location + } + .into() + )); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); +} + +#[test] +fn get_or_register_asset_should_return_asset_id_when_asset_exists() { + let existing_asset_id = 1_u32; + ExtBuilder::default() + .with_assets(vec![( + Some(existing_asset_id), + Some(b"Asset".to_vec()), + UNIT, + None, + None, + None, + false, + )]) + .build() + .execute_with(|| { + let _ = with_transaction(|| { + let name = b"Asset".to_vec(); + let symbol = b"TKN".to_vec(); + let decimals = 12; + let xcm_rate_limit = 1_000; + let ed = 10_000; + let is_sufficient = true; + + let key = Junction::from(BoundedVec::try_from(1_000.encode()).unwrap()); + let asset_location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + + //Act + assert_ok!( + >::get_or_register_asset( + &name, + AssetKind::XYK, + Some(ed), + Some(&symbol), + Some(decimals), + Some(asset_location), + Some(xcm_rate_limit), + is_sufficient + ), + existing_asset_id + ); + + //Assert + let bounded_name = Pallet::::try_into_bounded(Some(b"Asset".to_vec())).unwrap(); + assert_eq!( + Registry::assets(existing_asset_id), + Some(AssetDetails { + name: bounded_name, + asset_type: AssetType::Token, + existential_deposit: UNIT, + xcm_rate_limit: None, + symbol: None, + decimals: None, + is_sufficient: false + }) + ); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); +} + +#[test] +fn get_or_register_sufficient_asset_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = with_transaction(|| { + let new_asset_id = Registry::next_asset_id().unwrap(); + let name = b"Test asset".to_vec(); + let symbol = b"TKN".to_vec(); + let decimals = 12; + let xcm_rate_limit = 1_000; + let ed = 10_000; + + let key = Junction::from(BoundedVec::try_from(new_asset_id.encode()).unwrap()); + let asset_location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + + //Act + assert_ok!(>::get_or_register_sufficient_asset( + &name, + AssetKind::XYK, + ed, + Some(&symbol), + Some(decimals), + Some(asset_location.clone()), + Some(xcm_rate_limit), + ),); + + //Assert + let bounded_name = Pallet::::try_into_bounded(Some(name)).unwrap(); + let bounded_symbol = Pallet::::try_into_bounded(Some(symbol)).unwrap(); + assert_eq!( + Registry::assets(new_asset_id), + Some(AssetDetails { + name: bounded_name.clone(), + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol.clone(), + decimals: Some(decimals), + is_sufficient: true + }) + ); + + assert_eq!(Registry::asset_ids(bounded_name.clone().unwrap()), Some(new_asset_id)); + + assert_eq!(Registry::location_assets(asset_location.clone()), Some(new_asset_id)); + assert_eq!(Registry::locations(new_asset_id), Some(asset_location.clone())); + + assert!(has_event( + Event::::Registered { + asset_id: new_asset_id, + asset_name: bounded_name, + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol, + decimals: Some(decimals), + is_sufficient: true + } + .into() + )); + + assert!(has_event( + Event::::LocationSet { + asset_id: new_asset_id, + location: asset_location + } + .into() + )); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); +} + +#[test] +fn get_or_register_insufficient_asset_should_work() { + ExtBuilder::default().build().execute_with(|| { + let _ = with_transaction(|| { + let new_asset_id = Registry::next_asset_id().unwrap(); + let name = b"Test asset".to_vec(); + let symbol = b"TKN".to_vec(); + let decimals = 12; + let xcm_rate_limit = 1_000; + let ed = 10_000; + + let key = Junction::from(BoundedVec::try_from(new_asset_id.encode()).unwrap()); + let asset_location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + + //Act + assert_ok!(>::get_or_register_insufficient_asset( + &name, + AssetKind::XYK, + Some(ed), + Some(&symbol), + Some(decimals), + Some(asset_location.clone()), + Some(xcm_rate_limit), + ),); + + //Assert + let bounded_name = Pallet::::try_into_bounded(Some(name)).unwrap(); + let bounded_symbol = Pallet::::try_into_bounded(Some(symbol)).unwrap(); + assert_eq!( + Registry::assets(new_asset_id), + Some(AssetDetails { + name: bounded_name.clone(), + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol.clone(), + decimals: Some(decimals), + is_sufficient: false + }) + ); + + assert_eq!(Registry::asset_ids(bounded_name.clone().unwrap()), Some(new_asset_id)); + + assert_eq!(Registry::location_assets(asset_location.clone()), Some(new_asset_id)); + assert_eq!(Registry::locations(new_asset_id), Some(asset_location.clone())); + + assert!(has_event( + Event::::Registered { + asset_id: new_asset_id, + asset_name: bounded_name, + asset_type: AssetType::XYK, + existential_deposit: ed, + xcm_rate_limit: Some(xcm_rate_limit), + symbol: bounded_symbol, + decimals: Some(decimals), + is_sufficient: false + } + .into() + )); + + assert!(has_event( + Event::::LocationSet { + asset_id: new_asset_id, + location: asset_location + } + .into() + )); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); +} diff --git a/pallets/asset-registry/src/tests/inspect_trait.rs b/pallets/asset-registry/src/tests/inspect_trait.rs new file mode 100644 index 000000000..82f5b1422 --- /dev/null +++ b/pallets/asset-registry/src/tests/inspect_trait.rs @@ -0,0 +1,133 @@ +use super::*; + +use frame_support::storage::with_transaction; +use hydradx_traits::registry::{AssetKind, Inspect}; +use mock::Registry; + +use pretty_assertions::assert_eq; +use sp_runtime::{DispatchResult, TransactionOutcome}; + +#[test] +fn is_sufficient_should_work() { + let suff_asset_id = 1_u32; + let insuff_asset_id = 2_u32; + let non_existing_id = 3_u32; + + ExtBuilder::default() + .with_assets(vec![ + ( + Some(suff_asset_id), + Some(b"Suff".to_vec()), + UNIT, + None, + None, + None, + true, + ), + ( + Some(insuff_asset_id), + Some(b"Insuff".to_vec()), + UNIT, + None, + None, + None, + false, + ), + ]) + .build() + .execute_with(|| { + assert_eq!(::is_sufficient(suff_asset_id), true); + + assert_eq!(::is_sufficient(insuff_asset_id), false); + + assert_eq!(::is_sufficient(non_existing_id), false); + }); +} + +#[test] +fn exists_should_work() { + let asset_id = 2_u32; + let non_existing_id = 3_u32; + + ExtBuilder::default() + .with_assets(vec![( + Some(asset_id), + Some(b"Suff".to_vec()), + UNIT, + None, + None, + None, + true, + )]) + .build() + .execute_with(|| { + assert_eq!(::exists(asset_id), true); + + assert_eq!(::exists(non_existing_id), false); + }); +} + +#[test] +fn decimals_should_work() { + let non_existing_id = 543_u32; + + ExtBuilder::default() + .with_assets(vec![ + (Some(1), Some(b"TKN1".to_vec()), UNIT, None, Some(5_u8), None, true), + (Some(2), Some(b"TKN2".to_vec()), UNIT, None, Some(0_u8), None, true), + (Some(3), Some(b"TKN3".to_vec()), UNIT, None, None, None, true), + ]) + .build() + .execute_with(|| { + assert_eq!(::decimals(1), Some(5)); + + assert_eq!(::decimals(2), Some(0)); + + assert_eq!(::decimals(3), None); + + assert_eq!(::decimals(non_existing_id), None); + }); +} + +#[test] +fn asset_type_should_work() { + let non_existing_id = 543_u32; + + ExtBuilder::default().build().execute_with(|| { + let _ = with_transaction(|| { + //Arrange + let token_type_id = + Registry::register_insufficient_asset(None, None, AssetKind::Token, None, None, None, None, None) + .unwrap(); + let xyk_type_id = + Registry::register_insufficient_asset(None, None, AssetKind::XYK, None, None, None, None, None) + .unwrap(); + let stableswap_type_id = + Registry::register_insufficient_asset(None, None, AssetKind::StableSwap, None, None, None, None, None) + .unwrap(); + let bond_type_id = + Registry::register_insufficient_asset(None, None, AssetKind::Bond, None, None, None, None, None) + .unwrap(); + let external_type_id = + Registry::register_insufficient_asset(None, None, AssetKind::External, None, None, None, None, None) + .unwrap(); + + //Assert + assert_eq!(::asset_type(token_type_id), Some(AssetKind::Token)); + assert_eq!(::asset_type(xyk_type_id), Some(AssetKind::XYK)); + assert_eq!( + ::asset_type(stableswap_type_id), + Some(AssetKind::StableSwap) + ); + assert_eq!(::asset_type(bond_type_id), Some(AssetKind::Bond)); + assert_eq!( + ::asset_type(external_type_id), + Some(AssetKind::External) + ); + + assert_eq!(::asset_type(non_existing_id), None); + + TransactionOutcome::Commit(DispatchResult::Ok(())) + }); + }); +} diff --git a/pallets/asset-registry/src/tests/mod.rs b/pallets/asset-registry/src/tests/mod.rs index f85c48bcb..16d7c4489 100644 --- a/pallets/asset-registry/src/tests/mod.rs +++ b/pallets/asset-registry/src/tests/mod.rs @@ -3,7 +3,10 @@ use mock::*; use crate::*; use frame_support::{assert_noop, assert_ok}; +mod create_trait; +mod inspect_trait; pub(crate) mod mock; +mod mutate_trait; mod register; mod update; diff --git a/pallets/asset-registry/src/tests/mutate_trait.rs b/pallets/asset-registry/src/tests/mutate_trait.rs new file mode 100644 index 000000000..0477fe167 --- /dev/null +++ b/pallets/asset-registry/src/tests/mutate_trait.rs @@ -0,0 +1,82 @@ +use super::*; + +use hydradx_traits::registry::Mutate; +use mock::Registry; + +use polkadot_xcm::v3::{ + Junction::{self, Parachain}, + Junctions::X2, + MultiLocation, +}; + +#[test] +fn set_location_should_work_when_location_was_not_set_yet() { + let asset_id = 1_u32; + ExtBuilder::default() + .with_assets(vec![( + Some(asset_id), + Some(b"Suff".to_vec()), + UNIT, + None, + None, + None, + true, + )]) + .build() + .execute_with(|| { + let key = Junction::from(BoundedVec::try_from(asset_id.encode()).unwrap()); + let location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + assert_eq!(Registry::locations(asset_id), None); + + //Act + assert_ok!(::set_location(asset_id, location.clone())); + + //Assert + assert_eq!(Registry::location_assets(location.clone()), Some(asset_id)); + assert_eq!(Registry::locations(asset_id), Some(location)); + }); +} + +#[test] +fn set_location_should_not_work_when_location_was_not() { + let asset_id = 1_u32; + ExtBuilder::default() + .with_assets(vec![( + Some(asset_id), + Some(b"Suff".to_vec()), + UNIT, + None, + None, + None, + true, + )]) + .build() + .execute_with(|| { + //Arrange + let key = Junction::from(BoundedVec::try_from(asset_id.encode()).unwrap()); + let location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + Pallet::::set_location(asset_id, location.clone()).unwrap(); + + //Act + assert_noop!( + ::set_location(asset_id, location), + Error::::LocationAlreadyRegistered + ); + }); +} + +#[test] +fn set_location_should_not_work_when_asset_does_not_exists() { + let non_existing_id = 190_u32; + ExtBuilder::default().build().execute_with(|| { + //Arrange + let key = Junction::from(BoundedVec::try_from(non_existing_id.encode()).unwrap()); + let location = AssetLocation(MultiLocation::new(0, X2(Parachain(200), key))); + + //Act + assert_noop!( + ::set_location(non_existing_id, location), + Error::::AssetNotFound + ); + }); +} diff --git a/pallets/asset-registry/src/types.rs b/pallets/asset-registry/src/types.rs index 606722b89..434567a2d 100644 --- a/pallets/asset-registry/src/types.rs +++ b/pallets/asset-registry/src/types.rs @@ -26,16 +26,15 @@ use serde::{Deserialize, Serialize}; #[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum AssetType { +pub enum AssetType { Token, - PoolShare(AssetId, AssetId), // Use XYX instead XYK, StableSwap, Bond, External, } -impl From for AssetType { +impl From for AssetType { fn from(value: AssetKind) -> Self { match value { AssetKind::Token => Self::Token, @@ -47,11 +46,10 @@ impl From for AssetType { } } -impl From> for AssetKind { - fn from(value: AssetType) -> Self { +impl From for AssetKind { + fn from(value: AssetType) -> Self { match value { AssetType::Token => Self::Token, - AssetType::PoolShare(_, _) => Self::XYK, AssetType::XYK => Self::XYK, AssetType::StableSwap => Self::StableSwap, AssetType::Bond => Self::Bond, @@ -63,12 +61,12 @@ impl From> for AssetKind { #[derive(Encode, Decode, Eq, PartialEq, Clone, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[scale_info(skip_type_params(StringLimit))] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct AssetDetails> { +pub struct AssetDetails> { /// The name of this asset. Limited in length by `StringLimit`. pub name: Option>, /// Asset type - pub asset_type: AssetType, + pub asset_type: AssetType, /// Existential deposit pub existential_deposit: Balance, @@ -86,10 +84,10 @@ pub struct AssetDetails> { pub is_sufficient: bool, } -impl> AssetDetails { +impl> AssetDetails { pub fn new( name: Option>, - asset_type: AssetType, + asset_type: AssetType, existential_deposit: Balance, symbol: Option>, decimals: Option, diff --git a/pallets/bonds/Cargo.toml b/pallets/bonds/Cargo.toml index aeb4cbf7f..0f806a0e5 100644 --- a/pallets/bonds/Cargo.toml +++ b/pallets/bonds/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-bonds" -version = "2.0.0" +version = "2.1.0" authors = ['GalacticCouncil'] edition = "2021" license = "Apache-2.0" diff --git a/pallets/bonds/src/lib.rs b/pallets/bonds/src/lib.rs index bc064be8e..2d43e271c 100644 --- a/pallets/bonds/src/lib.rs +++ b/pallets/bonds/src/lib.rs @@ -55,7 +55,10 @@ use frame_system::{ensure_signed, pallet_prelude::OriginFor}; use sp_core::MaxEncodedLen; use sp_std::vec::Vec; -use hydradx_traits::{AssetKind, CreateRegistry, Registry}; +use hydradx_traits::{ + registry::{Create, Inspect}, + AssetKind, +}; use orml_traits::{GetByKey, MultiCurrency}; use primitives::{AssetId, Moment}; @@ -101,8 +104,7 @@ pub mod pallet { type Currency: MultiCurrency; /// Asset Registry mechanism - used to register bonds in the asset registry. - type AssetRegistry: Registry, Self::Balance, DispatchError> - + CreateRegistry; + type AssetRegistry: Inspect + Create; /// Provider for existential deposits of assets. type ExistentialDeposits: GetByKey; @@ -180,6 +182,8 @@ pub mod pallet { InvalidMaturity, /// Asset type not allowed for underlying asset DisallowedAsset, + /// Asset is not registered in `AssetRegistry` + AssetNotFound, } #[pallet::call] @@ -211,7 +215,9 @@ pub mod pallet { let who = T::IssueOrigin::ensure_origin(origin)?; ensure!( - T::AssetTypeWhitelist::contains(&T::AssetRegistry::retrieve_asset_type(asset_id)?), + T::AssetTypeWhitelist::contains( + &T::AssetRegistry::asset_type(asset_id).ok_or(Error::::AssetNotFound)? + ), Error::::DisallowedAsset ); @@ -226,11 +232,15 @@ pub mod pallet { ensure!(maturity >= T::TimestampProvider::now(), Error::::InvalidMaturity); let ed = T::ExistentialDeposits::get(&asset_id); - - let bond_id = >::create_asset( - &Self::bond_name(asset_id, maturity), + let bond_id = T::AssetRegistry::register_insufficient_asset( + None, + Some(&Self::bond_name(asset_id, maturity)), AssetKind::Bond, - ed, + Some(ed), + None, + None, + None, + None, )?; Bonds::::insert(bond_id, (asset_id, maturity)); diff --git a/pallets/bonds/src/tests/issue.rs b/pallets/bonds/src/tests/issue.rs index 79a071686..42569a292 100644 --- a/pallets/bonds/src/tests/issue.rs +++ b/pallets/bonds/src/tests/issue.rs @@ -494,7 +494,7 @@ fn issue_bonds_should_fail_when_underlying_asset_not_registered() { let asset_id = next_asset_id(); assert_noop!( Bonds::issue(RuntimeOrigin::signed(ALICE), asset_id, ONE, NOW + MONTH), - DispatchError::Other("AssetNotFound") + Error::::AssetNotFound ); }); } diff --git a/pallets/bonds/src/tests/mock.rs b/pallets/bonds/src/tests/mock.rs index da070395a..9f6eedeca 100644 --- a/pallets/bonds/src/tests/mock.rs +++ b/pallets/bonds/src/tests/mock.rs @@ -30,7 +30,7 @@ use frame_system::EnsureSignedBy; use sp_core::H256; use std::{cell::RefCell, collections::HashMap}; -use hydradx_traits::CreateRegistry; +use hydradx_traits::registry::{Create, Inspect}; use orml_traits::parameter_type_with_key; pub use primitives::constants::{ currency::NATIVE_EXISTENTIAL_DEPOSIT, @@ -43,6 +43,8 @@ pub use primitives::constants::{ type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; +type AssetLocation = u8; + pub type AccountId = u64; pub type Balance = u128; @@ -103,7 +105,7 @@ impl Contains for AssetTypeWhitelist { } } -impl Config for Test { +impl pallet_bonds::Config for Test { type RuntimeEvent = RuntimeEvent; type Balance = Balance; type Currency = Tokens; @@ -172,40 +174,72 @@ impl pallet_timestamp::Config for Test { pub struct DummyRegistry(sp_std::marker::PhantomData); -impl CreateRegistry for DummyRegistry { +impl Create for DummyRegistry { type Error = DispatchError; - fn create_asset(_name: &[u8], _kind: AssetKind, existential_deposit: Balance) -> Result { + fn register_asset( + _asset_id: Option, + _name: Option<&[u8]>, + _kind: AssetKind, + _existential_deposit: Option, + _symbol: Option<&[u8]>, + _decimals: Option, + _location: Option, + _xcm_rate_limit: Option, + _is_sufficient: bool, + ) -> Result { + unimplemented!() + } + + fn register_insufficient_asset( + _asset_id: Option, + _name: Option<&[u8]>, + _kind: AssetKind, + existential_deposit: Option, + _symbol: Option<&[u8]>, + _decimals: Option, + _location: Option, + _xcm_rate_limit: Option, + ) -> Result { let assigned = REGISTERED_ASSETS.with(|v| { let l = v.borrow().len(); - v.borrow_mut().insert(l as u32, (existential_deposit, AssetKind::Bond)); + v.borrow_mut() + .insert(l as u32, (existential_deposit.unwrap(), AssetKind::Bond)); l as u32 }); Ok(assigned) } -} - -impl Registry, Balance, DispatchError> for DummyRegistry { - fn exists(_name: AssetId) -> bool { + fn get_or_register_asset( + _name: &[u8], + _kind: AssetKind, + _existential_deposit: Option, + _symbol: Option<&[u8]>, + _decimals: Option, + _location: Option, + _xcm_rate_limit: Option, + _is_sufficient: bool, + ) -> Result { unimplemented!() } +} + +impl Inspect for DummyRegistry { + type AssetId = AssetId; + type Location = AssetLocation; - fn retrieve_asset(_name: &Vec) -> Result { + fn is_sufficient(_id: Self::AssetId) -> bool { unimplemented!() } - fn retrieve_asset_type(asset_id: AssetId) -> Result { - REGISTERED_ASSETS - .with(|v| v.borrow().get(&asset_id).cloned()) - .map(|v| v.1) - .ok_or(DispatchError::Other("AssetNotFound")) + fn decimals(_id: Self::AssetId) -> Option { + unimplemented!() } - fn create_asset(_name: &Vec, _existential_deposit: Balance) -> Result { - unimplemented!() + fn asset_type(id: Self::AssetId) -> Option { + REGISTERED_ASSETS.with(|v| v.borrow().get(&id).cloned()).map(|v| v.1) } - fn get_or_create_asset(_name: Vec, _existential_deposit: Balance) -> Result { + fn exists(_name: AssetId) -> bool { unimplemented!() } } diff --git a/pallets/circuit-breaker/Cargo.toml b/pallets/circuit-breaker/Cargo.toml index 6ebe64d55..f0d88a8d3 100644 --- a/pallets/circuit-breaker/Cargo.toml +++ b/pallets/circuit-breaker/Cargo.toml @@ -47,6 +47,9 @@ std = [ 'frame-system/std', 'serde/std', 'scale-info/std', + 'frame-benchmarking/std', + 'pallet-balances/std', + 'orml-tokens/std', ] runtime-benchmarks = [ "frame-benchmarking", diff --git a/pallets/circuit-breaker/src/tests/mock.rs b/pallets/circuit-breaker/src/tests/mock.rs index 6ae036067..21d7884ae 100644 --- a/pallets/circuit-breaker/src/tests/mock.rs +++ b/pallets/circuit-breaker/src/tests/mock.rs @@ -362,35 +362,33 @@ impl + Into + Copy> Mutate for DummyNFT { } use crate::Config; -use hydradx_traits::{AssetKind, Registry}; +use hydradx_traits::registry::{AssetKind, Inspect as InspectRegistry}; use pallet_omnipool::traits::{AssetInfo, ExternalPriceProvider, OmnipoolHooks}; pub struct DummyRegistry(sp_std::marker::PhantomData); -impl Registry, Balance, DispatchError> for DummyRegistry +impl InspectRegistry for DummyRegistry where T::AssetId: Into + From, { - fn exists(asset_id: T::AssetId) -> bool { - let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); - matches!(asset, Some(_)) + type AssetId = T::AssetId; + type Location = u8; + + fn is_sufficient(_id: Self::AssetId) -> bool { + unimplemented!() } - fn retrieve_asset(_name: &Vec) -> Result { - Ok(T::AssetId::default()) + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() } - fn retrieve_asset_type(_asset_id: T::AssetId) -> Result { + fn decimals(_id: Self::AssetId) -> Option { unimplemented!() } - fn create_asset(_name: &Vec, _existential_deposit: Balance) -> Result { - let assigned = REGISTERED_ASSETS.with(|v| { - let l = v.borrow().len(); - v.borrow_mut().insert(l as u32, l as u32); - l as u32 - }); - Ok(T::AssetId::from(assigned)) + fn exists(asset_id: T::AssetId) -> bool { + let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); + matches!(asset, Some(_)) } } diff --git a/pallets/dca/Cargo.toml b/pallets/dca/Cargo.toml index 00e5aef6a..29ae58192 100644 --- a/pallets/dca/Cargo.toml +++ b/pallets/dca/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-dca' -version = "1.2.0" +version = "1.2.1" description = 'A pallet to manage DCA scheduling' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/dca/src/tests/mock.rs b/pallets/dca/src/tests/mock.rs index 2cec929fc..e31a25c33 100644 --- a/pallets/dca/src/tests/mock.rs +++ b/pallets/dca/src/tests/mock.rs @@ -28,7 +28,7 @@ use frame_support::BoundedVec; use frame_support::{assert_ok, parameter_types}; use frame_system as system; use frame_system::{ensure_signed, EnsureRoot}; -use hydradx_traits::{AssetKind, NativePriceOracle, OraclePeriod, PriceOracle, Registry}; +use hydradx_traits::{registry::Inspect as InspectRegistry, AssetKind, NativePriceOracle, OraclePeriod, PriceOracle}; use orml_traits::{parameter_type_with_key, GetByKey}; use pallet_currencies::BasicCurrencyAdapter; use primitive_types::U128; @@ -716,30 +716,28 @@ impl + Into + Copy> Mutate for DummyNFT { pub struct DummyRegistry(sp_std::marker::PhantomData); -impl Registry, Balance, DispatchError> for DummyRegistry +impl InspectRegistry for DummyRegistry where T::AssetId: Into + From, { - fn exists(asset_id: T::AssetId) -> bool { - let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); - matches!(asset, Some(_)) + type AssetId = T::AssetId; + type Location = u8; + + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() } - fn retrieve_asset(_name: &Vec) -> Result { - Ok(1.into()) + fn is_sufficient(_id: Self::AssetId) -> bool { + unimplemented!() } - fn retrieve_asset_type(_asset_id: T::AssetId) -> Result { + fn decimals(_id: Self::AssetId) -> Option { unimplemented!() } - fn create_asset(_name: &Vec, _existential_deposit: Balance) -> Result { - let assigned = REGISTERED_ASSETS.with(|v| { - let l = v.borrow().len(); - v.borrow_mut().insert(l as u32, l as u32); - l as u32 - }); - Ok(T::AssetId::from(assigned)) + fn exists(asset_id: T::AssetId) -> bool { + let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); + matches!(asset, Some(_)) } } diff --git a/pallets/lbp/src/types.rs b/pallets/lbp/src/types.rs new file mode 100644 index 000000000..e565b7146 --- /dev/null +++ b/pallets/lbp/src/types.rs @@ -0,0 +1,67 @@ +// This file is part of HydraDX-node. + +// Copyright (C) 2020-2022 Intergalactic, Limited (GIB). +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub type AssetId = u32; +pub type Balance = u128; +pub type Amount = i128; + +use codec::{Decode, Encode}; +use scale_info::TypeInfo; +use sp_std::vec::Vec; + +#[cfg(feature = "std")] +use serde::{Deserialize, Serialize}; + +/// Asset Pair representation for AMM trades +/// `( asset_a, asset_b )` combination where `asset_a` is meant to be exchanged for `asset_b` +/// +/// `asset_in` represents asset coming into the pool +/// `asset_out` represents asset coming out of the pool +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Debug, Encode, Decode, Copy, Clone, PartialEq, Eq, Default, TypeInfo)] +pub struct AssetPair { + pub asset_in: AssetId, + pub asset_out: AssetId, +} + +impl AssetPair { + pub fn new(asset_in: AssetId, asset_out: AssetId) -> Self { + Self { asset_in, asset_out } + } + + /// Return ordered asset tuple (A,B) where A < B + /// Used in storage + pub fn ordered_pair(&self) -> (AssetId, AssetId) { + match self.asset_in <= self.asset_out { + true => (self.asset_in, self.asset_out), + false => (self.asset_out, self.asset_in), + } + } + + /// Return share token name + pub fn name(&self) -> Vec { + let mut buf: Vec = Vec::new(); + + let (asset_a, asset_b) = self.ordered_pair(); + + buf.extend_from_slice(&asset_a.to_le_bytes()); + buf.extend_from_slice(b"HDT"); + buf.extend_from_slice(&asset_b.to_le_bytes()); + + buf + } +} diff --git a/pallets/liquidity-mining/Cargo.toml b/pallets/liquidity-mining/Cargo.toml index f49cd3f62..b4b5337bb 100644 --- a/pallets/liquidity-mining/Cargo.toml +++ b/pallets/liquidity-mining/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-liquidity-mining" -version = "4.2.4" +version = "4.3.0" description = "Liquidity mining" authors = ["GalacticCouncil"] edition = "2021" @@ -55,5 +55,7 @@ std = [ "sp-runtime/std", "scale-info/std", "hydra-dx-math/std", + "pallet-balances/std", + "orml-tokens/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/liquidity-mining/src/lib.rs b/pallets/liquidity-mining/src/lib.rs index 70384b119..55e0d99c6 100644 --- a/pallets/liquidity-mining/src/lib.rs +++ b/pallets/liquidity-mining/src/lib.rs @@ -115,7 +115,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use sp_runtime::ArithmeticError; use hydra_dx_math::liquidity_mining as math; -use hydradx_traits::{liquidity_mining::PriceAdjustment, pools::DustRemovalAccountWhitelist, registry::Registry}; +use hydradx_traits::{liquidity_mining::PriceAdjustment, pools::DustRemovalAccountWhitelist, registry::Inspect}; use orml_traits::{GetByKey, MultiCurrency}; use scale_info::TypeInfo; use sp_arithmetic::{ @@ -209,7 +209,7 @@ pub mod pallet { /// Asset Registry - used to check if asset is correctly registered in asset registry and /// provides information about existential deposit of the asset. - type AssetRegistry: Registry, Balance, DispatchError> + GetByKey; + type AssetRegistry: Inspect + GetByKey; /// Account whitelist manager to exclude pool accounts from dusting mechanism. type NonDustableWhitelistHandler: DustRemovalAccountWhitelist; diff --git a/pallets/liquidity-mining/src/tests/mock.rs b/pallets/liquidity-mining/src/tests/mock.rs index f958404b3..356a0dd0e 100644 --- a/pallets/liquidity-mining/src/tests/mock.rs +++ b/pallets/liquidity-mining/src/tests/mock.rs @@ -27,7 +27,7 @@ use frame_support::{ PalletId, }; use frame_system as system; -use hydradx_traits::{pools::DustRemovalAccountWhitelist, registry::Registry, AssetKind, AMM}; +use hydradx_traits::{pools::DustRemovalAccountWhitelist, registry::Inspect, AssetKind, AMM}; use orml_traits::GetByKey; use sp_core::H256; use sp_runtime::{ @@ -293,7 +293,7 @@ impl Config for Test { type MaxFarmEntriesPerDeposit = MaxEntriesPerDeposit; type MaxYieldFarmsPerGlobalFarm = MaxYieldFarmsPerGlobalFarm; type NonDustableWhitelistHandler = Whitelist; - type AssetRegistry = AssetRegistry; + type AssetRegistry = DummyRegistry; type PriceAdjustment = DefaultPriceAdjustment; } @@ -317,7 +317,7 @@ impl Config for Test { type MaxFarmEntriesPerDeposit = MaxEntriesPerDeposit2; type MaxYieldFarmsPerGlobalFarm = MaxYieldFarmsPerGlobalFarm; type NonDustableWhitelistHandler = Whitelist; - type AssetRegistry = AssetRegistry; + type AssetRegistry = DummyRegistry; type PriceAdjustment = DefaultPriceAdjustment; } @@ -337,7 +337,7 @@ impl Config for Test { type MaxFarmEntriesPerDeposit = MaxEntriesPerDeposit; type MaxYieldFarmsPerGlobalFarm = MaxYieldFarmsPerGlobalFarm; type NonDustableWhitelistHandler = Whitelist; - type AssetRegistry = AssetRegistry; + type AssetRegistry = DummyRegistry; type PriceAdjustment = DummyOraclePriceAdjustment; } @@ -365,7 +365,7 @@ impl orml_tokens::Config for Test { type Amount = Amount; type CurrencyId = AssetId; type WeightInfo = (); - type ExistentialDeposits = AssetRegistry; + type ExistentialDeposits = DummyRegistry; type MaxLocks = MaxLocks; type DustRemovalWhitelist = Whitelist; type MaxReserves = ConstU32<100_000>; @@ -429,31 +429,30 @@ impl DustRemovalAccountWhitelist for Whitelist { } } -pub struct AssetRegistry; +pub struct DummyRegistry; -impl Registry, Balance, DispatchError> for AssetRegistry { - fn exists(name: AssetId) -> bool { - name != UNKNOWN_ASSET - } +impl Inspect for DummyRegistry { + type AssetId = AssetId; + type Location = u8; - fn retrieve_asset(_name: &Vec) -> Result { - Err(sp_runtime::DispatchError::Other("NotImplemented")) + fn is_sufficient(_id: Self::AssetId) -> bool { + unimplemented!() } - fn retrieve_asset_type(_asset_id: AssetId) -> Result { + fn decimals(_id: Self::AssetId) -> Option { unimplemented!() } - fn create_asset(_name: &Vec, _existential_deposit: Balance) -> Result { - Err(sp_runtime::DispatchError::Other("NotImplemented")) + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() } - fn get_or_create_asset(_name: Vec, _existential_deposit: Balance) -> Result { - Err(sp_runtime::DispatchError::Other("NotImplemented")) + fn exists(name: AssetId) -> bool { + name != UNKNOWN_ASSET } } -impl GetByKey for AssetRegistry { +impl GetByKey for DummyRegistry { fn get(_key: &AssetId) -> Balance { 1_000_u128 } diff --git a/pallets/omnipool-liquidity-mining/Cargo.toml b/pallets/omnipool-liquidity-mining/Cargo.toml index a327bf927..c8c9d55b8 100644 --- a/pallets/omnipool-liquidity-mining/Cargo.toml +++ b/pallets/omnipool-liquidity-mining/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-omnipool-liquidity-mining" -version = "2.0.11" +version = "2.1.0" authors = ['GalacticCouncil'] edition = "2021" license = "Apache-2.0" @@ -40,7 +40,6 @@ hydra-dx-math = { workspace = true } # third party primitive-types = { version = "0.12.0", default-features = false } -bitflags = "1.3.2" # Optional imports for benchmarking frame-benchmarking = { workspace = true, optional = true } @@ -60,17 +59,20 @@ test-utils = { workspace = true } default = ["std"] std = [ "codec/std", + "scale-info/std", "sp-runtime/std", "sp-std/std", "frame-support/std", "frame-system/std", - "scale-info/std", "sp-core/std", "sp-io/std", "pallet-balances/std", "orml-tokens/std", - "pallet-omnipool/std", + "pallet-omnipool/std", "pallet-liquidity-mining/std", + "pallet-ema-oracle/std", + "hydra-dx-math/std", + "primitives/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/pallets/omnipool-liquidity-mining/src/benchmarks.rs b/pallets/omnipool-liquidity-mining/src/benchmarks.rs index 5132a6f0c..bcd7f299a 100644 --- a/pallets/omnipool-liquidity-mining/src/benchmarks.rs +++ b/pallets/omnipool-liquidity-mining/src/benchmarks.rs @@ -17,12 +17,14 @@ use crate::*; use frame_benchmarking::{account, benchmarks}; +use frame_support::storage::with_transaction; use frame_support::traits::{OnFinalize, OnInitialize}; use frame_system::{Pallet as System, RawOrigin}; -use hydradx_traits::Registry; +use hydradx_traits::registry::{AssetKind, Create}; use orml_traits::MultiCurrencyExtended; use pallet_liquidity_mining::Instance1; use primitives::AssetId; +use sp_runtime::TransactionOutcome; use sp_runtime::{traits::One, FixedU128, Permill}; const TVL_CAP: Balance = 222_222_000_000_000_000_000_000; @@ -94,6 +96,8 @@ where ::Currency: MultiCurrencyExtended, T: pallet_ema_oracle::Config, T::AssetId: From, + ::AssetRegistry: Create, + <::AssetRegistry as hydradx_traits::Inspect>::AssetId: From, { let stable_amount: Balance = 1_000_000_000_000_000_u128; let native_amount: Balance = 1_000_000_000_000_000_u128; @@ -103,6 +107,7 @@ where OmnipoolPallet::::set_tvl_cap(RawOrigin::Root.into(), TVL_CAP)?; + fund::(acc.clone(), HDX.into(), 10_000 * ONE)?; ::Currency::update_balance(T::StableCoinAssetId::get(), &acc, stable_amount as i128)?; ::Currency::update_balance(T::HdxAssetId::get(), &acc, native_amount as i128)?; @@ -115,9 +120,42 @@ where )?; // Register new asset in asset registry - T::AssetRegistry::create_asset(&b"BSX".to_vec(), Balance::one())?; - T::AssetRegistry::create_asset(&b"ETH".to_vec(), Balance::one())?; - T::AssetRegistry::create_asset(&b"BTC".to_vec(), Balance::one())?; + with_transaction(|| { + TransactionOutcome::Commit(T::AssetRegistry::register_sufficient_asset( + None, + Some(b"BSX".as_ref()), + AssetKind::Token, + Balance::one(), + None, + None, + None, + None, + )) + })?; + with_transaction(|| { + TransactionOutcome::Commit(T::AssetRegistry::register_sufficient_asset( + None, + Some(b"ETH".as_ref()), + AssetKind::Token, + Balance::one(), + None, + None, + None, + None, + )) + })?; + with_transaction(|| { + TransactionOutcome::Commit(T::AssetRegistry::register_sufficient_asset( + None, + Some(b"BTC".as_ref()), + AssetKind::Token, + Balance::one(), + None, + None, + None, + None, + )) + })?; // Create account for token provider and set balance let owner: T::AccountId = account("owner", 0, 1); @@ -228,6 +266,7 @@ benchmarks! { ::AssetId: From, ::Currency: MultiCurrencyExtended, T: crate::pallet::Config + pallet_ema_oracle::Config + pallet_liquidity_mining::Config, + ::AssetRegistry: Create::AssetId>, } create_global_farm { diff --git a/pallets/omnipool-liquidity-mining/src/tests/mock.rs b/pallets/omnipool-liquidity-mining/src/tests/mock.rs index d1627a73d..2fe4bf781 100644 --- a/pallets/omnipool-liquidity-mining/src/tests/mock.rs +++ b/pallets/omnipool-liquidity-mining/src/tests/mock.rs @@ -169,7 +169,7 @@ parameter_types! { pub const OracleSource: Source = *b"omnipool"; } -impl Config for Test { +impl omnipool_liquidity_mining::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Tokens; type CreateOrigin = frame_system::EnsureRoot; @@ -636,28 +636,55 @@ impl Transfer for DummyNFT { } } -use hydradx_traits::Registry; +use hydradx_traits::Inspect as InspectRegistry; pub struct DummyRegistry(sp_std::marker::PhantomData); -impl Registry, Balance, DispatchError> for DummyRegistry +impl InspectRegistry for DummyRegistry where T::AssetId: Into + From, { - fn exists(asset_id: T::AssetId) -> bool { - let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); - matches!(asset, Some(_)) + type AssetId = T::AssetId; + type Location = u8; + + fn is_sufficient(_id: Self::AssetId) -> bool { + unimplemented!() } - fn retrieve_asset(_name: &Vec) -> Result { - Ok(T::AssetId::default()) + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() } - fn retrieve_asset_type(_asset_id: T::AssetId) -> Result { + fn decimals(_id: Self::AssetId) -> Option { unimplemented!() } - fn create_asset(_name: &Vec, _existential_deposit: Balance) -> Result { + fn exists(asset_id: T::AssetId) -> bool { + let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); + matches!(asset, Some(_)) + } +} + +#[cfg(feature = "runtime-benchmarks")] +use hydradx_traits::Create as CreateRegistry; +#[cfg(feature = "runtime-benchmarks")] +impl CreateRegistry for DummyRegistry +where + T::AssetId: Into + From, +{ + type Error = DispatchError; + + fn register_asset( + _asset_id: Option, + _name: Option<&[u8]>, + _kind: AssetKind, + _existential_deposit: Option, + _symbol: Option<&[u8]>, + _decimals: Option, + _location: Option, + _xcm_rate_limit: Option, + _is_sufficient: bool, + ) -> Result { let assigned = REGISTERED_ASSETS.with(|v| { //NOTE: This is to have same ids as real AssetRegistry which is used in the benchmarks. //1_000_000 - offset of the reals AssetRegistry @@ -670,6 +697,19 @@ where }); Ok(T::AssetId::from(assigned)) } + + fn get_or_register_asset( + _name: &[u8], + _kind: AssetKind, + _existential_deposit: Option, + _symbol: Option<&[u8]>, + _decimals: Option, + _location: Option, + _xcm_rate_limit: Option, + _is_sufficient: bool, + ) -> Result { + unimplemented!() + } } use hydradx_traits::oracle::AggregatedPriceOracle; diff --git a/pallets/omnipool/Cargo.toml b/pallets/omnipool/Cargo.toml index 7bf8a892d..dd64f492b 100644 --- a/pallets/omnipool/Cargo.toml +++ b/pallets/omnipool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-omnipool" -version = "3.2.3" +version = "3.3.0" authors = ['GalacticCouncil'] edition = "2021" license = "Apache-2.0" diff --git a/pallets/omnipool/src/lib.rs b/pallets/omnipool/src/lib.rs index 586ff528e..aaf807def 100644 --- a/pallets/omnipool/src/lib.rs +++ b/pallets/omnipool/src/lib.rs @@ -79,7 +79,7 @@ use sp_std::prelude::*; use frame_support::traits::tokens::nonfungibles::{Create, Inspect, Mutate}; use hydra_dx_math::omnipool::types::{AssetStateChange, BalanceUpdate, I129}; -use hydradx_traits::Registry; +use hydradx_traits::registry::Inspect as RegistryInspect; use orml_traits::{GetByKey, MultiCurrency}; use scale_info::TypeInfo; use sp_runtime::{ArithmeticError, DispatchError, FixedPointNumber, FixedU128, Permill}; @@ -145,7 +145,7 @@ pub mod pallet { type TechnicalOrigin: EnsureOrigin; /// Asset Registry mechanism - used to check if asset is correctly registered in asset registry - type AssetRegistry: Registry, Balance, DispatchError>; + type AssetRegistry: RegistryInspect; /// Native Asset ID #[pallet::constant] diff --git a/pallets/omnipool/src/tests/mock.rs b/pallets/omnipool/src/tests/mock.rs index 637d50797..ccbcb7119 100644 --- a/pallets/omnipool/src/tests/mock.rs +++ b/pallets/omnipool/src/tests/mock.rs @@ -31,7 +31,7 @@ use frame_support::{ traits::{ConstU32, ConstU64}, }; use frame_system::EnsureRoot; -use hydradx_traits::{AssetKind, Registry}; +use hydradx_traits::{registry::Inspect as InspectRegistry, AssetKind}; use orml_traits::parameter_type_with_key; use primitive_types::{U128, U256}; use sp_core::H256; @@ -515,30 +515,28 @@ impl + Into + Copy> Mutate for DummyNFT { pub struct DummyRegistry(sp_std::marker::PhantomData); -impl Registry, Balance, DispatchError> for DummyRegistry +impl InspectRegistry for DummyRegistry where T::AssetId: Into + From, { + type AssetId = T::AssetId; + type Location = u8; + + fn is_sufficient(_id: Self::AssetId) -> bool { + unimplemented!() + } + fn exists(asset_id: T::AssetId) -> bool { let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); matches!(asset, Some(_)) } - fn retrieve_asset(_name: &Vec) -> Result { - Ok(T::AssetId::default()) - } - - fn retrieve_asset_type(_asset_id: T::AssetId) -> Result { + fn decimals(_id: Self::AssetId) -> Option { unimplemented!() } - fn create_asset(_name: &Vec, _existential_deposit: Balance) -> Result { - let assigned = REGISTERED_ASSETS.with(|v| { - let l = v.borrow().len(); - v.borrow_mut().insert(l as u32, l as u32); - l as u32 - }); - Ok(T::AssetId::from(assigned)) + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() } } diff --git a/pallets/otc/Cargo.toml b/pallets/otc/Cargo.toml index 37ef5ef91..e27a5b5b3 100644 --- a/pallets/otc/Cargo.toml +++ b/pallets/otc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-otc' -version = '1.0.2' +version = '1.1.0' description = 'A pallet for trustless over-the-counter trading' authors = ['GalacticCouncil'] edition = '2021' @@ -51,6 +51,7 @@ std = [ "scale-info/std", "orml-tokens/std", "hydradx-traits/std", + "frame-benchmarking/std" ] runtime-benchmarks = [ diff --git a/pallets/otc/src/benchmarks.rs b/pallets/otc/src/benchmarks.rs index 0e494de05..19901ea9b 100644 --- a/pallets/otc/src/benchmarks.rs +++ b/pallets/otc/src/benchmarks.rs @@ -17,9 +17,10 @@ use super::*; use frame_benchmarking::{account, benchmarks}; use frame_support::assert_ok; use frame_system::RawOrigin; -use hydradx_traits::Registry; +use hydradx_traits::{AssetKind, Create}; use orml_traits::MultiCurrencyExtended; use sp_std::vec; +use sp_std::vec::Vec; pub const ONE: Balance = 1_000_000_000_000; benchmarks! { @@ -28,66 +29,93 @@ benchmarks! { T::Currency: MultiCurrencyExtended, T: crate::pallet::Config, u32: From<::AssetId>, + T::AssetRegistry: Create } place_order { - let (hdx, dai) = seed_registry::()?; + let (dot, dai) = seed_registry::()?; - let owner: T::AccountId = create_account_with_balances::("owner", 1, vec!(hdx, dai))?; - }: _(RawOrigin::Signed(owner.clone()), dai.into(), hdx.into(), 20 * ONE, 100 * ONE, true) + let owner: T::AccountId = create_account_with_balances::("owner", 1, vec!(dot, dai))?; + }: _(RawOrigin::Signed(owner.clone()), dai.into(), dot.into(), 20 * ONE, 100 * ONE, true) verify { - assert_eq!(T::Currency::reserved_balance_named(&NAMED_RESERVE_ID, hdx.into(), &owner), 100 * ONE); + assert_eq!(T::Currency::reserved_balance_named(&NAMED_RESERVE_ID, dot.into(), &owner), 100 * ONE); } partial_fill_order { - let (hdx, dai) = seed_registry::()?; + let (dot, dai) = seed_registry::()?; - let owner: T::AccountId = create_account_with_balances::("owner", 1, vec!(hdx, dai))?; - let filler: T::AccountId = create_account_with_balances::("filler", 2, vec!(hdx, dai))?; + let owner: T::AccountId = create_account_with_balances::("owner", 1, vec!(dot, dai))?; + let filler: T::AccountId = create_account_with_balances::("filler", 2, vec!(dot, dai))?; assert_ok!( - crate::Pallet::::place_order(RawOrigin::Signed(owner.clone()).into(), dai.into(), hdx.into(), 20 * ONE, 100 * ONE, true) + crate::Pallet::::place_order(RawOrigin::Signed(owner.clone()).into(), dai.into(), dot.into(), 20 * ONE, 100 * ONE, true) ); }: _(RawOrigin::Signed(filler.clone()), 0u32, 10 * ONE) verify { - assert_eq!(T::Currency::reserved_balance_named(&NAMED_RESERVE_ID, hdx.into(), &owner), 50 * ONE); + assert_eq!(T::Currency::reserved_balance_named(&NAMED_RESERVE_ID, dot.into(), &owner), 50 * ONE); } fill_order { - let (hdx, dai) = seed_registry::()?; + let (dot, dai) = seed_registry::()?; - let owner: T::AccountId = create_account_with_balances::("owner", 1, vec!(hdx, dai))?; - let filler: T::AccountId = create_account_with_balances::("filler", 2, vec!(hdx, dai))?; + let owner: T::AccountId = create_account_with_balances::("owner", 1, vec!(dot, dai))?; + let filler: T::AccountId = create_account_with_balances::("filler", 2, vec!(dot, dai))?; assert_ok!( - crate::Pallet::::place_order(RawOrigin::Signed(owner.clone()).into(), dai.into(), hdx.into(), 20 * ONE, 100 * ONE, true) + crate::Pallet::::place_order(RawOrigin::Signed(owner.clone()).into(), dai.into(), dot.into(), 20 * ONE, 100 * ONE, true) ); }: _(RawOrigin::Signed(filler.clone()), 0u32) verify { - assert_eq!(T::Currency::reserved_balance_named(&NAMED_RESERVE_ID, hdx.into(), &owner), 0); + assert_eq!(T::Currency::reserved_balance_named(&NAMED_RESERVE_ID, dot.into(), &owner), 0); } cancel_order { - let (hdx, dai) = seed_registry::()?; + let (dot, dai) = seed_registry::()?; - let owner: T::AccountId = create_account_with_balances::("owner", 1, vec!(hdx, dai))?; + let owner: T::AccountId = create_account_with_balances::("owner", 1, vec!(dot, dai))?; assert_ok!( - crate::Pallet::::place_order(RawOrigin::Signed(owner.clone()).into(), dai.into(), hdx.into(), 20 * ONE, 100 * ONE, true) + crate::Pallet::::place_order(RawOrigin::Signed(owner.clone()).into(), dai.into(), dot.into(), 20 * ONE, 100 * ONE, true) ); }: _(RawOrigin::Signed(owner.clone()), 0u32) verify { - assert_eq!(T::Currency::reserved_balance_named(&NAMED_RESERVE_ID, hdx.into(), &owner), 0); + assert_eq!(T::Currency::reserved_balance_named(&NAMED_RESERVE_ID, dot.into(), &owner), 0); } } fn seed_registry() -> Result<(u32, u32), DispatchError> where u32: From<::AssetId>, + T::AssetRegistry: Create, { - // Register new asset in asset registry - let hdx = T::AssetRegistry::create_asset(&b"HDX".to_vec(), ONE)?; - let dai = T::AssetRegistry::create_asset(&b"DAI".to_vec(), ONE)?; + use frame_support::storage::with_transaction; + use sp_runtime::TransactionOutcome; - Ok((hdx.into(), dai.into())) + // Register new asset in asset registry + let dot = with_transaction(|| { + TransactionOutcome::Commit(::AssetRegistry::register_sufficient_asset( + None, + Some(b"DOT".as_ref()), + AssetKind::Token, + ONE, + None, + None, + None, + None, + )) + })?; + let dai = with_transaction(|| { + TransactionOutcome::Commit(::AssetRegistry::register_sufficient_asset( + None, + Some(b"DAI".as_ref()), + AssetKind::Token, + ONE, + None, + None, + None, + None, + )) + })?; + + Ok((dot.into(), dai.into())) } fn create_account_with_balances( diff --git a/pallets/otc/src/lib.rs b/pallets/otc/src/lib.rs index 0926af109..09cd45333 100644 --- a/pallets/otc/src/lib.rs +++ b/pallets/otc/src/lib.rs @@ -36,14 +36,11 @@ use codec::MaxEncodedLen; use frame_support::{pallet_prelude::*, require_transactional}; use frame_system::{ensure_signed, pallet_prelude::OriginFor}; -use hydradx_traits::Registry; +use hydradx_traits::Inspect; use orml_traits::{GetByKey, MultiCurrency, NamedMultiReservableCurrency}; use sp_core::U256; -use sp_runtime::{ - traits::{One, Zero}, - DispatchError, -}; -use sp_std::vec::Vec; +use sp_runtime::traits::{One, Zero}; + #[cfg(test)] mod tests; @@ -88,7 +85,7 @@ pub mod pallet { type AssetId: Member + Parameter + Copy + HasCompact + MaybeSerializeDeserialize + MaxEncodedLen; /// Asset Registry mechanism - used to check if asset is correctly registered in asset registry - type AssetRegistry: Registry, Balance, DispatchError>; + type AssetRegistry: Inspect; /// Named reservable multi currency type Currency: NamedMultiReservableCurrency< diff --git a/pallets/otc/src/tests/mock.rs b/pallets/otc/src/tests/mock.rs index 04651cf11..e86a35108 100644 --- a/pallets/otc/src/tests/mock.rs +++ b/pallets/otc/src/tests/mock.rs @@ -20,14 +20,13 @@ use frame_support::{ traits::{Everything, GenesisBuild, Nothing}, }; use frame_system as system; -use hydradx_traits::{AssetKind, Registry}; +use hydradx_traits::{registry::Inspect, AssetKind}; use orml_tokens::AccountData; use orml_traits::parameter_type_with_key; use sp_core::H256; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, - DispatchError, }; use std::{cell::RefCell, collections::HashMap}; @@ -79,7 +78,7 @@ parameter_type_with_key! { }; } -impl Config for Test { +impl otc::Config for Test { type AssetId = AssetId; type AssetRegistry = DummyRegistry; type Currency = Tokens; @@ -138,28 +137,75 @@ impl orml_tokens::Config for Test { pub struct DummyRegistry(sp_std::marker::PhantomData); -impl Registry, Balance, DispatchError> for DummyRegistry { - fn exists(asset_id: AssetId) -> bool { - let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id)).copied()); - matches!(asset, Some(_)) +impl Inspect for DummyRegistry { + type AssetId = AssetId; + type Location = u8; + + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() } - fn retrieve_asset(_name: &Vec) -> Result { - Ok(0) + fn decimals(_id: Self::AssetId) -> Option { + unimplemented!() } - fn retrieve_asset_type(_asset_id: AssetId) -> Result { + fn is_sufficient(_id: Self::AssetId) -> bool { unimplemented!() } - fn create_asset(_name: &Vec, _existential_deposit: Balance) -> Result { + fn exists(asset_id: AssetId) -> bool { + let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id)).copied()); + matches!(asset, Some(_)) + } +} + +#[cfg(feature = "runtime-benchmarks")] +use hydradx_traits::Create as CreateRegistry; +#[cfg(feature = "runtime-benchmarks")] +use sp_runtime::DispatchError; +#[cfg(feature = "runtime-benchmarks")] +impl CreateRegistry for DummyRegistry +where + T::AssetId: Into + From, +{ + type Error = DispatchError; + + fn register_asset( + _asset_id: Option, + _name: Option<&[u8]>, + _kind: AssetKind, + _existential_deposit: Option, + _symbol: Option<&[u8]>, + _decimals: Option, + _location: Option, + _xcm_rate_limit: Option, + _is_sufficient: bool, + ) -> Result { let assigned = REGISTERED_ASSETS.with(|v| { - let l = v.borrow().len(); + //NOTE: This is to have same ids as real AssetRegistry which is used in the benchmarks. + //1_000_000 - offset of the reals AssetRegistry + // - 3 - remove assets reagistered by default for the vec.len() + // +1 - first reg asset start with 1 not 0 + // => 1-th asset id == 1_000_001 + let l = 1_000_000 - 3 + 1 + v.borrow().len(); v.borrow_mut().insert(l as u32, l as u32); l as u32 }); Ok(assigned) } + + fn get_or_register_asset( + _name: &[u8], + _kind: AssetKind, + _existential_deposit: Option, + _symbol: Option<&[u8]>, + _decimals: Option, + _location: Option, + _xcm_rate_limit: Option, + _is_sufficient: bool, + ) -> Result { + unimplemented!() + } } pub struct ExtBuilder { diff --git a/pallets/stableswap/Cargo.toml b/pallets/stableswap/Cargo.toml index 3025cbcc1..54e1a085d 100644 --- a/pallets/stableswap/Cargo.toml +++ b/pallets/stableswap/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-stableswap' -version = '3.3.1' +version = '3.4.0' description = 'AMM for correlated assets' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/stableswap/src/lib.rs b/pallets/stableswap/src/lib.rs index 77f98ddaf..415f6e842 100644 --- a/pallets/stableswap/src/lib.rs +++ b/pallets/stableswap/src/lib.rs @@ -44,7 +44,7 @@ extern crate core; use frame_support::pallet_prelude::{DispatchResult, Get}; use frame_support::{ensure, require_transactional, transactional}; -use hydradx_traits::{registry::InspectRegistry, AccountIdFor}; +use hydradx_traits::{registry::Inspect, AccountIdFor}; pub use pallet::*; use sp_runtime::traits::{BlockNumberProvider, Zero}; use sp_runtime::{ArithmeticError, DispatchError, Permill, SaturatedConversion}; @@ -126,7 +126,7 @@ pub mod pallet { type ShareAccountId: AccountIdFor; /// Asset registry mechanism - type AssetInspection: InspectRegistry; + type AssetInspection: Inspect; /// The origin which can create a new pool type AuthorityOrigin: EnsureOrigin; diff --git a/pallets/stableswap/src/tests/mock.rs b/pallets/stableswap/src/tests/mock.rs index c357cc019..5de7148cf 100644 --- a/pallets/stableswap/src/tests/mock.rs +++ b/pallets/stableswap/src/tests/mock.rs @@ -311,12 +311,15 @@ impl ExtBuilder { use crate::types::BenchmarkHelper; use crate::types::{AssetAmount, PoolInfo, PoolState, StableswapHooks}; use hydradx_traits::pools::DustRemovalAccountWhitelist; -use hydradx_traits::{AccountIdFor, InspectRegistry}; +use hydradx_traits::{AccountIdFor, Inspect}; use sp_runtime::traits::Zero; pub struct DummyRegistry; -impl InspectRegistry for DummyRegistry { +impl Inspect for DummyRegistry { + type AssetId = AssetId; + type Location = u8; + fn exists(asset_id: AssetId) -> bool { let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&asset_id).copied()); matches!(asset, Some(_)) @@ -326,6 +329,14 @@ impl InspectRegistry for DummyRegistry { let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&asset_id).copied())?; Some(asset.1) } + + fn is_sufficient(_id: Self::AssetId) -> bool { + unimplemented!() + } + + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() + } } #[cfg(feature = "runtime-benchmarks")] diff --git a/pallets/staking/Cargo.toml b/pallets/staking/Cargo.toml index 0babe26ba..eab963ba8 100644 --- a/pallets/staking/Cargo.toml +++ b/pallets/staking/Cargo.toml @@ -58,7 +58,7 @@ std = [ "pallet-democracy/std", ] runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", + "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", diff --git a/pallets/xcm-rate-limiter/src/tests/mock.rs b/pallets/xcm-rate-limiter/src/tests/mock.rs index a038c5a8f..89475ca18 100644 --- a/pallets/xcm-rate-limiter/src/tests/mock.rs +++ b/pallets/xcm-rate-limiter/src/tests/mock.rs @@ -309,35 +309,33 @@ impl + Into + Copy> Mutate for DummyNFT { } use crate::Config; -use hydradx_traits::{AssetKind, Registry}; +use hydradx_traits::registry::{AssetKind, Inspect as InspectRegistry}; use pallet_omnipool::traits::ExternalPriceProvider; pub struct DummyRegistry(sp_std::marker::PhantomData); -impl Registry, Balance, DispatchError> for DummyRegistry +impl InspectRegistry for DummyRegistry where T::AssetId: Into + From, { - fn exists(asset_id: T::AssetId) -> bool { - let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); - matches!(asset, Some(_)) + type AssetId = T::AssetId; + type Location = MultiLocation; + + fn is_sufficient(_id: Self::AssetId) -> bool { + unimplemented!() } - fn retrieve_asset(_name: &Vec) -> Result { - Ok(T::AssetId::default()) + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() } - fn retrieve_asset_type(_asset_id: T::AssetId) -> Result { + fn decimals(_id: Self::AssetId) -> Option { unimplemented!() } - fn create_asset(_name: &Vec, _existential_deposit: Balance) -> Result { - let assigned = REGISTERED_ASSETS.with(|v| { - let l = v.borrow().len(); - v.borrow_mut().insert(l as u32, l as u32); - l as u32 - }); - Ok(T::AssetId::from(assigned)) + fn exists(asset_id: T::AssetId) -> bool { + let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); + matches!(asset, Some(_)) } } diff --git a/pallets/xyk/Cargo.toml b/pallets/xyk/Cargo.toml index 0bb2fac5d..32aa28c38 100644 --- a/pallets/xyk/Cargo.toml +++ b/pallets/xyk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'pallet-xyk' -version = "6.3.0" +version = "6.4.0" description = 'XYK automated market maker' authors = ['GalacticCouncil'] edition = '2021' diff --git a/pallets/xyk/src/lib.rs b/pallets/xyk/src/lib.rs index a53812719..9fbfedf59 100644 --- a/pallets/xyk/src/lib.rs +++ b/pallets/xyk/src/lib.rs @@ -64,7 +64,10 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::OriginFor; - use hydradx_traits::{pools::DustRemovalAccountWhitelist, registry::ShareTokenRegistry}; + use hydradx_traits::{ + pools::DustRemovalAccountWhitelist, + registry::{AssetKind, Create}, + }; #[pallet::pallet] pub struct Pallet(_); @@ -77,7 +80,7 @@ pub mod pallet { type RuntimeEvent: From> + IsType<::RuntimeEvent>; /// Registry support - type AssetRegistry: ShareTokenRegistry, Balance, DispatchError>; + type AssetRegistry: Create; /// Share token support type AssetPairAccountId: AssetPairAccountIdFor; @@ -344,10 +347,14 @@ pub mod pallet { let token_name = asset_pair.name(); - let share_token = T::AssetRegistry::get_or_create_shared_asset( - token_name, - vec![asset_a, asset_b], - T::MinPoolLiquidity::get(), + let share_token = T::AssetRegistry::get_or_register_insufficient_asset( + &token_name, + AssetKind::XYK, + None, + None, + None, + None, + None, )?; let _ = T::AMMHandler::on_create_pool(asset_pair.asset_in, asset_pair.asset_out); diff --git a/pallets/xyk/src/tests/creation.rs b/pallets/xyk/src/tests/creation.rs index bb79457e4..d5e6ad95f 100644 --- a/pallets/xyk/src/tests/creation.rs +++ b/pallets/xyk/src/tests/creation.rs @@ -1,7 +1,6 @@ pub use super::mock::*; use crate::{Error, Event}; use frame_support::{assert_noop, assert_ok, BoundedVec}; -use hydradx_traits::Registry; use hydradx_traits::AMM as AmmPool; use orml_traits::MultiCurrency; use pallet_asset_registry::AssetType; @@ -45,8 +44,8 @@ fn create_pool_should_work() { pallet_asset_registry::Event::Registered { asset_id: share_token, asset_name: Some(bounded_name), - asset_type: AssetType::PoolShare(HDX, ACA), - existential_deposit: ::MinPoolLiquidity::get(), + asset_type: AssetType::XYK, + existential_deposit: pallet_asset_registry::DEFAULT_ED, xcm_rate_limit: None, symbol: None, decimals: None, @@ -381,7 +380,7 @@ fn share_asset_id_should_be_offset() { RuntimeOrigin::signed(ALICE), Some(next_asset_id), Some(asset_pair.name()), - AssetType::PoolShare(HDX, ACA), + AssetType::XYK, Some(::MinPoolLiquidity::get()), None, None, @@ -403,7 +402,10 @@ fn share_asset_id_should_be_offset() { let share_token = XYK::share_token(pair_account); assert_eq!(share_token, next_asset_id); - assert_eq!(AssetRegistry::retrieve_asset(&asset_pair.name()).unwrap(), share_token); + let bounded_name = AssetRegistry::try_into_bounded(Some(asset_pair.name())) + .unwrap() + .unwrap(); + assert_eq!(AssetRegistry::asset_ids(bounded_name).unwrap(), share_token); // Act let next_asset_id = AssetRegistry::next_asset_id().unwrap(); @@ -427,6 +429,9 @@ fn share_asset_id_should_be_offset() { // Assert assert_eq!(share_token, next_asset_id); - assert_eq!(AssetRegistry::retrieve_asset(&asset_pair.name()).unwrap(), share_token); + let bounded_name = AssetRegistry::try_into_bounded(Some(asset_pair.name())) + .unwrap() + .unwrap(); + assert_eq!(AssetRegistry::asset_ids(bounded_name).unwrap(), share_token); }); } diff --git a/pallets/xyk/src/tests/mock.rs b/pallets/xyk/src/tests/mock.rs index c339dd8c9..22e59f666 100644 --- a/pallets/xyk/src/tests/mock.rs +++ b/pallets/xyk/src/tests/mock.rs @@ -16,7 +16,6 @@ // limitations under the License. use crate as xyk; -use crate::Config; use crate::*; use frame_support::parameter_types; use frame_system as system; @@ -54,6 +53,8 @@ pub const ONE: Balance = 1_000_000_000_000; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; +type AssetLocation = u8; + frame_support::construct_runtime!( pub enum Test where Block = Block, @@ -112,7 +113,7 @@ impl pallet_asset_registry::Config for Test { type Currency = Currency; type UpdateOrigin = EnsureSigned; type AssetId = AssetId; - type AssetNativeLocation = u8; + type AssetNativeLocation = AssetLocation; type StringLimit = RegistryStringLimit; type SequentialIdStartAt = SequentialIdOffset; type StorageFeesAssetId = NativeAssetId; @@ -199,7 +200,7 @@ impl CanCreatePool for Disallow10_10Pool { } } -impl Config for Test { +impl xyk::Config for Test { type RuntimeEvent = RuntimeEvent; type AssetRegistry = AssetRegistry; type AssetPairAccountId = AssetPairAccountIdTest; diff --git a/runtime/adapters/src/tests/mock.rs b/runtime/adapters/src/tests/mock.rs index 3dddb08a2..077e288ad 100644 --- a/runtime/adapters/src/tests/mock.rs +++ b/runtime/adapters/src/tests/mock.rs @@ -27,7 +27,7 @@ use frame_support::{ traits::{ConstU32, ConstU64}, }; use frame_system::EnsureRoot; -use hydradx_traits::{AssetKind, Registry}; +use hydradx_traits::{AssetKind, Inspect as InspectRegistry}; use orml_traits::{parameter_type_with_key, GetByKey}; use pallet_currencies::BasicCurrencyAdapter; use pallet_omnipool; @@ -538,30 +538,28 @@ impl + Into + Copy> Mutate for DummyNFT { pub struct DummyRegistry(sp_std::marker::PhantomData); -impl Registry, Balance, DispatchError> for DummyRegistry +impl InspectRegistry for DummyRegistry where T::AssetId: Into + From, { - fn exists(asset_id: T::AssetId) -> bool { - let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id.into())).copied()); - matches!(asset, Some(_)) + type AssetId = AssetId; + type Location = u8; + + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() } - fn retrieve_asset(_name: &Vec) -> Result { - Ok(T::AssetId::default()) + fn decimals(_id: Self::AssetId) -> Option { + unimplemented!() } - fn retrieve_asset_type(_asset_id: T::AssetId) -> Result { + fn is_sufficient(_id: Self::AssetId) -> bool { unimplemented!() } - fn create_asset(_name: &Vec, _existential_deposit: Balance) -> Result { - let assigned = REGISTERED_ASSETS.with(|v| { - let l = v.borrow().len(); - v.borrow_mut().insert(l as u32, l as u32); - l as u32 - }); - Ok(T::AssetId::from(assigned)) + fn exists(asset_id: AssetId) -> bool { + let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id)).copied()); + matches!(asset, Some(_)) } } diff --git a/runtime/hydradx/src/assets.rs b/runtime/hydradx/src/assets.rs index 1394f5b5b..42ce02472 100644 --- a/runtime/hydradx/src/assets.rs +++ b/runtime/hydradx/src/assets.rs @@ -933,7 +933,7 @@ impl BenchmarkHelper for RegisterAsse Some(asset_id), Some(&asset_name), AssetKind::Token, - Some(1), + 1, Some(&asset_name), Some(decimals), None, diff --git a/runtime/hydradx/src/benchmarking/mod.rs b/runtime/hydradx/src/benchmarking/mod.rs index 306a45c54..849234096 100644 --- a/runtime/hydradx/src/benchmarking/mod.rs +++ b/runtime/hydradx/src/benchmarking/mod.rs @@ -28,7 +28,7 @@ pub fn register_asset(name: Vec, deposit: Balance) -> Result { None, Some(&name), AssetKind::Token, - Some(deposit), + deposit, None, None, None, diff --git a/traits/Cargo.toml b/traits/Cargo.toml index 8a236ed39..a1797f0b0 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-traits" -version = "2.7.0" +version = "3.0.0" description = "Shared traits" authors = ["GalacticCouncil"] edition = "2021" diff --git a/traits/src/registry.rs b/traits/src/registry.rs index d4f4eb1b9..9851a05a7 100644 --- a/traits/src/registry.rs +++ b/traits/src/registry.rs @@ -1,52 +1,6 @@ use sp_std::vec::Vec; -pub trait Registry { - fn exists(name: AssetId) -> bool; - - fn retrieve_asset(name: &AssetName) -> Result; - - fn retrieve_asset_type(asset_id: AssetId) -> Result; - - fn create_asset(name: &AssetName, existential_deposit: Balance) -> Result; - - fn get_or_create_asset(name: AssetName, existential_deposit: Balance) -> Result { - if let Ok(asset_id) = Self::retrieve_asset(&name) { - Ok(asset_id) - } else { - Self::create_asset(&name, existential_deposit) - } - } -} - -// Use CreateRegistry if possible -pub trait ShareTokenRegistry: Registry { - fn retrieve_shared_asset(name: &AssetName, assets: &[AssetId]) -> Result; - - fn create_shared_asset( - name: &AssetName, - assets: &[AssetId], - existential_deposit: Balance, - ) -> Result; - - fn get_or_create_shared_asset( - name: AssetName, - assets: Vec, - existential_deposit: Balance, - ) -> Result { - if let Ok(asset_id) = Self::retrieve_shared_asset(&name, &assets) { - Ok(asset_id) - } else { - Self::create_shared_asset(&name, &assets, existential_deposit) - } - } -} - -pub trait InspectRegistry { - fn exists(asset_id: AssetId) -> bool; - fn decimals(asset_id: AssetId) -> Option; -} - -#[derive(Eq, PartialEq, Copy, Clone)] +#[derive(Eq, PartialEq, Copy, Clone, Debug)] pub enum AssetKind { Token, XYK, @@ -55,11 +9,6 @@ pub enum AssetKind { External, } -pub trait CreateRegistry { - type Error; - fn create_asset(name: &[u8], kind: AssetKind, existential_deposit: Balance) -> Result; -} - // Deprecated. // TODO: the following macro is commented out for a reason for now - due to failing clippy in CI // #[deprecated(since = "0.6.0", note = "Please use `AccountIdFor` instead")] @@ -81,14 +30,22 @@ pub trait AccountIdFor { use frame_support::dispatch::Parameter; pub trait Inspect { - type Error; type AssetId: Parameter; + type Location: Parameter; fn is_sufficient(id: Self::AssetId) -> bool; + + fn exists(id: Self::AssetId) -> bool; + + fn decimals(id: Self::AssetId) -> Option; + + fn asset_type(id: Self::AssetId) -> Option; } #[allow(clippy::too_many_arguments)] -pub trait Create: Inspect { +pub trait Create: Inspect { + type Error; + fn register_asset( asset_id: Option, name: Option<&[u8]>, @@ -96,7 +53,7 @@ pub trait Create: Inspect { existential_deposit: Option, symbol: Option<&[u8]>, decimals: Option, - location: Option, + location: Option, xcm_rate_limit: Option, is_sufficient: bool, ) -> Result; @@ -108,7 +65,7 @@ pub trait Create: Inspect { existential_deposit: Option, symbol: Option<&[u8]>, decimals: Option, - location: Option, + location: Option, xcm_rate_limit: Option, ) -> Result { Self::register_asset( @@ -128,17 +85,17 @@ pub trait Create: Inspect { asset_id: Option, name: Option<&[u8]>, kind: AssetKind, - existential_deposit: Option, + existential_deposit: Balance, symbol: Option<&[u8]>, decimals: Option, - location: Option, + location: Option, xcm_rate_limit: Option, ) -> Result { Self::register_asset( asset_id, name, kind, - existential_deposit, + Some(existential_deposit), symbol, decimals, location, @@ -146,9 +103,64 @@ pub trait Create: Inspect { true, ) } + + fn get_or_register_asset( + name: &[u8], + kind: AssetKind, + existential_deposit: Option, + symbol: Option<&[u8]>, + decimals: Option, + location: Option, + xcm_rate_limit: Option, + is_sufficient: bool, + ) -> Result; + + fn get_or_register_sufficient_asset( + name: &[u8], + kind: AssetKind, + existential_deposit: Balance, + symbol: Option<&[u8]>, + decimals: Option, + location: Option, + xcm_rate_limit: Option, + ) -> Result { + Self::get_or_register_asset( + name, + kind, + Some(existential_deposit), + symbol, + decimals, + location, + xcm_rate_limit, + true, + ) + } + + fn get_or_register_insufficient_asset( + name: &[u8], + kind: AssetKind, + existential_deposit: Option, + symbol: Option<&[u8]>, + decimals: Option, + location: Option, + xcm_rate_limit: Option, + ) -> Result { + Self::get_or_register_asset( + name, + kind, + existential_deposit, + symbol, + decimals, + location, + xcm_rate_limit, + false, + ) + } } -pub trait Mutate: Inspect { +pub trait Mutate: Inspect { + type Error; + /// Set location for existing asset id if it wasn't set yet. - fn set_location(asset_id: Self::AssetId, location: AssetNativeLocation) -> Result<(), Self::Error>; + fn set_location(asset_id: Self::AssetId, location: Self::Location) -> Result<(), Self::Error>; }