Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions node/primitives/src/xcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,16 @@ impl From<XcmBaseWeight> for u64 {
x.0.into()
}
}

/// represent the xcmp transact type
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode)]
pub enum ParachainTransactProxyType {
Primary = 0,
Derived = 1,
}

#[repr(u16)]
pub enum ParachainDerivedProxyAccountType {
Salp = 0,
Staking = 1,
}
83 changes: 68 additions & 15 deletions pallets/salp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,11 @@ pub mod pallet {
PalletId,
};
use frame_system::pallet_prelude::*;
use node_primitives::{BancorHandler, CurrencyId, LeasePeriod, ParaId, TransferOriginType};
use orml_traits::{currency::TransferAll, MultiCurrency, MultiReservableCurrency};
use node_primitives::{
BancorHandler, CurrencyId, LeasePeriod, ParaId, ParachainTransactProxyType,
TransferOriginType,
};
use orml_traits::{currency::TransferAll, MultiCurrency, MultiReservableCurrency, XcmTransfer};
use polkadot_parachain::primitives::Id as PolkadotParaId;
use sp_arithmetic::Percent;
use sp_std::{convert::TryInto, prelude::*};
Expand Down Expand Up @@ -256,8 +259,13 @@ pub mod pallet {
/// Weight information for the extrinsics in this module.
type WeightInfo: WeightInfo;

/// Parachain Id
type SelfParaId: Get<u32>;

/// Weight to Fee calculator
type WeightToFee: WeightToFeePolynomial<Balance = BalanceOf<Self>>;

/// Xcm weight
#[pallet::constant]
type BaseXcmWeight: Get<u64>;

Expand All @@ -267,13 +275,21 @@ pub mod pallet {
#[pallet::constant]
type WithdrawWeight: Get<u64>;

type WeightToFee: WeightToFeePolynomial<Balance = BalanceOf<Self>>;

#[pallet::constant]
type AddProxyWeight: Get<u64>;

#[pallet::constant]
type RemoveProxyWeight: Get<u64>;

/// The interface to Cross-chain transfer.
type XcmTransfer: XcmTransfer<AccountIdOf<Self>, BalanceOf<Self>, CurrencyId>;

/// The sovereign sub-account for where the staking currencies are sent to.
#[pallet::constant]
type SovereignSubAccountLocation: Get<MultiLocation>;

#[pallet::constant]
type TransactType: Get<ParachainTransactProxyType>;
}

#[pallet::pallet]
Expand Down Expand Up @@ -316,6 +332,8 @@ pub mod pallet {
/// Proxy
ProxyAdded(AccountIdOf<T>),
ProxyRemoved(AccountIdOf<T>),
/// Mint
Minted(AccountIdOf<T>, BalanceOf<T>),
}

#[pallet::error]
Expand Down Expand Up @@ -568,7 +586,6 @@ pub mod pallet {
Ok(())
}

/// TODO: Refactor the docs.
/// Contribute to a crowd sale. This will transfer some balance over to fund a parachain
/// slot. It will be withdrawable in two instances: the parachain becomes retired; or the
/// slot is unable to be purchased and the timeout expires.
Expand All @@ -593,9 +610,10 @@ pub mod pallet {
let (contributed, status) = Self::contribution(fund.trie_index, &who);
ensure!(status == ContributionStatus::Idle, Error::<T>::InvalidContributionStatus);

if is_proxy {
Self::xcm_ump_contribute(origin, index, value)
.map_err(|_e| Error::<T>::XcmFailed)?;
if (!is_proxy && T::XcmTransferOrigin::get() == TransferOriginType::FromRelayChain) ||
T::TransactType::get() == ParachainTransactProxyType::Primary
{
T::MultiCurrency::reserve(T::RelayChainToken::get(), &who, value)?;
}

Self::put_contribution(
Expand All @@ -605,8 +623,16 @@ pub mod pallet {
ContributionStatus::Contributing(value),
);

Self::deposit_event(Event::Contributing(who, index, value));
Self::deposit_event(Event::Contributing(who.clone(), index, value.clone()));

if !is_proxy {
Self::xcm_ump_contribute(origin, index, value)
.map_err(|_e| Error::<T>::XcmFailed)?;
} else {
if T::TransactType::get() == ParachainTransactProxyType::Derived {
Self::xcm_ump_transfer(who.clone(), value)?;
}
}
Ok(())
}

Expand All @@ -623,7 +649,6 @@ pub mod pallet {
is_success: bool,
) -> DispatchResult {
T::EnsureConfirmAsMultiSig::ensure_origin(origin)?;

let fund = Self::funds(index).ok_or(Error::<T>::InvalidParaId)?;
let can_confirm = fund.status == FundStatus::Ongoing ||
fund.status == FundStatus::Failed ||
Expand All @@ -649,7 +674,9 @@ pub mod pallet {
FundInfo { raised: fund.raised.saturating_add(contributing), ..fund };
Funds::<T>::insert(index, Some(fund_new));

if T::XcmTransferOrigin::get() == TransferOriginType::FromRelayChain {
if T::TransactType::get() == ParachainTransactProxyType::Primary &&
T::XcmTransferOrigin::get() == TransferOriginType::FromRelayChain
{
T::MultiCurrency::withdraw(T::RelayChainToken::get(), &who, contributing)?;
}

Expand Down Expand Up @@ -697,7 +724,7 @@ pub mod pallet {
let can = fund.status == FundStatus::Failed || fund.status == FundStatus::Retired;
ensure!(can, Error::<T>::InvalidFundStatus);

if is_proxy {
if !is_proxy {
Self::xcm_ump_withdraw(origin, index).map_err(|_| Error::<T>::XcmFailed)?;
}

Expand Down Expand Up @@ -775,7 +802,7 @@ pub mod pallet {
Error::<T>::NotEnoughReservedAssetsToRefund
);

if is_proxy {
if !is_proxy {
Self::xcm_ump_redeem(origin, index, contributed)
.map_err(|_| Error::<T>::XcmFailed)?;
}
Expand Down Expand Up @@ -874,7 +901,7 @@ pub mod pallet {
let status = Self::redeem_status(who.clone(), (index, fund.first_slot, fund.last_slot));
ensure!(status == RedeemStatus::Idle, Error::<T>::InvalidRedeemStatus);

if is_proxy {
if !is_proxy {
Self::xcm_ump_redeem(origin.clone(), index, value)
.map_err(|_| Error::<T>::XcmFailed)?;
}
Expand Down Expand Up @@ -985,7 +1012,6 @@ pub mod pallet {
let mut fund = Self::funds(index).ok_or(Error::<T>::InvalidParaId)?;
ensure!(fund.status == FundStatus::End, Error::<T>::InvalidFundStatus);

// TODO: Delete element when iter? Fix it?
let mut refund_count = 0u32;
// Try killing the crowdloan child trie and Assume everyone will be refunded.
let contributions = Self::contribution_iterator(fund.trie_index);
Expand Down Expand Up @@ -1044,6 +1070,23 @@ pub mod pallet {

Ok(())
}

/// transfer to parachain salp account
#[pallet::weight((
0,
DispatchClass::Normal,
Pays::No
))]
#[transactional]
pub fn mint(origin: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {
let who = ensure_signed(origin)?;

Self::xcm_ump_transfer(who.clone(), amount.clone())?;

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

Ok(())
}
}

#[pallet::hooks]
Expand Down Expand Up @@ -1260,5 +1303,15 @@ pub mod pallet {
false,
)
}

fn xcm_ump_transfer(who: AccountIdOf<T>, amount: BalanceOf<T>) -> DispatchResult {
T::XcmTransfer::transfer(
who.clone(),
T::RelayChainToken::get(),
amount,
T::SovereignSubAccountLocation::get(),
3 * T::BaseXcmWeight::get(),
)
}
}
}
43 changes: 42 additions & 1 deletion pallets/salp/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ use frame_support::{
PalletId,
};
use frame_system::RawOrigin;
use node_primitives::{Amount, Balance, CurrencyId, TokenSymbol, TransferOriginType};
use node_primitives::{
Amount, Balance, CurrencyId, ParachainTransactProxyType, TokenSymbol, TransferOriginType,
};
use sp_arithmetic::Percent;
use sp_core::H256;
use sp_runtime::{
Expand Down Expand Up @@ -183,6 +185,13 @@ impl bifrost_bancor::Config for Test {
type WeightInfo = ();
}

pub fn create_x2_parachain_multilocation(_index: u16) -> MultiLocation {
MultiLocation::X2(
Junction::Parent,
Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() },
)
}

parameter_types! {
pub const SubmissionDeposit: u32 = 1;
pub const MinContribution: Balance = 10;
Expand All @@ -207,6 +216,8 @@ parameter_types! {
BRUCE,
CATHI
],2);
pub RelaychainSovereignSubAccount: MultiLocation = create_x2_parachain_multilocation(0 as u16);
pub SalpTransactType: ParachainTransactProxyType = ParachainTransactProxyType::Derived;
}

parameter_types! {
Expand Down Expand Up @@ -237,8 +248,12 @@ impl EnsureOrigin<Origin> for EnsureConfirmAsMultiSig {
}
}

use frame_support::dispatch::DispatchResult;
use orml_traits::XcmTransfer;
use smallvec::smallvec;
pub use sp_runtime::Perbill;
use xcm::{opaque::v0::MultiAsset, v0::Junction};

pub struct WeightToFee;
impl WeightToFeePolynomial for WeightToFee {
type Balance = Balance;
Expand All @@ -252,6 +267,29 @@ impl WeightToFeePolynomial for WeightToFee {
}
}

pub struct MockXTokens;

impl XcmTransfer<AccountId, Balance, CurrencyId> for MockXTokens {
fn transfer(
_who: AccountId,
_currency_id: CurrencyId,
_amount: Balance,
_dest: MultiLocation,
_dest_weight: Weight,
) -> DispatchResult {
Ok(())
}

fn transfer_multi_asset(
_who: AccountId,
_asset: MultiAsset,
_dest: MultiLocation,
_dest_weight: Weight,
) -> DispatchResult {
Ok(())
}
}

impl salp::Config for Test {
type BancorPool = Bancor;
type BifrostXcmExecutor = MockXcmExecutor;
Expand Down Expand Up @@ -279,6 +317,9 @@ impl salp::Config for Test {
type WeightToFee = WeightToFee;
type AddProxyWeight = AddProxyWeight;
type RemoveProxyWeight = RemoveProxyWeight;
type XcmTransfer = MockXTokens;
type SovereignSubAccountLocation = RelaychainSovereignSubAccount;
type TransactType = SalpTransactType;
}

pub struct SalpWeightInfo;
Expand Down
66 changes: 42 additions & 24 deletions runtime/asgard/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ use constants::{currency::*, time::*};
use cumulus_primitives_core::ParaId as CumulusParaId;
use frame_support::traits::{EnsureOrigin, OnRuntimeUpgrade};
use node_primitives::{
Amount, CurrencyId, Moment, Nonce, TokenSymbol, TransferOriginType, XcmBaseWeight,
Amount, CurrencyId, Moment, Nonce, ParachainDerivedProxyAccountType,
ParachainTransactProxyType, TokenSymbol, TransferOriginType, XcmBaseWeight,
};
// orml imports
use orml_currencies::BasicCurrencyAdapter;
Expand All @@ -93,7 +94,9 @@ use pallet_xcm::XcmPassthrough;
use polkadot_parachain::primitives::Sibling;
use sp_runtime::traits::ConvertInto;
use static_assertions::const_assert;
use xcm::v0::{BodyId, Junction::*, MultiAsset, MultiLocation, MultiLocation::*, NetworkId, Xcm};
use xcm::v0::{
BodyId, Junction, Junction::*, MultiAsset, MultiLocation, MultiLocation::*, NetworkId, Xcm,
};
use xcm_builder::{
AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
EnsureXcmOrigin, FixedWeightBounds, IsConcrete, LocationInverter, ParentAsSuperuser,
Expand Down Expand Up @@ -958,6 +961,38 @@ impl bifrost_minter_reward::Config for Runtime {
type WeightInfo = weights::bifrost_minter_reward::WeightInfo<Runtime>;
}

pub fn create_x2_parachain_multilocation(index: u16) -> MultiLocation {
MultiLocation::X2(
Junction::Parent,
Junction::AccountId32 {
network: NetworkId::Any,
id: Utility::derivative_account_id(ParachainInfo::get().into_account(), index).into(),
},
)
}

pub struct EnsureConfirmAsMultiSig;
impl EnsureOrigin<Origin> for EnsureConfirmAsMultiSig {
type Success = AccountId;

fn try_origin(o: Origin) -> Result<Self::Success, Origin> {
Into::<Result<RawOrigin<AccountId>, Origin>>::into(o).and_then(|o| match o {
RawOrigin::Signed(who) =>
if who == ConfirmMuitiSigAccount::get() {
Ok(who)
} else {
Err(Origin::from(Some(who)))
},
r => Err(Origin::from(r)),
})
}

#[cfg(feature = "runtime-benchmarks")]
fn successful_origin() -> Origin {
Origin::from(RawOrigin::Signed(Default::default()))
}
}

parameter_types! {
pub const SubmissionDeposit: Balance = 100 * DOLLARS;
pub const MinContribution: Balance = 1 * DOLLARS;
Expand All @@ -981,28 +1016,8 @@ parameter_types! {
hex!["eee4ed9bb0a1a72aa966a1a21c403835b5edac59de296be19bd8b2ad31d03f3b"].into(),
hex!["ce6072037670ca8e974fd571eae4f215a58d0bf823b998f619c3f87a911c3541"].into(),//5GjJNWYS6f2UQ9aiLexuB8qgjG8fRs2Ax4nHin1z1engpnNt
],3);
}

pub struct EnsureConfirmAsMultiSig;
impl EnsureOrigin<Origin> for EnsureConfirmAsMultiSig {
type Success = AccountId;

fn try_origin(o: Origin) -> Result<Self::Success, Origin> {
Into::<Result<RawOrigin<AccountId>, Origin>>::into(o).and_then(|o| match o {
RawOrigin::Signed(who) =>
if who == ConfirmMuitiSigAccount::get() {
Ok(who)
} else {
Err(Origin::from(Some(who)))
},
r => Err(Origin::from(r)),
})
}

#[cfg(feature = "runtime-benchmarks")]
fn successful_origin() -> Origin {
Origin::from(RawOrigin::Signed(Default::default()))
}
pub RelaychainSovereignSubAccount: MultiLocation = create_x2_parachain_multilocation(ParachainDerivedProxyAccountType::Salp as u16);
pub SalpTransactType: ParachainTransactProxyType = ParachainTransactProxyType::Derived;
}

impl bifrost_salp::Config for Runtime {
Expand Down Expand Up @@ -1033,6 +1048,9 @@ impl bifrost_salp::Config for Runtime {
type WeightToFee = WeightToFee;
type AddProxyWeight = AddProxyWeight;
type RemoveProxyWeight = RemoveProxyWeight;
type XcmTransfer = XTokens;
type SovereignSubAccountLocation = RelaychainSovereignSubAccount;
type TransactType = SalpTransactType;
}

parameter_types! {
Expand Down
Loading