Skip to content

Commit

Permalink
Support statemine asset transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
yrong committed Nov 29, 2021
1 parent 1b23084 commit c7eb1be
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 14 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions node/primitives/src/currency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ create_currency_id! {
ETH("Ethereum", 18) = 5,
KAR("Karura", 12) = 6,
ZLK("Zenlink Network Token", 18) = 7,
USDT("Tether",6) = 8,
}
}

Expand Down
1 change: 1 addition & 0 deletions node/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,6 @@ pub type TrieIndex = u32;
)]
pub enum ExtraFeeName {
SalpContribute,
StatemineTransfer,
NoExtraFee,
}
3 changes: 3 additions & 0 deletions pallets/flexible-fee/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0
smallvec = "1.4.1"
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "polkadot-v0.9.12" }
xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.12" }
xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.12"}
pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.12" }
xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.12"}
xcm-support = { path = "../../xcm-support"}
bifrost-salp = { path = "../salp" }
bifrost-runtime = { path = "../../runtime/bifrost" }
bifrost-runtime-common = { path = "../../runtime/common" }

[features]
default = ["std"]
Expand Down
4 changes: 4 additions & 0 deletions pallets/flexible-fee/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,8 @@ impl XcmTransfer<AccountId, Balance, CurrencyId> for MockXTokens {
}
}

use bifrost_runtime_common::xcm_impl::BifrostAccountIdToMultiLocation;

impl bifrost_salp::Config for Test {
type BancorPool = ();
type BifrostXcmExecutor = MockXcmExecutor;
Expand Down Expand Up @@ -549,6 +551,8 @@ impl bifrost_salp::Config for Test {
type TransactProxyType = SalpTransactProxyType;
type TransactType = SalpTransactType;
type RelayNetwork = RelayNetwork;
type XcmExecutor = ();
type AccountIdToMultiLocation = BifrostAccountIdToMultiLocation;
}

//************** Salp mock end *****************
5 changes: 5 additions & 0 deletions pallets/salp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ orml-traits = { version = "0.4.1-dev", default-features = false }

[dev-dependencies]
xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.12" }
xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.12"}
pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.12" }
pallet-multisig = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.12"}
smallvec = "1.6.1"
Expand All @@ -31,8 +32,12 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkad
orml-tokens = "0.4.1-dev"
orml-currencies = "0.4.1-dev"
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.12" }
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.12" }
cumulus-pallet-dmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.12" }
cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.12" }
bifrost-bancor = { path = "../../pallets/bancor" }
bifrost-runtime = { path = "../../runtime/bifrost" }
bifrost-runtime-common = { path = "../../runtime/common" }

[features]
default = ["std"]
Expand Down
66 changes: 66 additions & 0 deletions pallets/salp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ pub mod pallet {
};
use orml_traits::{currency::TransferAll, MultiCurrency, MultiReservableCurrency, XcmTransfer};
use sp_arithmetic::Percent;
use sp_runtime::traits::Convert;
use sp_std::prelude::*;
use xcm::latest::prelude::*;

Expand Down Expand Up @@ -212,6 +213,12 @@ pub mod pallet {

#[pallet::constant]
type RelayNetwork: Get<NetworkId>;

/// XCM executor.
type XcmExecutor: ExecuteXcm<Self::Call>;

/// Convert `T::AccountId` to `MultiLocation`.
type AccountIdToMultiLocation: Convert<AccountIdOf<Self>, MultiLocation>;
}

#[pallet::pallet]
Expand Down Expand Up @@ -254,6 +261,7 @@ pub mod pallet {
ProxyRemoved(AccountIdOf<T>),
/// Mint
Minted(AccountIdOf<T>, BalanceOf<T>),
TransferredStatemineMultiAsset(AccountIdOf<T>, BalanceOf<T>),
}

#[pallet::error]
Expand Down Expand Up @@ -296,6 +304,8 @@ pub mod pallet {
NotEnoughFreeAssetsToRedeem,
/// Don't have enough token to redeem by users
NotEnoughBalanceInRedeemPool,
ConvertFailure,
XcmExecutionFailed,
}

/// Tracker for the next available fund index
Expand Down Expand Up @@ -971,6 +981,62 @@ pub mod pallet {

Ok(())
}

/// transfer asset to statemine
#[pallet::weight(T::WeightInfo::contribute())]
pub fn transfer_statemine_assets(
origin: OriginFor<T>,
amount: BalanceOf<T>,
asset_id: u32,
) -> DispatchResult {
let who = ensure_signed(origin)?;
let origin_location = T::AccountIdToMultiLocation::convert(who.clone());
let mut assets = MultiAssets::new(); // VersionedMultiAssets::V1(MultiAssets::new(MultiAsset))
let amount_128 =
TryInto::<u128>::try_into(amount).map_err(|_| Error::<T>::ConvertFailure)?;
let statemine_asset = MultiAsset {
id: AssetId::Concrete(MultiLocation::new(
1,
Junctions::X2(
Junction::Parachain(1000),
Junction::GeneralIndex(asset_id.into()),
),
)),
fun: Fungibility::Fungible(amount_128),
};
let dest_weight = 4 * T::BaseXcmWeight::get();
let fee_asset = MultiAsset {
id: AssetId::Concrete(MultiLocation::new(1, Junctions::Here)),
fun: Fungibility::Fungible(dest_weight.into()),
};
assets.push(statemine_asset);
assets.push(fee_asset.clone());
let msg = Xcm(vec![
WithdrawAsset(assets),
InitiateReserveWithdraw {
assets: All.into(),
reserve: MultiLocation::new(1, Junctions::X1(Junction::Parachain(1000))),
xcm: Xcm(vec![
BuyExecution {
fees: fee_asset,
weight_limit: WeightLimit::Limited(dest_weight),
},
DepositAsset {
assets: All.into(),
max_assets: 2,
beneficiary: origin_location.clone(),
},
]),
},
]);
T::XcmExecutor::execute_xcm_in_credit(origin_location, msg, dest_weight, dest_weight)
.ensure_complete()
.map_err(|_| Error::<T>::XcmExecutionFailed)?;

Self::deposit_event(Event::<T>::TransferredStatemineMultiAsset(who, amount));

Ok(())
}
}

