From a6f37fbe53317e8e0d5c0391a65700fabb54a13d Mon Sep 17 00:00:00 2001 From: Daniel Shiposha Date: Tue, 06 Sep 2022 12:56:03 +0000 Subject: [PATCH] fix: typo foreing -> foreign --- --- a/Cargo.lock +++ b/Cargo.lock @@ -5176,7 +5176,7 @@ "pallet-evm-contract-helpers", "pallet-evm-migration", "pallet-evm-transaction-payment", - "pallet-foreing-assets", + "pallet-foreign-assets", "pallet-fungible", "pallet-inflation", "pallet-nonfungible", @@ -5846,7 +5846,7 @@ ] [[package]] -name = "pallet-foreing-assets" +name = "pallet-foreign-assets" version = "0.1.0" dependencies = [ "frame-support", @@ -8496,7 +8496,7 @@ "pallet-evm-contract-helpers", "pallet-evm-migration", "pallet-evm-transaction-payment", - "pallet-foreing-assets", + "pallet-foreign-assets", "pallet-fungible", "pallet-inflation", "pallet-nonfungible", @@ -12491,7 +12491,7 @@ "pallet-evm-contract-helpers", "pallet-evm-migration", "pallet-evm-transaction-payment", - "pallet-foreing-assets", + "pallet-foreign-assets", "pallet-fungible", "pallet-inflation", "pallet-nonfungible", --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ xtokens -> transfer currencyId: - ForeingAsset + ForeignAsset amount: --- /dev/null +++ b/pallets/foreign-assets/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "pallet-foreign-assets" +version = "0.1.0" +license = "GPLv3" +edition = "2021" + +[dependencies] +log = { version = "0.4.16", default-features = false } +serde = { version = "1.0.136", optional = true } +scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +up-data-structs = { default-features = false, path = '../../primitives/data-structs' } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } +pallet-common = { default-features = false, path = '../common' } +pallet-fungible = { default-features = false, path = '../fungible' } +xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27", default-features = false } +xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27", default-features = false } +xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27", default-features = false } +#orml-tokens = { git = 'https://github.com/UniqueNetwork/open-runtime-module-library', branch = 'unique-polkadot-v0.9.24', version = "0.4.1-dev", default-features = false } +orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.27", version = "0.4.1-dev", default-features = false } +#git = "https://github.com/open-web3-stack/open-runtime-module-library" +#branch = "polkadot-v0.9.27" + +[dev-dependencies] +serde_json = "1.0.68" +hex = { version = "0.4" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } +pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } + +[features] +default = ["std"] +std = [ + "serde", + "log/std", + "codec/std", + "scale-info/std", + "sp-runtime/std", + "sp-std/std", + "frame-support/std", + "frame-system/std", + "up-data-structs/std", + "pallet-common/std", + "pallet-balances/std", + "pallet-fungible/std", + "orml-tokens/std" +] +try-runtime = ["frame-support/try-runtime"] --- /dev/null +++ b/pallets/foreign-assets/src/impl_fungibles.rs @@ -0,0 +1,621 @@ +// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. +// This file is part of Unique Network. + +// Unique Network is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Unique Network is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Unique Network. If not, see . + +//! Implementations for fungibles trait. + +use super::*; +use frame_system::Config as SystemConfig; + +use frame_support::traits::tokens::{DepositConsequence, WithdrawConsequence}; +use pallet_common::CollectionHandle; +use pallet_fungible::FungibleHandle; +use pallet_common::CommonCollectionOperations; +use up_data_structs::budget::Unlimited; +use sp_runtime::traits::{CheckedAdd, CheckedSub}; + +impl fungibles::Inspect<::AccountId> for Pallet +where + T: orml_tokens::Config, +{ + type AssetId = AssetIds; + type Balance = BalanceOf; + + fn total_issuance(asset: Self::AssetId) -> Self::Balance { + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible total_issuance"); + + match asset { + AssetIds::NativeAssetId(NativeCurrency::Here) => { + let parent_amount = as fungible::Inspect< + T::AccountId, + >>::total_issuance(); + + let value: u128 = match parent_amount.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + let ti: Self::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + ti + } + AssetIds::NativeAssetId(NativeCurrency::Parent) => { + let amount = + as fungibles::Inspect>::total_issuance( + AssetIds::NativeAssetId(NativeCurrency::Parent), + ); + + let value: u128 = match amount.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + let ti: Self::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + ti + } + AssetIds::ForeignAssetId(fid) => { + let target_collection_id = match >::get(fid) { + Some(v) => v, + None => return Zero::zero(), + }; + let collection_handle = match >::try_get(target_collection_id) { + Ok(v) => v, + Err(_) => return Zero::zero(), + }; + let collection = FungibleHandle::cast(collection_handle); + Self::Balance::try_from(collection.total_supply()).unwrap_or(Zero::zero()) + } + } + } + + fn minimum_balance(asset: Self::AssetId) -> Self::Balance { + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible minimum_balance"); + match asset { + AssetIds::NativeAssetId(NativeCurrency::Here) => { + let parent_amount = as fungible::Inspect< + T::AccountId, + >>::minimum_balance(); + + let value: u128 = match parent_amount.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + let ti: Self::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + ti + } + AssetIds::NativeAssetId(NativeCurrency::Parent) => { + let amount = + as fungibles::Inspect>::minimum_balance( + AssetIds::NativeAssetId(NativeCurrency::Parent), + ); + + let value: u128 = match amount.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + let ti: Self::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + ti + } + AssetIds::ForeignAssetId(fid) => { + AssetMetadatas::::get(AssetIds::ForeignAssetId(fid)) + .map(|x| x.minimal_balance) + .unwrap_or_else(Zero::zero) + } + } + } + + fn balance(asset: Self::AssetId, who: &::AccountId) -> Self::Balance { + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible balance"); + match asset { + AssetIds::NativeAssetId(NativeCurrency::Here) => { + let parent_amount = + as fungible::Inspect>::balance(who); + + let value: u128 = match parent_amount.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + let ti: Self::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + ti + } + AssetIds::NativeAssetId(NativeCurrency::Parent) => { + let amount = as fungibles::Inspect>::balance( + AssetIds::NativeAssetId(NativeCurrency::Parent), + who, + ); + + let value: u128 = match amount.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + let ti: Self::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + ti + } + AssetIds::ForeignAssetId(fid) => { + let target_collection_id = match >::get(fid) { + Some(v) => v, + None => return Zero::zero(), + }; + let collection_handle = match >::try_get(target_collection_id) { + Ok(v) => v, + Err(_) => return Zero::zero(), + }; + let collection = FungibleHandle::cast(collection_handle); + Self::Balance::try_from( + collection.balance(T::CrossAccountId::from_sub(who.clone()), TokenId(0)), + ) + .unwrap_or(Zero::zero()) + } + } + } + + fn reducible_balance( + asset: Self::AssetId, + who: &::AccountId, + keep_alive: bool, + ) -> Self::Balance { + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible reducible_balance"); + + match asset { + AssetIds::NativeAssetId(NativeCurrency::Here) => { + let parent_amount = as fungible::Inspect< + T::AccountId, + >>::reducible_balance(who, keep_alive); + + let value: u128 = match parent_amount.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + let ti: Self::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + ti + } + AssetIds::NativeAssetId(NativeCurrency::Parent) => { + let amount = + as fungibles::Inspect>::reducible_balance( + AssetIds::NativeAssetId(NativeCurrency::Parent), + who, + keep_alive, + ); + + let value: u128 = match amount.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + let ti: Self::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => return Zero::zero(), + }; + + ti + } + _ => Self::balance(asset, who), + } + } + + fn can_deposit( + asset: Self::AssetId, + who: &::AccountId, + amount: Self::Balance, + mint: bool, + ) -> DepositConsequence { + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible can_deposit"); + + let value: u128 = match amount.try_into() { + Ok(val) => val, + Err(_) => return DepositConsequence::CannotCreate, + }; + + match asset { + AssetIds::NativeAssetId(NativeCurrency::Here) => { + let this_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return DepositConsequence::CannotCreate; + } + }; + as fungible::Inspect>::can_deposit( + who, + this_amount, + mint, + ) + } + AssetIds::NativeAssetId(NativeCurrency::Parent) => { + let parent_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return DepositConsequence::CannotCreate; + } + }; + as fungibles::Inspect>::can_deposit( + AssetIds::NativeAssetId(NativeCurrency::Parent), + who, + parent_amount, + mint, + ) + } + _ => { + if amount.is_zero() { + return DepositConsequence::Success; + } + + let extential_deposit_value = T::ExistentialDeposit::get(); + let ed_value: u128 = match extential_deposit_value.try_into() { + Ok(val) => val, + Err(_) => return DepositConsequence::CannotCreate, + }; + let extential_deposit: Self::Balance = match ed_value.try_into() { + Ok(val) => val, + Err(_) => return DepositConsequence::CannotCreate, + }; + + let new_total_balance = match Self::balance(asset, who).checked_add(&amount) { + Some(x) => x, + None => return DepositConsequence::Overflow, + }; + + if new_total_balance < extential_deposit { + return DepositConsequence::BelowMinimum; + } + + DepositConsequence::Success + } + } + } + + fn can_withdraw( + asset: Self::AssetId, + who: &::AccountId, + amount: Self::Balance, + ) -> WithdrawConsequence { + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible can_withdraw"); + let value: u128 = match amount.try_into() { + Ok(val) => val, + Err(_) => return WithdrawConsequence::UnknownAsset, + }; + + match asset { + AssetIds::NativeAssetId(NativeCurrency::Here) => { + let this_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return WithdrawConsequence::UnknownAsset; + } + }; + match as fungible::Inspect>::can_withdraw( + who, + this_amount, + ) { + WithdrawConsequence::NoFunds => WithdrawConsequence::NoFunds, + WithdrawConsequence::WouldDie => WithdrawConsequence::WouldDie, + WithdrawConsequence::UnknownAsset => WithdrawConsequence::UnknownAsset, + WithdrawConsequence::Underflow => WithdrawConsequence::Underflow, + WithdrawConsequence::Overflow => WithdrawConsequence::Overflow, + WithdrawConsequence::Frozen => WithdrawConsequence::Frozen, + WithdrawConsequence::Success => WithdrawConsequence::Success, + _ => WithdrawConsequence::NoFunds, + } + } + AssetIds::NativeAssetId(NativeCurrency::Parent) => { + let parent_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return WithdrawConsequence::UnknownAsset; + } + }; + match as fungibles::Inspect>::can_withdraw( + AssetIds::NativeAssetId(NativeCurrency::Parent), + who, + parent_amount, + ) { + WithdrawConsequence::NoFunds => WithdrawConsequence::NoFunds, + WithdrawConsequence::WouldDie => WithdrawConsequence::WouldDie, + WithdrawConsequence::UnknownAsset => WithdrawConsequence::UnknownAsset, + WithdrawConsequence::Underflow => WithdrawConsequence::Underflow, + WithdrawConsequence::Overflow => WithdrawConsequence::Overflow, + WithdrawConsequence::Frozen => WithdrawConsequence::Frozen, + WithdrawConsequence::Success => WithdrawConsequence::Success, + _ => WithdrawConsequence::NoFunds, + } + } + _ => match Self::balance(asset, who).checked_sub(&amount) { + Some(_) => WithdrawConsequence::Success, + None => WithdrawConsequence::NoFunds, + }, + } + } +} + +impl fungibles::Mutate<::AccountId> for Pallet +where + T: orml_tokens::Config, +{ + fn mint_into( + asset: Self::AssetId, + who: &::AccountId, + amount: Self::Balance, + ) -> DispatchResult { + //Self::do_mint(asset, who, amount, None) + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible mint_into {:?}", asset); + + let value: u128 = match amount.try_into() { + Ok(val) => val, + Err(_) => return Err(DispatchError::Other("Bad amount to value conversion")), + }; + + match asset { + AssetIds::NativeAssetId(NativeCurrency::Here) => { + let this_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return Err(DispatchError::Other( + "Bad amount to this parachain value conversion", + )) + } + }; + + as fungible::Mutate>::mint_into( + who, + this_amount, + ) + } + AssetIds::NativeAssetId(NativeCurrency::Parent) => { + let parent_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return Err(DispatchError::Other( + "Bad amount to relay chain value conversion", + )) + } + }; + + as fungibles::Mutate>::mint_into( + AssetIds::NativeAssetId(NativeCurrency::Parent), + who, + parent_amount, + ) + } + AssetIds::ForeignAssetId(fid) => { + let target_collection_id = match >::get(fid) { + Some(v) => v, + None => { + return Err(DispatchError::Other( + "Associated collection not found for asset", + )) + } + }; + let collection = + FungibleHandle::cast(>::try_get(target_collection_id)?); + let account = T::CrossAccountId::from_sub(who.clone()); + + let amount_data: pallet_fungible::CreateItemData = (account.clone(), value); + + pallet_fungible::Pallet::::create_item_foreign( + &collection, + &account, + amount_data, + &Unlimited, + )?; + + Ok(()) + } + } + } + + fn burn_from( + asset: Self::AssetId, + who: &::AccountId, + amount: Self::Balance, + ) -> Result { + // let f = DebitFlags { keep_alive: false, best_effort: false }; + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible burn_from"); + + let value: u128 = match amount.try_into() { + Ok(val) => val, + Err(_) => return Err(DispatchError::Other("Bad amount to value conversion")), + }; + + match asset { + AssetIds::NativeAssetId(NativeCurrency::Here) => { + let this_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return Err(DispatchError::Other( + "Bad amount to this parachain value conversion", + )) + } + }; + + match as fungible::Mutate>::burn_from( + who, + this_amount, + ) { + Ok(_) => Ok(amount), + Err(e) => Err(e), + } + } + AssetIds::NativeAssetId(NativeCurrency::Parent) => { + let parent_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return Err(DispatchError::Other( + "Bad amount to relay chain value conversion", + )) + } + }; + + match as fungibles::Mutate>::burn_from( + AssetIds::NativeAssetId(NativeCurrency::Parent), + who, + parent_amount, + ) { + Ok(_) => Ok(amount), + Err(e) => Err(e), + } + } + AssetIds::ForeignAssetId(fid) => { + let target_collection_id = match >::get(fid) { + Some(v) => v, + None => { + return Err(DispatchError::Other( + "Associated collection not found for asset", + )) + } + }; + let collection = + FungibleHandle::cast(>::try_get(target_collection_id)?); + pallet_fungible::Pallet::::burn_foreign( + &collection, + &T::CrossAccountId::from_sub(who.clone()), + value, + )?; + + Ok(amount) + } + } + } + + fn slash( + asset: Self::AssetId, + who: &::AccountId, + amount: Self::Balance, + ) -> Result { + // let f = DebitFlags { keep_alive: false, best_effort: true }; + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible slash"); + Self::burn_from(asset, who, amount)?; + Ok(amount) + } +} + +impl fungibles::Transfer for Pallet +where + T: orml_tokens::Config, +{ + fn transfer( + asset: Self::AssetId, + source: &::AccountId, + dest: &::AccountId, + amount: Self::Balance, + keep_alive: bool, + ) -> Result { + // let f = TransferFlags { keep_alive, best_effort: false, burn_dust: false }; + log::trace!(target: "fassets::impl_foreign_assets", "impl_fungible transfer"); + + let value: u128 = match amount.try_into() { + Ok(val) => val, + Err(_) => return Err(DispatchError::Other("Bad amount to value conversion")), + }; + + match asset { + AssetIds::NativeAssetId(NativeCurrency::Here) => { + let this_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return Err(DispatchError::Other( + "Bad amount to this parachain value conversion", + )) + } + }; + + match as fungible::Transfer>::transfer( + source, + dest, + this_amount, + keep_alive, + ) { + Ok(_) => Ok(amount), + Err(_) => Err(DispatchError::Other( + "Bad amount to relay chain value conversion", + )), + } + } + AssetIds::NativeAssetId(NativeCurrency::Parent) => { + let parent_amount: ::Balance = match value.try_into() { + Ok(val) => val, + Err(_) => { + return Err(DispatchError::Other( + "Bad amount to relay chain value conversion", + )) + } + }; + + match as fungibles::Transfer>::transfer( + AssetIds::NativeAssetId(NativeCurrency::Parent), + source, + dest, + parent_amount, + keep_alive, + ) { + Ok(_) => Ok(amount), + Err(e) => Err(e), + } + } + AssetIds::ForeignAssetId(fid) => { + let target_collection_id = match >::get(fid) { + Some(v) => v, + None => { + return Err(DispatchError::Other( + "Associated collection not found for asset", + )) + } + }; + let collection = + FungibleHandle::cast(>::try_get(target_collection_id)?); + + pallet_fungible::Pallet::::transfer( + &collection, + &T::CrossAccountId::from_sub(source.clone()), + &T::CrossAccountId::from_sub(dest.clone()), + value, + &Unlimited, + )?; + + Ok(amount) + } + } + } +} --- /dev/null +++ b/pallets/foreign-assets/src/lib.rs @@ -0,0 +1,497 @@ +// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. +// This file is part of Unique Network. + +// Unique Network is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Unique Network is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Unique Network. If not, see . + +//! # Foreign assets +//! +//! - [`Config`] +//! - [`Call`] +//! - [`Pallet`] +//! +//! ## Overview +//! +//! The foreign assests pallet provides functions for: +//! +//! - Local and foreign assets management. The foreign assets can be updated without runtime upgrade. +//! - Bounds between asset and target collection for cross chain transfer and inner transfers. +//! +//! ## Overview +//! +//! Under construction + +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(clippy::unused_unit)] + +use frame_support::{ + dispatch::DispatchResult, + ensure, + pallet_prelude::*, + traits::{fungible, fungibles, Currency, EnsureOrigin}, + transactional, RuntimeDebug, +}; +use frame_system::pallet_prelude::*; +use up_data_structs::{CollectionMode}; +use pallet_fungible::{Pallet as PalletFungible}; +use scale_info::{TypeInfo}; +use sp_runtime::{ + traits::{One, Zero}, + ArithmeticError, +}; +use sp_std::{boxed::Box, vec::Vec}; +use up_data_structs::{CollectionId, TokenId, CreateCollectionData}; + +// NOTE:v1::MultiLocation is used in storages, we would need to do migration if upgrade the +// MultiLocation in the future. +use xcm::opaque::latest::prelude::XcmError; +use xcm::{v1::MultiLocation, VersionedMultiLocation}; +use xcm_executor::{traits::WeightTrader, Assets}; + +use pallet_common::erc::CrossAccountId; + +#[cfg(feature = "std")] +use serde::{Deserialize, Serialize}; + +// TODO: Move to primitives +// Id of native currency. +// 0 - QTZ\UNQ +// 1 - KSM\DOT +#[derive( + Clone, + Copy, + Eq, + PartialEq, + PartialOrd, + Ord, + MaxEncodedLen, + RuntimeDebug, + Encode, + Decode, + TypeInfo, +)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum NativeCurrency { + Here = 0, + Parent = 1, +} + +#[derive( + Clone, + Copy, + Eq, + PartialEq, + PartialOrd, + Ord, + MaxEncodedLen, + RuntimeDebug, + Encode, + Decode, + TypeInfo, +)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum AssetIds { + ForeignAssetId(ForeignAssetId), + NativeAssetId(NativeCurrency), +} + +pub trait TryAsForeign { + fn try_as_foreign(asset: T) -> Option; +} + +impl TryAsForeign for AssetIds { + fn try_as_foreign(asset: AssetIds) -> Option { + match asset { + AssetIds::ForeignAssetId(id) => Some(id), + _ => None, + } + } +} + +pub type ForeignAssetId = u32; +pub type CurrencyId = AssetIds; + +mod impl_fungibles; +mod weights; + +pub use module::*; +pub use weights::WeightInfo; + +/// Type alias for currency balance. +pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + +/// A mapping between ForeignAssetId and AssetMetadata. +pub trait AssetIdMapping { + /// Returns the AssetMetadata associated with a given ForeignAssetId. + fn get_asset_metadata(foreign_asset_id: ForeignAssetId) -> Option; + /// Returns the MultiLocation associated with a given ForeignAssetId. + fn get_multi_location(foreign_asset_id: ForeignAssetId) -> Option; + /// Returns the CurrencyId associated with a given MultiLocation. + fn get_currency_id(multi_location: MultiLocation) -> Option; +} + +pub struct XcmForeignAssetIdMapping(sp_std::marker::PhantomData); + +impl AssetIdMapping>> + for XcmForeignAssetIdMapping +{ + fn get_asset_metadata(foreign_asset_id: ForeignAssetId) -> Option>> { + log::trace!(target: "fassets::asset_metadatas", "call"); + Pallet::::asset_metadatas(AssetIds::ForeignAssetId(foreign_asset_id)) + } + + fn get_multi_location(foreign_asset_id: ForeignAssetId) -> Option { + log::trace!(target: "fassets::get_multi_location", "call"); + Pallet::::foreign_asset_locations(foreign_asset_id) + } + + fn get_currency_id(multi_location: MultiLocation) -> Option { + log::trace!(target: "fassets::get_currency_id", "call"); + Some(AssetIds::ForeignAssetId( + Pallet::::location_to_currency_ids(multi_location).unwrap_or(0), + )) + } +} + +#[frame_support::pallet] +pub mod module { + use super::*; + + #[pallet::config] + pub trait Config: + frame_system::Config + + pallet_common::Config + + pallet_fungible::Config + + orml_tokens::Config + + pallet_balances::Config + { + /// The overarching event type. + type Event: From> + IsType<::Event>; + + /// Currency type for withdraw and balance storage. + type Currency: Currency; + + /// Required origin for registering asset. + type RegisterOrigin: EnsureOrigin; + + /// Weight information for the extrinsics in this module. + type WeightInfo: WeightInfo; + } + + #[derive(Clone, Eq, PartialEq, RuntimeDebug, Encode, Decode, TypeInfo)] + pub struct AssetMetadata { + pub name: Vec, + pub symbol: Vec, + pub decimals: u8, + pub minimal_balance: Balance, + } + + #[pallet::error] + pub enum Error { + /// The given location could not be used (e.g. because it cannot be expressed in the + /// desired version of XCM). + BadLocation, + /// MultiLocation existed + MultiLocationExisted, + /// AssetId not exists + AssetIdNotExists, + /// AssetId exists + AssetIdExisted, + } + + #[pallet::event] + #[pallet::generate_deposit(fn deposit_event)] + pub enum Event { + /// The foreign asset registered. + ForeignAssetRegistered { + asset_id: ForeignAssetId, + asset_address: MultiLocation, + metadata: AssetMetadata>, + }, + /// The foreign asset updated. + ForeignAssetUpdated { + asset_id: ForeignAssetId, + asset_address: MultiLocation, + metadata: AssetMetadata>, + }, + /// The asset registered. + AssetRegistered { + asset_id: AssetIds, + metadata: AssetMetadata>, + }, + /// The asset updated. + AssetUpdated { + asset_id: AssetIds, + metadata: AssetMetadata>, + }, + } + + /// Next available Foreign AssetId ID. + /// + /// NextForeignAssetId: ForeignAssetId + #[pallet::storage] + #[pallet::getter(fn next_foreign_asset_id)] + pub type NextForeignAssetId = StorageValue<_, ForeignAssetId, ValueQuery>; + /// The storages for MultiLocations. + /// + /// ForeignAssetLocations: map ForeignAssetId => Option + #[pallet::storage] + #[pallet::getter(fn foreign_asset_locations)] + pub type ForeignAssetLocations = + StorageMap<_, Twox64Concat, ForeignAssetId, MultiLocation, OptionQuery>; + + /// The storages for CurrencyIds. + /// + /// LocationToCurrencyIds: map MultiLocation => Option + #[pallet::storage] + #[pallet::getter(fn location_to_currency_ids)] + pub type LocationToCurrencyIds = + StorageMap<_, Twox64Concat, MultiLocation, ForeignAssetId, OptionQuery>; + + /// The storages for AssetMetadatas. + /// + /// AssetMetadatas: map AssetIds => Option + #[pallet::storage] + #[pallet::getter(fn asset_metadatas)] + pub type AssetMetadatas = + StorageMap<_, Twox64Concat, AssetIds, AssetMetadata>, OptionQuery>; + + /// The storages for assets to fungible collection binding + /// + #[pallet::storage] + #[pallet::getter(fn asset_binding)] + pub type AssetBinding = + StorageMap<_, Twox64Concat, ForeignAssetId, CollectionId, OptionQuery>; + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::call] + impl Pallet { + #[pallet::weight(::WeightInfo::register_foreign_asset())] + #[transactional] + pub fn register_foreign_asset( + origin: OriginFor, + owner: T::AccountId, + location: Box, + metadata: Box>>, + ) -> DispatchResult { + T::RegisterOrigin::ensure_origin(origin.clone())?; + + let location: MultiLocation = (*location) + .try_into() + .map_err(|()| Error::::BadLocation)?; + + let md = metadata.clone(); + let name: Vec = md.name.into_iter().map(|x| x as u16).collect::>(); + let mut description: Vec = "Foreign assets collection for " + .encode_utf16() + .collect::>(); + description.append(&mut name.clone()); + + let data: CreateCollectionData = CreateCollectionData { + name: name.try_into().unwrap(), + description: description.try_into().unwrap(), + mode: CollectionMode::Fungible(18), + ..Default::default() + }; + + let bounded_collection_id = >::init_foreign_collection( + CrossAccountId::from_sub(owner), + data, + )?; + let foreign_asset_id = + Self::do_register_foreign_asset(&location, &metadata, bounded_collection_id)?; + + Self::deposit_event(Event::::ForeignAssetRegistered { + asset_id: foreign_asset_id, + asset_address: location, + metadata: *metadata, + }); + Ok(()) + } + + #[pallet::weight(::WeightInfo::update_foreign_asset())] + #[transactional] + pub fn update_foreign_asset( + origin: OriginFor, + foreign_asset_id: ForeignAssetId, + location: Box, + metadata: Box>>, + ) -> DispatchResult { + T::RegisterOrigin::ensure_origin(origin)?; + + let location: MultiLocation = (*location) + .try_into() + .map_err(|()| Error::::BadLocation)?; + Self::do_update_foreign_asset(foreign_asset_id, &location, &metadata)?; + + Self::deposit_event(Event::::ForeignAssetUpdated { + asset_id: foreign_asset_id, + asset_address: location, + metadata: *metadata, + }); + Ok(()) + } + } +} + +impl Pallet { + fn get_next_foreign_asset_id() -> Result { + NextForeignAssetId::::try_mutate(|current| -> Result { + let id = *current; + *current = current + .checked_add(One::one()) + .ok_or(ArithmeticError::Overflow)?; + Ok(id) + }) + } + + fn do_register_foreign_asset( + location: &MultiLocation, + metadata: &AssetMetadata>, + bounded_collection_id: CollectionId, + ) -> Result { + let foreign_asset_id = Self::get_next_foreign_asset_id()?; + LocationToCurrencyIds::::try_mutate(location, |maybe_currency_ids| -> DispatchResult { + ensure!( + maybe_currency_ids.is_none(), + Error::::MultiLocationExisted + ); + *maybe_currency_ids = Some(foreign_asset_id); + // *maybe_currency_ids = Some(CurrencyId::ForeignAsset(foreign_asset_id)); + + ForeignAssetLocations::::try_mutate( + foreign_asset_id, + |maybe_location| -> DispatchResult { + ensure!(maybe_location.is_none(), Error::::MultiLocationExisted); + *maybe_location = Some(location.clone()); + + AssetMetadatas::::try_mutate( + AssetIds::ForeignAssetId(foreign_asset_id), + |maybe_asset_metadatas| -> DispatchResult { + ensure!(maybe_asset_metadatas.is_none(), Error::::AssetIdExisted); + *maybe_asset_metadatas = Some(metadata.clone()); + Ok(()) + }, + ) + }, + )?; + + AssetBinding::::try_mutate(foreign_asset_id, |collection_id| -> DispatchResult { + *collection_id = Some(bounded_collection_id); + Ok(()) + }) + })?; + + Ok(foreign_asset_id) + } + + fn do_update_foreign_asset( + foreign_asset_id: ForeignAssetId, + location: &MultiLocation, + metadata: &AssetMetadata>, + ) -> DispatchResult { + ForeignAssetLocations::::try_mutate( + foreign_asset_id, + |maybe_multi_locations| -> DispatchResult { + let old_multi_locations = maybe_multi_locations + .as_mut() + .ok_or(Error::::AssetIdNotExists)?; + + AssetMetadatas::::try_mutate( + AssetIds::ForeignAssetId(foreign_asset_id), + |maybe_asset_metadatas| -> DispatchResult { + ensure!( + maybe_asset_metadatas.is_some(), + Error::::AssetIdNotExists + ); + + // modify location + if location != old_multi_locations { + LocationToCurrencyIds::::remove(old_multi_locations.clone()); + LocationToCurrencyIds::::try_mutate( + location, + |maybe_currency_ids| -> DispatchResult { + ensure!( + maybe_currency_ids.is_none(), + Error::::MultiLocationExisted + ); + // *maybe_currency_ids = Some(CurrencyId::ForeignAsset(foreign_asset_id)); + *maybe_currency_ids = Some(foreign_asset_id); + Ok(()) + }, + )?; + } + *maybe_asset_metadatas = Some(metadata.clone()); + *old_multi_locations = location.clone(); + Ok(()) + }, + ) + }, + ) + } +} + +pub use frame_support::{ + traits::{ + fungibles::{Balanced, CreditOf}, + tokens::currency::Currency as CurrencyT, + OnUnbalanced as OnUnbalancedT, + }, + weights::{WeightToFeePolynomial, WeightToFee}, +}; + +pub struct FreeForAll< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, +>( + Weight, + Currency::Balance, + PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, +); + +impl< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > WeightTrader for FreeForAll +{ + fn new() -> Self { + Self(0, Zero::zero(), PhantomData) + } + + fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { + log::trace!(target: "fassets::weight", "buy_weight weight: {:?}, payment: {:?}", weight, payment); + Ok(payment) + } +} +impl< + WeightToFee: WeightToFeePolynomial, + AssetId: Get, + AccountId, + Currency: CurrencyT, + OnUnbalanced: OnUnbalancedT, + > Drop for FreeForAll +{ + fn drop(&mut self) { + OnUnbalanced::on_unbalanced(Currency::issue(self.1)); + } +} --- /dev/null +++ b/pallets/foreign-assets/src/weights.rs @@ -0,0 +1,43 @@ + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(clippy::unnecessary_cast)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for module_asset_registry. +pub trait WeightInfo { + fn register_foreign_asset() -> Weight; + fn update_foreign_asset() -> Weight; +} + +/// Weights for module_asset_registry using the Acala node and recommended hardware. +pub struct AcalaWeight(PhantomData); +impl WeightInfo for AcalaWeight { + fn register_foreign_asset() -> Weight { + (29_819_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn update_foreign_asset() -> Weight { + (25_119_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn register_foreign_asset() -> Weight { + (29_819_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn update_foreign_asset() -> Weight { + (25_119_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } +} \ No newline at end of file --- a/pallets/foreing-assets/Cargo.toml +++ /dev/null @@ -1,53 +0,0 @@ -[package] -name = "pallet-foreing-assets" -version = "0.1.0" -license = "GPLv3" -edition = "2021" - -[dependencies] -log = { version = "0.4.16", default-features = false } -serde = { version = "1.0.136", optional = true } -scale-info = { version = "2.0.1", default-features = false, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } -up-data-structs = { default-features = false, path = '../../primitives/data-structs' } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27", default-features = false } -pallet-common = { default-features = false, path = '../common' } -pallet-fungible = { default-features = false, path = '../fungible' } -xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27", default-features = false } -xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27", default-features = false } -xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27", default-features = false } -#orml-tokens = { git = 'https://github.com/UniqueNetwork/open-runtime-module-library', branch = 'unique-polkadot-v0.9.24', version = "0.4.1-dev", default-features = false } -orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.27", version = "0.4.1-dev", default-features = false } -#git = "https://github.com/open-web3-stack/open-runtime-module-library" -#branch = "polkadot-v0.9.27" - -[dev-dependencies] -serde_json = "1.0.68" -hex = { version = "0.4" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } -pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } - -[features] -default = ["std"] -std = [ - "serde", - "log/std", - "codec/std", - "scale-info/std", - "sp-runtime/std", - "sp-std/std", - "frame-support/std", - "frame-system/std", - "up-data-structs/std", - "pallet-common/std", - "pallet-balances/std", - "pallet-fungible/std", - "orml-tokens/std" -] -try-runtime = ["frame-support/try-runtime"] --- a/pallets/foreing-assets/src/impl_fungibles.rs +++ /dev/null @@ -1,621 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -//! Implementations for fungibles trait. - -use super::*; -use frame_system::Config as SystemConfig; - -use frame_support::traits::tokens::{DepositConsequence, WithdrawConsequence}; -use pallet_common::CollectionHandle; -use pallet_fungible::FungibleHandle; -use pallet_common::CommonCollectionOperations; -use up_data_structs::budget::Unlimited; -use sp_runtime::traits::{CheckedAdd, CheckedSub}; - -impl fungibles::Inspect<::AccountId> for Pallet -where - T: orml_tokens::Config, -{ - type AssetId = AssetIds; - type Balance = BalanceOf; - - fn total_issuance(asset: Self::AssetId) -> Self::Balance { - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible total_issuance"); - - match asset { - AssetIds::NativeAssetId(NativeCurrency::Here) => { - let parent_amount = as fungible::Inspect< - T::AccountId, - >>::total_issuance(); - - let value: u128 = match parent_amount.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - let ti: Self::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - ti - } - AssetIds::NativeAssetId(NativeCurrency::Parent) => { - let amount = - as fungibles::Inspect>::total_issuance( - AssetIds::NativeAssetId(NativeCurrency::Parent), - ); - - let value: u128 = match amount.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - let ti: Self::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - ti - } - AssetIds::ForeignAssetId(fid) => { - let target_collection_id = match >::get(fid) { - Some(v) => v, - None => return Zero::zero(), - }; - let collection_handle = match >::try_get(target_collection_id) { - Ok(v) => v, - Err(_) => return Zero::zero(), - }; - let collection = FungibleHandle::cast(collection_handle); - Self::Balance::try_from(collection.total_supply()).unwrap_or(Zero::zero()) - } - } - } - - fn minimum_balance(asset: Self::AssetId) -> Self::Balance { - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible minimum_balance"); - match asset { - AssetIds::NativeAssetId(NativeCurrency::Here) => { - let parent_amount = as fungible::Inspect< - T::AccountId, - >>::minimum_balance(); - - let value: u128 = match parent_amount.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - let ti: Self::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - ti - } - AssetIds::NativeAssetId(NativeCurrency::Parent) => { - let amount = - as fungibles::Inspect>::minimum_balance( - AssetIds::NativeAssetId(NativeCurrency::Parent), - ); - - let value: u128 = match amount.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - let ti: Self::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - ti - } - AssetIds::ForeignAssetId(fid) => { - AssetMetadatas::::get(AssetIds::ForeignAssetId(fid)) - .map(|x| x.minimal_balance) - .unwrap_or_else(Zero::zero) - } - } - } - - fn balance(asset: Self::AssetId, who: &::AccountId) -> Self::Balance { - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible balance"); - match asset { - AssetIds::NativeAssetId(NativeCurrency::Here) => { - let parent_amount = - as fungible::Inspect>::balance(who); - - let value: u128 = match parent_amount.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - let ti: Self::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - ti - } - AssetIds::NativeAssetId(NativeCurrency::Parent) => { - let amount = as fungibles::Inspect>::balance( - AssetIds::NativeAssetId(NativeCurrency::Parent), - who, - ); - - let value: u128 = match amount.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - let ti: Self::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - ti - } - AssetIds::ForeignAssetId(fid) => { - let target_collection_id = match >::get(fid) { - Some(v) => v, - None => return Zero::zero(), - }; - let collection_handle = match >::try_get(target_collection_id) { - Ok(v) => v, - Err(_) => return Zero::zero(), - }; - let collection = FungibleHandle::cast(collection_handle); - Self::Balance::try_from( - collection.balance(T::CrossAccountId::from_sub(who.clone()), TokenId(0)), - ) - .unwrap_or(Zero::zero()) - } - } - } - - fn reducible_balance( - asset: Self::AssetId, - who: &::AccountId, - keep_alive: bool, - ) -> Self::Balance { - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible reducible_balance"); - - match asset { - AssetIds::NativeAssetId(NativeCurrency::Here) => { - let parent_amount = as fungible::Inspect< - T::AccountId, - >>::reducible_balance(who, keep_alive); - - let value: u128 = match parent_amount.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - let ti: Self::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - ti - } - AssetIds::NativeAssetId(NativeCurrency::Parent) => { - let amount = - as fungibles::Inspect>::reducible_balance( - AssetIds::NativeAssetId(NativeCurrency::Parent), - who, - keep_alive, - ); - - let value: u128 = match amount.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - let ti: Self::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => return Zero::zero(), - }; - - ti - } - _ => Self::balance(asset, who), - } - } - - fn can_deposit( - asset: Self::AssetId, - who: &::AccountId, - amount: Self::Balance, - mint: bool, - ) -> DepositConsequence { - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible can_deposit"); - - let value: u128 = match amount.try_into() { - Ok(val) => val, - Err(_) => return DepositConsequence::CannotCreate, - }; - - match asset { - AssetIds::NativeAssetId(NativeCurrency::Here) => { - let this_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return DepositConsequence::CannotCreate; - } - }; - as fungible::Inspect>::can_deposit( - who, - this_amount, - mint, - ) - } - AssetIds::NativeAssetId(NativeCurrency::Parent) => { - let parent_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return DepositConsequence::CannotCreate; - } - }; - as fungibles::Inspect>::can_deposit( - AssetIds::NativeAssetId(NativeCurrency::Parent), - who, - parent_amount, - mint, - ) - } - _ => { - if amount.is_zero() { - return DepositConsequence::Success; - } - - let extential_deposit_value = T::ExistentialDeposit::get(); - let ed_value: u128 = match extential_deposit_value.try_into() { - Ok(val) => val, - Err(_) => return DepositConsequence::CannotCreate, - }; - let extential_deposit: Self::Balance = match ed_value.try_into() { - Ok(val) => val, - Err(_) => return DepositConsequence::CannotCreate, - }; - - let new_total_balance = match Self::balance(asset, who).checked_add(&amount) { - Some(x) => x, - None => return DepositConsequence::Overflow, - }; - - if new_total_balance < extential_deposit { - return DepositConsequence::BelowMinimum; - } - - DepositConsequence::Success - } - } - } - - fn can_withdraw( - asset: Self::AssetId, - who: &::AccountId, - amount: Self::Balance, - ) -> WithdrawConsequence { - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible can_withdraw"); - let value: u128 = match amount.try_into() { - Ok(val) => val, - Err(_) => return WithdrawConsequence::UnknownAsset, - }; - - match asset { - AssetIds::NativeAssetId(NativeCurrency::Here) => { - let this_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return WithdrawConsequence::UnknownAsset; - } - }; - match as fungible::Inspect>::can_withdraw( - who, - this_amount, - ) { - WithdrawConsequence::NoFunds => WithdrawConsequence::NoFunds, - WithdrawConsequence::WouldDie => WithdrawConsequence::WouldDie, - WithdrawConsequence::UnknownAsset => WithdrawConsequence::UnknownAsset, - WithdrawConsequence::Underflow => WithdrawConsequence::Underflow, - WithdrawConsequence::Overflow => WithdrawConsequence::Overflow, - WithdrawConsequence::Frozen => WithdrawConsequence::Frozen, - WithdrawConsequence::Success => WithdrawConsequence::Success, - _ => WithdrawConsequence::NoFunds, - } - } - AssetIds::NativeAssetId(NativeCurrency::Parent) => { - let parent_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return WithdrawConsequence::UnknownAsset; - } - }; - match as fungibles::Inspect>::can_withdraw( - AssetIds::NativeAssetId(NativeCurrency::Parent), - who, - parent_amount, - ) { - WithdrawConsequence::NoFunds => WithdrawConsequence::NoFunds, - WithdrawConsequence::WouldDie => WithdrawConsequence::WouldDie, - WithdrawConsequence::UnknownAsset => WithdrawConsequence::UnknownAsset, - WithdrawConsequence::Underflow => WithdrawConsequence::Underflow, - WithdrawConsequence::Overflow => WithdrawConsequence::Overflow, - WithdrawConsequence::Frozen => WithdrawConsequence::Frozen, - WithdrawConsequence::Success => WithdrawConsequence::Success, - _ => WithdrawConsequence::NoFunds, - } - } - _ => match Self::balance(asset, who).checked_sub(&amount) { - Some(_) => WithdrawConsequence::Success, - None => WithdrawConsequence::NoFunds, - }, - } - } -} - -impl fungibles::Mutate<::AccountId> for Pallet -where - T: orml_tokens::Config, -{ - fn mint_into( - asset: Self::AssetId, - who: &::AccountId, - amount: Self::Balance, - ) -> DispatchResult { - //Self::do_mint(asset, who, amount, None) - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible mint_into {:?}", asset); - - let value: u128 = match amount.try_into() { - Ok(val) => val, - Err(_) => return Err(DispatchError::Other("Bad amount to value conversion")), - }; - - match asset { - AssetIds::NativeAssetId(NativeCurrency::Here) => { - let this_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return Err(DispatchError::Other( - "Bad amount to this parachain value conversion", - )) - } - }; - - as fungible::Mutate>::mint_into( - who, - this_amount, - ) - } - AssetIds::NativeAssetId(NativeCurrency::Parent) => { - let parent_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return Err(DispatchError::Other( - "Bad amount to relay chain value conversion", - )) - } - }; - - as fungibles::Mutate>::mint_into( - AssetIds::NativeAssetId(NativeCurrency::Parent), - who, - parent_amount, - ) - } - AssetIds::ForeignAssetId(fid) => { - let target_collection_id = match >::get(fid) { - Some(v) => v, - None => { - return Err(DispatchError::Other( - "Associated collection not found for asset", - )) - } - }; - let collection = - FungibleHandle::cast(>::try_get(target_collection_id)?); - let account = T::CrossAccountId::from_sub(who.clone()); - - let amount_data: pallet_fungible::CreateItemData = (account.clone(), value); - - pallet_fungible::Pallet::::create_item_foreign( - &collection, - &account, - amount_data, - &Unlimited, - )?; - - Ok(()) - } - } - } - - fn burn_from( - asset: Self::AssetId, - who: &::AccountId, - amount: Self::Balance, - ) -> Result { - // let f = DebitFlags { keep_alive: false, best_effort: false }; - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible burn_from"); - - let value: u128 = match amount.try_into() { - Ok(val) => val, - Err(_) => return Err(DispatchError::Other("Bad amount to value conversion")), - }; - - match asset { - AssetIds::NativeAssetId(NativeCurrency::Here) => { - let this_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return Err(DispatchError::Other( - "Bad amount to this parachain value conversion", - )) - } - }; - - match as fungible::Mutate>::burn_from( - who, - this_amount, - ) { - Ok(_) => Ok(amount), - Err(e) => Err(e), - } - } - AssetIds::NativeAssetId(NativeCurrency::Parent) => { - let parent_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return Err(DispatchError::Other( - "Bad amount to relay chain value conversion", - )) - } - }; - - match as fungibles::Mutate>::burn_from( - AssetIds::NativeAssetId(NativeCurrency::Parent), - who, - parent_amount, - ) { - Ok(_) => Ok(amount), - Err(e) => Err(e), - } - } - AssetIds::ForeignAssetId(fid) => { - let target_collection_id = match >::get(fid) { - Some(v) => v, - None => { - return Err(DispatchError::Other( - "Associated collection not found for asset", - )) - } - }; - let collection = - FungibleHandle::cast(>::try_get(target_collection_id)?); - pallet_fungible::Pallet::::burn_foreign( - &collection, - &T::CrossAccountId::from_sub(who.clone()), - value, - )?; - - Ok(amount) - } - } - } - - fn slash( - asset: Self::AssetId, - who: &::AccountId, - amount: Self::Balance, - ) -> Result { - // let f = DebitFlags { keep_alive: false, best_effort: true }; - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible slash"); - Self::burn_from(asset, who, amount)?; - Ok(amount) - } -} - -impl fungibles::Transfer for Pallet -where - T: orml_tokens::Config, -{ - fn transfer( - asset: Self::AssetId, - source: &::AccountId, - dest: &::AccountId, - amount: Self::Balance, - keep_alive: bool, - ) -> Result { - // let f = TransferFlags { keep_alive, best_effort: false, burn_dust: false }; - log::trace!(target: "fassets::impl_foreing_assets", "impl_fungible transfer"); - - let value: u128 = match amount.try_into() { - Ok(val) => val, - Err(_) => return Err(DispatchError::Other("Bad amount to value conversion")), - }; - - match asset { - AssetIds::NativeAssetId(NativeCurrency::Here) => { - let this_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return Err(DispatchError::Other( - "Bad amount to this parachain value conversion", - )) - } - }; - - match as fungible::Transfer>::transfer( - source, - dest, - this_amount, - keep_alive, - ) { - Ok(_) => Ok(amount), - Err(_) => Err(DispatchError::Other( - "Bad amount to relay chain value conversion", - )), - } - } - AssetIds::NativeAssetId(NativeCurrency::Parent) => { - let parent_amount: ::Balance = match value.try_into() { - Ok(val) => val, - Err(_) => { - return Err(DispatchError::Other( - "Bad amount to relay chain value conversion", - )) - } - }; - - match as fungibles::Transfer>::transfer( - AssetIds::NativeAssetId(NativeCurrency::Parent), - source, - dest, - parent_amount, - keep_alive, - ) { - Ok(_) => Ok(amount), - Err(e) => Err(e), - } - } - AssetIds::ForeignAssetId(fid) => { - let target_collection_id = match >::get(fid) { - Some(v) => v, - None => { - return Err(DispatchError::Other( - "Associated collection not found for asset", - )) - } - }; - let collection = - FungibleHandle::cast(>::try_get(target_collection_id)?); - - pallet_fungible::Pallet::::transfer( - &collection, - &T::CrossAccountId::from_sub(source.clone()), - &T::CrossAccountId::from_sub(dest.clone()), - value, - &Unlimited, - )?; - - Ok(amount) - } - } - } -} --- a/pallets/foreing-assets/src/lib.rs +++ /dev/null @@ -1,497 +0,0 @@ -// Copyright 2019-2022 Unique Network (Gibraltar) Ltd. -// This file is part of Unique Network. - -// Unique Network is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Unique Network is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Unique Network. If not, see . - -//! # Foreing assets -//! -//! - [`Config`] -//! - [`Call`] -//! - [`Pallet`] -//! -//! ## Overview -//! -//! The foreing assests pallet provides functions for: -//! -//! - Local and foreign assets management. The foreign assets can be updated without runtime upgrade. -//! - Bounds between asset and target collection for cross chain transfer and inner transfers. -//! -//! ## Overview -//! -//! Under construction - -#![cfg_attr(not(feature = "std"), no_std)] -#![allow(clippy::unused_unit)] - -use frame_support::{ - dispatch::DispatchResult, - ensure, - pallet_prelude::*, - traits::{fungible, fungibles, Currency, EnsureOrigin}, - transactional, RuntimeDebug, -}; -use frame_system::pallet_prelude::*; -use up_data_structs::{CollectionMode}; -use pallet_fungible::{Pallet as PalletFungible}; -use scale_info::{TypeInfo}; -use sp_runtime::{ - traits::{One, Zero}, - ArithmeticError, -}; -use sp_std::{boxed::Box, vec::Vec}; -use up_data_structs::{CollectionId, TokenId, CreateCollectionData}; - -// NOTE:v1::MultiLocation is used in storages, we would need to do migration if upgrade the -// MultiLocation in the future. -use xcm::opaque::latest::prelude::XcmError; -use xcm::{v1::MultiLocation, VersionedMultiLocation}; -use xcm_executor::{traits::WeightTrader, Assets}; - -use pallet_common::erc::CrossAccountId; - -#[cfg(feature = "std")] -use serde::{Deserialize, Serialize}; - -// TODO: Move to primitives -// Id of native currency. -// 0 - QTZ\UNQ -// 1 - KSM\DOT -#[derive( - Clone, - Copy, - Eq, - PartialEq, - PartialOrd, - Ord, - MaxEncodedLen, - RuntimeDebug, - Encode, - Decode, - TypeInfo, -)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum NativeCurrency { - Here = 0, - Parent = 1, -} - -#[derive( - Clone, - Copy, - Eq, - PartialEq, - PartialOrd, - Ord, - MaxEncodedLen, - RuntimeDebug, - Encode, - Decode, - TypeInfo, -)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum AssetIds { - ForeignAssetId(ForeignAssetId), - NativeAssetId(NativeCurrency), -} - -pub trait TryAsForeing { - fn try_as_foreing(asset: T) -> Option; -} - -impl TryAsForeing for AssetIds { - fn try_as_foreing(asset: AssetIds) -> Option { - match asset { - AssetIds::ForeignAssetId(id) => Some(id), - _ => None, - } - } -} - -pub type ForeignAssetId = u32; -pub type CurrencyId = AssetIds; - -mod impl_fungibles; -mod weights; - -pub use module::*; -pub use weights::WeightInfo; - -/// Type alias for currency balance. -pub type BalanceOf = - <::Currency as Currency<::AccountId>>::Balance; - -/// A mapping between ForeignAssetId and AssetMetadata. -pub trait AssetIdMapping { - /// Returns the AssetMetadata associated with a given ForeignAssetId. - fn get_asset_metadata(foreign_asset_id: ForeignAssetId) -> Option; - /// Returns the MultiLocation associated with a given ForeignAssetId. - fn get_multi_location(foreign_asset_id: ForeignAssetId) -> Option; - /// Returns the CurrencyId associated with a given MultiLocation. - fn get_currency_id(multi_location: MultiLocation) -> Option; -} - -pub struct XcmForeignAssetIdMapping(sp_std::marker::PhantomData); - -impl AssetIdMapping>> - for XcmForeignAssetIdMapping -{ - fn get_asset_metadata(foreign_asset_id: ForeignAssetId) -> Option>> { - log::trace!(target: "fassets::asset_metadatas", "call"); - Pallet::::asset_metadatas(AssetIds::ForeignAssetId(foreign_asset_id)) - } - - fn get_multi_location(foreign_asset_id: ForeignAssetId) -> Option { - log::trace!(target: "fassets::get_multi_location", "call"); - Pallet::::foreign_asset_locations(foreign_asset_id) - } - - fn get_currency_id(multi_location: MultiLocation) -> Option { - log::trace!(target: "fassets::get_currency_id", "call"); - Some(AssetIds::ForeignAssetId( - Pallet::::location_to_currency_ids(multi_location).unwrap_or(0), - )) - } -} - -#[frame_support::pallet] -pub mod module { - use super::*; - - #[pallet::config] - pub trait Config: - frame_system::Config - + pallet_common::Config - + pallet_fungible::Config - + orml_tokens::Config - + pallet_balances::Config - { - /// The overarching event type. - type Event: From> + IsType<::Event>; - - /// Currency type for withdraw and balance storage. - type Currency: Currency; - - /// Required origin for registering asset. - type RegisterOrigin: EnsureOrigin; - - /// Weight information for the extrinsics in this module. - type WeightInfo: WeightInfo; - } - - #[derive(Clone, Eq, PartialEq, RuntimeDebug, Encode, Decode, TypeInfo)] - pub struct AssetMetadata { - pub name: Vec, - pub symbol: Vec, - pub decimals: u8, - pub minimal_balance: Balance, - } - - #[pallet::error] - pub enum Error { - /// The given location could not be used (e.g. because it cannot be expressed in the - /// desired version of XCM). - BadLocation, - /// MultiLocation existed - MultiLocationExisted, - /// AssetId not exists - AssetIdNotExists, - /// AssetId exists - AssetIdExisted, - } - - #[pallet::event] - #[pallet::generate_deposit(fn deposit_event)] - pub enum Event { - /// The foreign asset registered. - ForeignAssetRegistered { - asset_id: ForeignAssetId, - asset_address: MultiLocation, - metadata: AssetMetadata>, - }, - /// The foreign asset updated. - ForeignAssetUpdated { - asset_id: ForeignAssetId, - asset_address: MultiLocation, - metadata: AssetMetadata>, - }, - /// The asset registered. - AssetRegistered { - asset_id: AssetIds, - metadata: AssetMetadata>, - }, - /// The asset updated. - AssetUpdated { - asset_id: AssetIds, - metadata: AssetMetadata>, - }, - } - - /// Next available Foreign AssetId ID. - /// - /// NextForeignAssetId: ForeignAssetId - #[pallet::storage] - #[pallet::getter(fn next_foreign_asset_id)] - pub type NextForeignAssetId = StorageValue<_, ForeignAssetId, ValueQuery>; - /// The storages for MultiLocations. - /// - /// ForeignAssetLocations: map ForeignAssetId => Option - #[pallet::storage] - #[pallet::getter(fn foreign_asset_locations)] - pub type ForeignAssetLocations = - StorageMap<_, Twox64Concat, ForeignAssetId, MultiLocation, OptionQuery>; - - /// The storages for CurrencyIds. - /// - /// LocationToCurrencyIds: map MultiLocation => Option - #[pallet::storage] - #[pallet::getter(fn location_to_currency_ids)] - pub type LocationToCurrencyIds = - StorageMap<_, Twox64Concat, MultiLocation, ForeignAssetId, OptionQuery>; - - /// The storages for AssetMetadatas. - /// - /// AssetMetadatas: map AssetIds => Option - #[pallet::storage] - #[pallet::getter(fn asset_metadatas)] - pub type AssetMetadatas = - StorageMap<_, Twox64Concat, AssetIds, AssetMetadata>, OptionQuery>; - - /// The storages for assets to fungible collection binding - /// - #[pallet::storage] - #[pallet::getter(fn asset_binding)] - pub type AssetBinding = - StorageMap<_, Twox64Concat, ForeignAssetId, CollectionId, OptionQuery>; - - #[pallet::pallet] - #[pallet::without_storage_info] - pub struct Pallet(_); - - #[pallet::call] - impl Pallet { - #[pallet::weight(::WeightInfo::register_foreign_asset())] - #[transactional] - pub fn register_foreign_asset( - origin: OriginFor, - owner: T::AccountId, - location: Box, - metadata: Box>>, - ) -> DispatchResult { - T::RegisterOrigin::ensure_origin(origin.clone())?; - - let location: MultiLocation = (*location) - .try_into() - .map_err(|()| Error::::BadLocation)?; - - let md = metadata.clone(); - let name: Vec = md.name.into_iter().map(|x| x as u16).collect::>(); - let mut description: Vec = "Foreing assets collection for " - .encode_utf16() - .collect::>(); - description.append(&mut name.clone()); - - let data: CreateCollectionData = CreateCollectionData { - name: name.try_into().unwrap(), - description: description.try_into().unwrap(), - mode: CollectionMode::Fungible(18), - ..Default::default() - }; - - let bounded_collection_id = >::init_foreign_collection( - CrossAccountId::from_sub(owner), - data, - )?; - let foreign_asset_id = - Self::do_register_foreign_asset(&location, &metadata, bounded_collection_id)?; - - Self::deposit_event(Event::::ForeignAssetRegistered { - asset_id: foreign_asset_id, - asset_address: location, - metadata: *metadata, - }); - Ok(()) - } - - #[pallet::weight(::WeightInfo::update_foreign_asset())] - #[transactional] - pub fn update_foreign_asset( - origin: OriginFor, - foreign_asset_id: ForeignAssetId, - location: Box, - metadata: Box>>, - ) -> DispatchResult { - T::RegisterOrigin::ensure_origin(origin)?; - - let location: MultiLocation = (*location) - .try_into() - .map_err(|()| Error::::BadLocation)?; - Self::do_update_foreign_asset(foreign_asset_id, &location, &metadata)?; - - Self::deposit_event(Event::::ForeignAssetUpdated { - asset_id: foreign_asset_id, - asset_address: location, - metadata: *metadata, - }); - Ok(()) - } - } -} - -impl Pallet { - fn get_next_foreign_asset_id() -> Result { - NextForeignAssetId::::try_mutate(|current| -> Result { - let id = *current; - *current = current - .checked_add(One::one()) - .ok_or(ArithmeticError::Overflow)?; - Ok(id) - }) - } - - fn do_register_foreign_asset( - location: &MultiLocation, - metadata: &AssetMetadata>, - bounded_collection_id: CollectionId, - ) -> Result { - let foreign_asset_id = Self::get_next_foreign_asset_id()?; - LocationToCurrencyIds::::try_mutate(location, |maybe_currency_ids| -> DispatchResult { - ensure!( - maybe_currency_ids.is_none(), - Error::::MultiLocationExisted - ); - *maybe_currency_ids = Some(foreign_asset_id); - // *maybe_currency_ids = Some(CurrencyId::ForeignAsset(foreign_asset_id)); - - ForeignAssetLocations::::try_mutate( - foreign_asset_id, - |maybe_location| -> DispatchResult { - ensure!(maybe_location.is_none(), Error::::MultiLocationExisted); - *maybe_location = Some(location.clone()); - - AssetMetadatas::::try_mutate( - AssetIds::ForeignAssetId(foreign_asset_id), - |maybe_asset_metadatas| -> DispatchResult { - ensure!(maybe_asset_metadatas.is_none(), Error::::AssetIdExisted); - *maybe_asset_metadatas = Some(metadata.clone()); - Ok(()) - }, - ) - }, - )?; - - AssetBinding::::try_mutate(foreign_asset_id, |collection_id| -> DispatchResult { - *collection_id = Some(bounded_collection_id); - Ok(()) - }) - })?; - - Ok(foreign_asset_id) - } - - fn do_update_foreign_asset( - foreign_asset_id: ForeignAssetId, - location: &MultiLocation, - metadata: &AssetMetadata>, - ) -> DispatchResult { - ForeignAssetLocations::::try_mutate( - foreign_asset_id, - |maybe_multi_locations| -> DispatchResult { - let old_multi_locations = maybe_multi_locations - .as_mut() - .ok_or(Error::::AssetIdNotExists)?; - - AssetMetadatas::::try_mutate( - AssetIds::ForeignAssetId(foreign_asset_id), - |maybe_asset_metadatas| -> DispatchResult { - ensure!( - maybe_asset_metadatas.is_some(), - Error::::AssetIdNotExists - ); - - // modify location - if location != old_multi_locations { - LocationToCurrencyIds::::remove(old_multi_locations.clone()); - LocationToCurrencyIds::::try_mutate( - location, - |maybe_currency_ids| -> DispatchResult { - ensure!( - maybe_currency_ids.is_none(), - Error::::MultiLocationExisted - ); - // *maybe_currency_ids = Some(CurrencyId::ForeignAsset(foreign_asset_id)); - *maybe_currency_ids = Some(foreign_asset_id); - Ok(()) - }, - )?; - } - *maybe_asset_metadatas = Some(metadata.clone()); - *old_multi_locations = location.clone(); - Ok(()) - }, - ) - }, - ) - } -} - -pub use frame_support::{ - traits::{ - fungibles::{Balanced, CreditOf}, - tokens::currency::Currency as CurrencyT, - OnUnbalanced as OnUnbalancedT, - }, - weights::{WeightToFeePolynomial, WeightToFee}, -}; - -pub struct FreeForAll< - WeightToFee: WeightToFeePolynomial, - AssetId: Get, - AccountId, - Currency: CurrencyT, - OnUnbalanced: OnUnbalancedT, ->( - Weight, - Currency::Balance, - PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>, -); - -impl< - WeightToFee: WeightToFeePolynomial, - AssetId: Get, - AccountId, - Currency: CurrencyT, - OnUnbalanced: OnUnbalancedT, - > WeightTrader for FreeForAll -{ - fn new() -> Self { - Self(0, Zero::zero(), PhantomData) - } - - fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result { - log::trace!(target: "fassets::weight", "buy_weight weight: {:?}, payment: {:?}", weight, payment); - Ok(payment) - } -} -impl< - WeightToFee: WeightToFeePolynomial, - AssetId: Get, - AccountId, - Currency: CurrencyT, - OnUnbalanced: OnUnbalancedT, - > Drop for FreeForAll -{ - fn drop(&mut self) { - OnUnbalanced::on_unbalanced(Currency::issue(self.1)); - } -} --- a/pallets/foreing-assets/src/weights.rs +++ /dev/null @@ -1,43 +0,0 @@ - -#![cfg_attr(rustfmt, rustfmt_skip)] -#![allow(unused_parens)] -#![allow(unused_imports)] -#![allow(clippy::unnecessary_cast)] - -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; -use sp_std::marker::PhantomData; - -/// Weight functions needed for module_asset_registry. -pub trait WeightInfo { - fn register_foreign_asset() -> Weight; - fn update_foreign_asset() -> Weight; -} - -/// Weights for module_asset_registry using the Acala node and recommended hardware. -pub struct AcalaWeight(PhantomData); -impl WeightInfo for AcalaWeight { - fn register_foreign_asset() -> Weight { - (29_819_000 as Weight) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) - } - fn update_foreign_asset() -> Weight { - (25_119_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } -} - -// For backwards compatibility and tests -impl WeightInfo for () { - fn register_foreign_asset() -> Weight { - (29_819_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(2 as Weight)) - .saturating_add(RocksDbWeight::get().writes(3 as Weight)) - } - fn update_foreign_asset() -> Weight { - (25_119_000 as Weight) - .saturating_add(RocksDbWeight::get().reads(1 as Weight)) - .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } -} \ No newline at end of file --- a/runtime/common/config/orml.rs +++ b/runtime/common/config/orml.rs @@ -26,7 +26,7 @@ use xcm_builder::LocationInverter; use xcm_executor::XcmExecutor; use sp_std::{vec, vec::Vec}; -use pallet_foreing_assets::{CurrencyId, NativeCurrency}; +use pallet_foreign_assets::{CurrencyId, NativeCurrency}; use crate::{ Runtime, Event, RelayChainBlockNumberProvider, runtime_common::config::{ --- a/runtime/common/config/pallets/foreign_asset.rs +++ b/runtime/common/config/pallets/foreign_asset.rs @@ -1,7 +1,7 @@ use crate::{Runtime, Event, Balances}; use up_common::types::AccountId; -impl pallet_foreing_assets::Config for Runtime { +impl pallet_foreign_assets::Config for Runtime { type Event = Event; type Currency = Balances; type RegisterOrigin = frame_system::EnsureRoot; --- a/runtime/common/config/xcm/foreignassets.rs +++ b/runtime/common/config/xcm/foreignassets.rs @@ -23,12 +23,12 @@ use xcm::latest::MultiAsset; use xcm_builder::{FungiblesAdapter, ConvertedConcreteAssetId}; use xcm_executor::traits::{Convert as ConvertXcm, JustTry, FilterAssetLocation}; -use pallet_foreing_assets::{ - AssetIds, AssetIdMapping, XcmForeignAssetIdMapping, NativeCurrency, FreeForAll, TryAsForeing, +use pallet_foreign_assets::{ + AssetIds, AssetIdMapping, XcmForeignAssetIdMapping, NativeCurrency, FreeForAll, TryAsForeign, ForeignAssetId, CurrencyId, }; use sp_std::{borrow::Borrow, marker::PhantomData}; -use crate::{Runtime, Balances, ParachainInfo, PolkadotXcm, ForeingAssets}; +use crate::{Runtime, Balances, ParachainInfo, PolkadotXcm, ForeignAssets}; use super::{LocationToAccountId, RelayLocation}; @@ -39,15 +39,15 @@ } /// Allow checking in assets that have issuance > 0. -pub struct NonZeroIssuance(PhantomData<(AccountId, ForeingAssets)>); +pub struct NonZeroIssuance(PhantomData<(AccountId, ForeignAssets)>); -impl Contains<>::AssetId> - for NonZeroIssuance +impl Contains<>::AssetId> + for NonZeroIssuance where - ForeingAssets: fungibles::Inspect, + ForeignAssets: fungibles::Inspect, { - fn contains(id: &>::AssetId) -> bool { - !ForeingAssets::total_issuance(*id).is_zero() + fn contains(id: &>::AssetId) -> bool { + !ForeignAssets::total_issuance(*id).is_zero() } } @@ -56,7 +56,7 @@ ConvertXcm for AsInnerId where AssetId: Borrow, - AssetId: TryAsForeing, + AssetId: TryAsForeign, AssetIds: Borrow, { fn convert_ref(id: impl Borrow) -> Result { @@ -112,7 +112,7 @@ )); } - match >::try_as_foreing(asset_id.clone()) { + match >::try_as_foreign(asset_id.clone()) { Some(fid) => match XcmForeignAssetIdMapping::::get_multi_location(fid) { Some(location) => Ok(location), None => Err(()), @@ -125,7 +125,7 @@ /// Means for transacting assets besides the native currency on this chain. pub type FungiblesTransactor = FungiblesAdapter< // Use this fungibles implementation: - ForeingAssets, + ForeignAssets, // Use this currency when it is a fungible asset matching the given location or name: ConvertedConcreteAssetId, JustTry>, // Convert an XCM MultiLocation into a local account id: @@ -134,7 +134,7 @@ AccountId, // We only want to allow teleports of known assets. We use non-zero issuance as an indication // that this asset is known. - NonZeroIssuance, + NonZeroIssuance, // The account to use for tracking teleports. CheckingAccount, >; --- a/runtime/common/config/xcm/nativeassets.rs +++ b/runtime/common/config/xcm/nativeassets.rs @@ -30,7 +30,7 @@ Assets, traits::{MatchesFungible, WeightTrader}, }; -use pallet_foreing_assets::{AssetIds, NativeCurrency}; +use pallet_foreign_assets::{AssetIds, NativeCurrency}; use sp_std::marker::PhantomData; use crate::{Balances, ParachainInfo}; use super::{LocationToAccountId, RelayLocation}; --- a/runtime/common/construct_runtime/mod.rs +++ b/runtime/common/construct_runtime/mod.rs @@ -81,7 +81,7 @@ RmrkEquip: pallet_proxy_rmrk_equip::{Pallet, Call, Storage, Event} = 72, #[runtimes(opal)] - ForeingAssets: pallet_foreing_assets::{Pallet, Call, Storage, Event} = 80, + ForeignAssets: pallet_foreign_assets::{Pallet, Call, Storage, Event} = 80, // Frontier EVM: pallet_evm::{Pallet, Config, Call, Storage, Event} = 100, --- a/runtime/opal/Cargo.toml +++ b/runtime/opal/Cargo.toml @@ -123,7 +123,7 @@ "orml-tokens/std", "orml-xtokens/std", "orml-traits/std", - "pallet-foreing-assets/std" + "pallet-foreign-assets/std" ] limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing'] opal-runtime = ['refungible', 'scheduler', 'rmrk', 'foreign-assets'] @@ -460,7 +460,7 @@ fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" } evm-coder = { default-features = false, path = '../../crates/evm-coder' } up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' } -pallet-foreing-assets = { default-features = false, path = "../../pallets/foreing-assets" } +pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" } ################################################################################ # Other Dependencies --- a/runtime/quartz/Cargo.toml +++ b/runtime/quartz/Cargo.toml @@ -123,7 +123,7 @@ "orml-tokens/std", "orml-xtokens/std", "orml-traits/std", - "pallet-foreing-assets/std" + "pallet-foreign-assets/std" ] limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing'] quartz-runtime = [] @@ -468,7 +468,7 @@ fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" } evm-coder = { default-features = false, path = '../../crates/evm-coder' } up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' } -pallet-foreing-assets = { default-features = false, path = "../../pallets/foreing-assets" } +pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" } ################################################################################ # Other Dependencies --- a/runtime/unique/Cargo.toml +++ b/runtime/unique/Cargo.toml @@ -124,7 +124,7 @@ "orml-tokens/std", "orml-xtokens/std", "orml-traits/std", - "pallet-foreing-assets/std" + "pallet-foreign-assets/std" ] limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing'] unique-runtime = [] @@ -460,7 +460,7 @@ fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.27" } evm-coder = { default-features = false, path = '../../crates/evm-coder' } up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.27' } -pallet-foreing-assets = { default-features = false, path = "../../pallets/foreing-assets" } +pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" } ################################################################################ # Other Dependencies -- gitstuff