Skip to content

Commit

Permalink
Added PDEX Token Handler (#642)
Browse files Browse the repository at this point in the history
Handled Native-token transfer from Solochain to Polkadex Parachain. 
Partially close Polkadex-Substrate/issue-tracker#100
  • Loading branch information
Gauthamastro committed Feb 20, 2023
2 parents 90cf880 + 6750d37 commit 16249fe
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 13 deletions.
41 changes: 41 additions & 0 deletions pallets/asset-handler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ pub mod pallet {
/// Parachain Network Id
#[pallet::constant]
type ParachainNetworkId: Get<u8>;

/// Polkadex Asset
#[pallet::constant]
type PolkadexAssetId: Get<u128>;

/// PDEX Token Holder Account
type PDEXHolderAccount: Get<Self::AccountId>;
}

#[pallet::pallet]
Expand Down Expand Up @@ -660,6 +667,40 @@ pub mod pallet {
Ok(())
}

/// Asset Handler for Withdraw Extrinsic
/// # Parameters
///
/// * `asset_id`: Asset Id.
/// * `who`: Asset Holder.
/// * `amount`: Amount to be burned/locked.
pub fn handle_asset(
asset_id: u128,
who: T::AccountId,
amount: u128,
) -> Result<(), DispatchError> {
let polkadex_asset_id = T::PolkadexAssetId::get();
if polkadex_asset_id == asset_id {
Self::lock_pdex_asset(amount, who)
} else {
Self::burn_thea_asset(asset_id, who, amount)
}
}

/// Asset Locker
/// # Parameters
///
/// * `amount`: Amount to be locked.
/// * `who`: Asset Holder.
pub fn lock_pdex_asset(amount: u128, who: T::AccountId) -> DispatchResult {
let polkadex_holder_account = T::PDEXHolderAccount::get();
T::Currency::transfer(
&who,
&polkadex_holder_account,
amount.saturated_into(),
ExistenceRequirement::AllowDeath,
)
}

pub fn burn_thea_asset(
asset_id: u128,
who: T::AccountId,
Expand Down
7 changes: 7 additions & 0 deletions pallets/asset-handler/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ impl chainbridge::Config for Test {
//type PalletId = ChainbridgePalletId;
}

parameter_types! {
pub const PolkadexAssetId: u128 = 1000;
pub const PDEXHolderAccount: u64 = 10u64;
}

impl asset_handler::Config for Test {
type Event = Event;
type Currency = Balances;
Expand All @@ -153,6 +158,8 @@ impl asset_handler::Config for Test {
type TreasuryPalletId = ChainbridgePalletId;
type WeightInfo = crate::weights::WeightInfo<Test>;
type ParachainNetworkId = ParachainNetworkId;
type PolkadexAssetId = PolkadexAssetId;
type PDEXHolderAccount = PDEXHolderAccount;
}

// Build genesis storage according to the mock runtime.
Expand Down
9 changes: 9 additions & 0 deletions pallets/thea-staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ impl chainbridge::Config for Test {
type ProposalLifetime = ProposalLifetime;
}

parameter_types! {
pub const PolkadexAssetId: u128 = 1000;
pub const PDEXHolderAccount: u64 = 10u64;
}

impl asset_handler::pallet::Config for Test {
type Event = Event;
type Currency = Balances;
Expand All @@ -121,11 +126,14 @@ impl asset_handler::pallet::Config for Test {
type TreasuryPalletId = ChainbridgePalletId;
type WeightInfo = asset_handler::weights::WeightInfo<Test>;
type ParachainNetworkId = ParachainNetworkId;
type PolkadexAssetId = PolkadexAssetId;
type PDEXHolderAccount = PDEXHolderAccount;
}

parameter_types! {
pub const TheaPalletId: PalletId = PalletId(*b"THBRIDGE");
pub const WithdrawalSize: u32 = 10;
pub const ParaId: u32 = 2040;
}

impl thea::pallet::Config for Test {
Expand All @@ -134,6 +142,7 @@ impl thea::pallet::Config for Test {
type AssetCreateUpdateOrigin = frame_system::EnsureSigned<Self::AccountId>;
type TheaPalletId = TheaPalletId;
type WithdrawalSize = WithdrawalSize;
type ParaId = ParaId;
}

//defined trait for Session Change
Expand Down
39 changes: 26 additions & 13 deletions pallets/thea/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub mod pallet {
};
use thea_primitives::{
normal_deposit::Deposit,
parachain_primitives::{ParachainAsset, ParachainDeposit, ParachainWithdraw},
parachain_primitives::{AssetType, ParachainAsset, ParachainDeposit, ParachainWithdraw},
thea_types::OnSessionChange,
ApprovedWithdraw, AssetIdConverter, BLSPublicKey, TokenType,
};
Expand Down Expand Up @@ -101,6 +101,8 @@ pub mod pallet {
/// Total Withdrawals
#[pallet::constant]
type WithdrawalSize: Get<u32>;
/// Para Id
type ParaId: Get<u32>;
}

#[pallet::pallet]
Expand Down Expand Up @@ -502,14 +504,16 @@ pub mod pallet {
pay_for_remaining: bool,
) -> Result<(), DispatchError> {
ensure!(beneficiary.len() <= 100, Error::<T>::BeneficiaryTooLong);
// TODO: This will be refactored when work on withdrawal so not fixing clippy suggestion
let (network, ..) = asset_handler::pallet::Pallet::<T>::get_thea_assets(asset_id);
let network = if asset_id == T::PolkadexAssetId::get() {
1
} else {
let (network, ..) = asset_handler::pallet::Pallet::<T>::get_thea_assets(asset_id);
network
};
ensure!(network != 0, Error::<T>::UnableFindNetworkForAssetId);
let payload = Self::withdrawal_router(network, asset_id, amount, beneficiary.clone())?;
let withdrawal_nonce = <WithdrawalNonces<T>>::get(network);

let mut pending_withdrawals = <PendingWithdrawals<T>>::get(network);

// Ensure pending withdrawals have space for a new withdrawal
ensure!(!pending_withdrawals.is_full(), Error::<T>::WithdrawalNotAllowed);

Expand All @@ -536,10 +540,8 @@ pub mod pallet {
)?;

// TODO[#610]: Update Thea Staking pallet about fees collected

// Burn assets
asset_handler::pallet::Pallet::<T>::burn_thea_asset(asset_id, user.clone(), amount)?;

// Handle assets
asset_handler::pallet::Pallet::<T>::handle_asset(asset_id, user.clone(), amount)?;
let withdrawal = ApprovedWithdraw {
asset_id,
amount: amount.saturated_into(),
Expand Down Expand Up @@ -593,10 +595,21 @@ pub mod pallet {
amount: u128,
beneficiary: Vec<u8>,
) -> Result<Vec<u8>, DispatchError> {
let (_, _, asset_identifier) = asset_handler::pallet::TheaAssets::<T>::get(asset_id);
let asset_identifier: ParachainAsset =
Decode::decode(&mut &asset_identifier.to_vec()[..])
.map_err(|_| Error::<T>::FailedToDecode)?;
let asset_identifier = if asset_id != T::PolkadexAssetId::get() {
let (_, _, asset_identifier) =
asset_handler::pallet::TheaAssets::<T>::get(asset_id);
let asset_identifier: ParachainAsset =
Decode::decode(&mut &asset_identifier.to_vec()[..])
.map_err(|_| Error::<T>::FailedToDecode)?;
asset_identifier
} else {
let para_id = T::ParaId::get();
let asset_location = MultiLocation {
parents: 1,
interior: Junctions::X1(Junction::Parachain(para_id)),
};
ParachainAsset { location: asset_location, asset_type: AssetType::Fungible }
};
let asset_id = AssetId::Concrete(asset_identifier.location);
let asset_and_amount = MultiAsset { id: asset_id, fun: Fungible(amount) };
let recipient: MultiLocation = Self::get_recipient(beneficiary)?;
Expand Down
10 changes: 10 additions & 0 deletions pallets/thea/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use crate::pallet as thea;

use asset_handler::pallet::WithdrawalLimit;
use frame_support::PalletId;
use sp_core::crypto::AccountId32;
use sp_runtime::traits::AccountIdConversion;

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
Expand Down Expand Up @@ -148,6 +149,11 @@ impl chainbridge::Config for Test {
//type PalletId = ChainbridgePalletId;
}

parameter_types! {
pub const PolkadexAssetId: u128 = 1000;
pub const PDEXHolderAccount: u64 = 10u64;
}

impl asset_handler::pallet::Config for Test {
type Event = Event;
type Currency = Balances;
Expand All @@ -156,11 +162,14 @@ impl asset_handler::pallet::Config for Test {
type TreasuryPalletId = ChainbridgePalletId;
type WeightInfo = asset_handler::weights::WeightInfo<Test>;
type ParachainNetworkId = ParachainNetworkId;
type PolkadexAssetId = PolkadexAssetId;
type PDEXHolderAccount = PDEXHolderAccount;
}

parameter_types! {
pub const TheaPalletId: PalletId = PalletId(*b"THBRIDGE");
pub const WithdrawalSize: u32 = 10;
pub const ParaId: u32 = 2040;
}

impl thea::Config for Test {
Expand All @@ -169,6 +178,7 @@ impl thea::Config for Test {
type AssetCreateUpdateOrigin = frame_system::EnsureSigned<Self::AccountId>;
type TheaPalletId = TheaPalletId;
type WithdrawalSize = WithdrawalSize;
type ParaId = ParaId;
}

// Build genesis storage according to the mock runtime.
Expand Down
44 changes: 44 additions & 0 deletions pallets/thea/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,50 @@ fn test_withdraw_with_no_fee_config() {
})
}

#[test]
fn transfer_native_asset() {
new_test_ext().execute_with(|| {
let asset_id = 1000;
let para_id = 2040;
let multi_location = MultiLocation {
parents: 1,
interior: X1(Junction::AccountId32 { network: NetworkId::Any, id: [1; 32] }),
};
let asset_location =
MultiLocation { parents: 1, interior: Junctions::X1(Junction::Parachain(para_id)) };
let asset = MultiAsset {
id: AssetId::Concrete(asset_location),
fun: 10_000_000_000_000u128.into(),
};
assert_ok!(Thea::set_withdrawal_fee(Origin::root(), 1, 0));
let beneficiary: [u8; 32] = [1; 32];
// Mint Asset to Alice
assert_ok!(pallet_balances::pallet::Pallet::<Test>::set_balance(
Origin::root(),
1,
1_000_000_000_000_000_000,
0
));
assert_ok!(Thea::withdraw(
Origin::signed(1),
asset_id.clone(),
10_000_000_000_000u128,
beneficiary.to_vec(),
false
));
let pending_withdrawal = <PendingWithdrawals<Test>>::get(1);
let payload = ParachainWithdraw::get_parachain_withdraw(asset, multi_location);
let approved_withdraw = ApprovedWithdraw {
asset_id,
amount: 10_000_000_000_000u128,
network: 1,
beneficiary: vec![1; 32],
payload: payload.encode(),
};
assert_eq!(pending_withdrawal.to_vec().pop().unwrap(), approved_withdraw);
})
}

pub type PrivateKeys = Vec<SecretKey>;
pub type PublicKeys = Vec<BLSPublicKey>;

Expand Down
10 changes: 10 additions & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ parameter_types! {
pub const MaxPending: u16 = 32;
}
use scale_info::TypeInfo;
use sp_core::crypto::AccountId32;
use sp_npos_elections::ExtendedBalance;

/// The type used to represent the kinds of proxying allowed.
Expand Down Expand Up @@ -1288,6 +1289,12 @@ impl chainbridge::Config for Runtime {
type ProposalLifetime = ProposalLifetime;
}

parameter_types! {
pub const PolkadexAssetId: u128 = 1000; //TODO: Chnage Polkddex Asset ID
pub const PDEXHolderAccount: AccountId32 = AccountId32::new([1u8;32]); //TODO Chnage Holder Account
pub const ParaId: u32 = 2040;
}

impl asset_handler::pallet::Config for Runtime {
type Event = Event;
type Currency = Balances;
Expand All @@ -1296,6 +1303,8 @@ impl asset_handler::pallet::Config for Runtime {
type TreasuryPalletId = TreasuryPalletId;
type WeightInfo = asset_handler::WeightInfo<Runtime>;
type ParachainNetworkId = ParachainNetworkId;
type PolkadexAssetId = PolkadexAssetId;
type PDEXHolderAccount = PDEXHolderAccount;
}

impl thea::pallet::Config for Runtime {
Expand All @@ -1304,6 +1313,7 @@ impl thea::pallet::Config for Runtime {
type AssetCreateUpdateOrigin = EnsureRootOrHalfCouncil;
type TheaPalletId = TheaPalletId;
type WithdrawalSize = WithdrawalSize;
type ParaId = ParaId;
}

//Install Staking Pallet
Expand Down

0 comments on commit 16249fe

Please sign in to comment.