#[pallet::hooks]
Expand Down
4 changes: 4 additions & 0 deletions pallets/salp/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ impl XcmTransfer<AccountId, Balance, CurrencyId> for MockXTokens {
}
}

use bifrost_runtime_common::xcm_impl::BifrostAccountIdToMultiLocation;

impl salp::Config for Test {
type BancorPool = Bancor;
type BifrostXcmExecutor = MockXcmExecutor;
Expand Down Expand Up @@ -298,6 +300,8 @@ impl salp::Config for Test {
type TransactProxyType = SalpTransactProxyType;
type TransactType = SalpTransactType;
type RelayNetwork = RelayNetwork;
type XcmExecutor = ();
type AccountIdToMultiLocation = BifrostAccountIdToMultiLocation;
}

pub struct SalpWeightInfo;
Expand Down
45 changes: 38 additions & 7 deletions runtime/asgard/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,14 @@ parameter_types! {
// kUSD:KSM = 400:1
ksm_per_second() * 400
);
pub UsdtPerSecond: (AssetId, u128) = (
MultiLocation::new(
1,
X2(Parachain(parachains::Statemine::ID), GeneralIndex(parachains::Statemine::USDT_ID.into()))
).into(),
// usdt:KSM = 400:1
ksm_per_second() * 400 / 1_000_000
);
}

pub struct ToTreasury;
Expand All @@ -959,6 +967,7 @@ pub type Trader = (
FixedRateOfFungible<BncPerSecond, ToTreasury>,
FixedRateOfFungible<KarPerSecond, ToTreasury>,
FixedRateOfFungible<KusdPerSecond, ToTreasury>,
FixedRateOfFungible<UsdtPerSecond, ToTreasury>,
);

pub struct XcmConfig;
Expand Down Expand Up @@ -1126,6 +1135,7 @@ orml_traits::parameter_type_with_key! {
&CurrencyId::VSBond(TokenSymbol::BNC, ..) => 10 * MILLICENTS,
&CurrencyId::VSBond(TokenSymbol::DOT, ..) => 100_000_000,
&CurrencyId::LPToken(..) => 10 * MILLICENTS,
&CurrencyId::Stable(TokenSymbol::USDT) => MICROBNC /1000,
_ => Balance::max_value() // unsupported
}
};
Expand Down Expand Up @@ -1205,6 +1215,8 @@ impl NameGetter<Call> for FeeNameGetter {
fn get_name(c: &Call) -> ExtraFeeName {
match *c {
Call::Salp(bifrost_salp::Call::contribute { .. }) => ExtraFeeName::SalpContribute,
Call::Salp(bifrost_salp::Call::transfer_statemine_assets { .. }) =>
ExtraFeeName::StatemineTransfer,
_ => ExtraFeeName::NoExtraFee,
}
}
Expand All @@ -1217,6 +1229,7 @@ impl Contains<Call> for AggregateExtraFeeFilter {
fn contains(c: &Call) -> bool {
match *c {
Call::Salp(bifrost_salp::Call::contribute { .. }) => true,
Call::Salp(bifrost_salp::Call::transfer_statemine_assets { .. }) => true,
_ => false,
}
}
Expand All @@ -1232,11 +1245,33 @@ impl Contains<Call> for ContributeFeeFilter {
}
}

pub struct StatemineTransferFeeFilter;
impl Contains<Call> for StatemineTransferFeeFilter {
fn contains(c: &Call) -> bool {
match *c {
Call::Salp(bifrost_salp::Call::transfer_statemine_assets { .. }) => true,
_ => false,
}
}
}

parameter_types! {
pub const AltFeeCurrencyExchangeRate: (u32, u32) = (1, 100);
pub SalpWeightHolder: XcmBaseWeight = XcmBaseWeight::from(4 * XCM_WEIGHT) + ContributionWeight::get() + u64::pow(2, 24).into();
pub StatemineTransferWeightHolder: XcmBaseWeight = XcmBaseWeight::from(6 * XCM_WEIGHT);
}

pub type MiscFeeHandlers = (
MiscFeeHandler<Runtime, RelayCurrencyId, WeightToFee, SalpWeightHolder, ContributeFeeFilter>,
MiscFeeHandler<
Runtime,
RelayCurrencyId,
IdentityFee<Balance>,
StatemineTransferWeightHolder,
StatemineTransferFeeFilter,
>,
);

impl bifrost_flexible_fee::Config for Runtime {
type Currency = Balances;
type DexOperator = ZenlinkProtocol;
Expand All @@ -1251,13 +1286,7 @@ impl bifrost_flexible_fee::Config for Runtime {
type OnUnbalanced = Treasury;
type WeightInfo = weights::bifrost_flexible_fee::WeightInfo<Runtime>;
type ExtraFeeMatcher = ExtraFeeMatcher<Runtime, FeeNameGetter, AggregateExtraFeeFilter>;
type MiscFeeHandler = MiscFeeHandler<
Runtime,
RelayCurrencyId,
WeightToFee,
SalpWeightHolder,
ContributeFeeFilter,
>;
type MiscFeeHandler = MiscFeeHandlers;
}

parameter_types! {
Expand Down Expand Up @@ -1361,6 +1390,8 @@ impl bifrost_salp::Config for Runtime {
type TransactProxyType = SalpProxyType;
type TransactType = SalpTransactType;
type RelayNetwork = RelayNetwork;
type XcmExecutor = XcmExecutor<XcmConfig>;
type AccountIdToMultiLocation = BifrostAccountIdToMultiLocation;
}

impl bifrost_salp_lite::Config for Runtime {
Expand Down
Loading

0 comments on commit c7eb1be

Please sign in to comment.