Skip to content

Commit

Permalink
Direct Deposit/Withdrawal (#959)
Browse files Browse the repository at this point in the history
## Describe your changes

1. Registers main account and deposits the assets on detection of direct
deposit XCM type
2. Modified Ob Withdrawal to use Multilocation for direct withdrawal
from OB.

## Issue ticket number and link
#956

## Checklist before requesting a review
- [ ] I have performed a self-review of my code.
- [ ] If it is a core feature, I have added thorough tests.
- [ ] I removed all Clippy and Formatting Warnings. 
- [ ] I added required Copyrights.
  • Loading branch information
Gauthamastro authored May 20, 2024
2 parents 57aa653 + e6398c0 commit 6046b3a
Show file tree
Hide file tree
Showing 39 changed files with 765 additions and 519 deletions.
240 changes: 127 additions & 113 deletions Cargo.lock

Large diffs are not rendered by default.

26 changes: 1 addition & 25 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,30 +52,7 @@ members = [
"polkadex-xcm-simulator",
]
exclude = ["scripts/check-off-on-deviation"]
default-members = [
"client",
"nodes/mainnet",
"nodes/parachain",
"runtimes/mainnet",
"runtimes/parachain",
"pallets/pdex-migration",
"pallets/pdex-migration",
"pallets/ocex",
"pallets/ocex/rpc",
"pallets/liquidity-mining",
"pallets/ocex/rpc/runtime-api",
"pallets/rewards",
"primitives/orderbook",
"primitives/polkadex",
"primitives/thea",
"primitives/bls",
"pallets/thea",
"pallets/thea-executor",
"pallets/rewards/rpc",
"pallets/rewards/rpc/runtime-api",
"rpc/swap",
"polkadex-xcm-simulator",
]


[workspace.dependencies]
log = { version = "0.4.8", default-features = false }
Expand Down Expand Up @@ -135,7 +112,6 @@ pallet-authority-discovery = { git = "https://github.com/paritytech/polkadot-sdk
pallet-transaction-payment = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false }
pallet-staking-reward-curve = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false }
pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false }
#pallet-randomness-collective-flip = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false }
pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false }
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false }
pallet-statement = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion check-all-ci-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ cargo build --features try-runtime || exit
cargo build --features runtime-benchmarks || exit
./target/debug/polkadex-node benchmark pallet --pallet "*" --extrinsic "*" --steps 2 --repeat 1 || exit
cargo clippy -- -D warnings || exit
RUSTFLAGS="-D warnings" cargo test || exit
RUSTFLAGS="-D warnings" cargo test --workspace || exit
1 change: 1 addition & 0 deletions pallets/liquidity-mining/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ impl ocex::Config for Test {
type CrowdSourceLiqudityMining = LiqudityMining;
type OBWithdrawalLimit = OBWithdrawalLimit;
type WeightInfo = ocex::weights::WeightInfo<Test>;
type CrossChainGadget = ();
}

parameter_types! {
Expand Down
1 change: 1 addition & 0 deletions pallets/ocex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ sp-io = { workspace = true }
pallet-lmp = { path = "../liquidity-mining", default-features = false }
lazy_static = "1.4.0"
sequential-test = "0.2.4"
hex = "0.4.3"

[features]
default = ["std"]
Expand Down
14 changes: 6 additions & 8 deletions pallets/ocex/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,14 +222,9 @@ benchmarks! {
let proxy = account::<T::AccountId>("proxy", x, 0);
Ocex::<T>::register_main_account(RawOrigin::Signed(user.clone()).into(), proxy)?;
let call = Call::<T>::deposit { asset, amount };
let id = H160::zero();
}: { call.dispatch_bypass_filter(RawOrigin::Signed(user.clone()).into())? }
verify {
assert_last_event::<T>(Event::DepositSuccessful {
user,
asset,
amount
}.into());
}


remove_proxy_account {
let x in 1 .. 255; // should not overflow u8
Expand Down Expand Up @@ -285,12 +280,13 @@ benchmarks! {
let mut vec_withdrawals = Vec::with_capacity(1);
let fees = Decimal::new(100, 5);
vec_withdrawals.push(Withdrawal {
id: Default::default(),
amount: Decimal::new(x.into(), 0),
stid:0,
asset,
main_account: main.clone(),
fees,
});
destination: None,});
let mut wm = sp_std::collections::btree_map::BTreeMap::new();
wm.insert(main.clone(), vec_withdrawals.clone());
<Withdrawals<T>>::insert(x as u64, wm);
Expand Down Expand Up @@ -580,11 +576,13 @@ fn get_dummy_snapshot<T: Config>() -> SnapshotSummary<T::AccountId> {
);
for _ in 0..50 {
withdrawals.push(Withdrawal {
id: Default::default(),
main_account: T::AccountId::decode(&mut &[0u8; 32][..]).unwrap(),
amount: Decimal::one(),
asset: AssetId::Polkadex,
fees: Decimal::one(),
stid: 1,
destination: None,
});
}
SnapshotSummary {
Expand Down
18 changes: 13 additions & 5 deletions pallets/ocex/src/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use rust_decimal::Decimal;
use sequential_test::sequential;
use sp_core::crypto::AccountId32;
use sp_core::sr25519::Signature;
use sp_core::{Pair, H256};
use sp_core::{Pair, H160, H256};
use sp_runtime::offchain::storage::StorageValueRef;
use std::collections::BTreeMap;

Expand Down Expand Up @@ -321,10 +321,18 @@ fn push_trade_user_actions(stid: u64, snapshot_id: u64, block_no: u64) {
fn get_block_import(block_no: u64) -> u64 {
let block_no = block_no;
let (maker_account, taker_account) = get_maker_and_taker_account();
let maker_ingress_message =
IngressMessages::Deposit(maker_account, AssetId::Asset(1), Decimal::from(100));
let taker_ingress_message =
IngressMessages::Deposit(taker_account, AssetId::Polkadex, Decimal::from(100));
let maker_ingress_message = IngressMessages::Deposit(
H160::zero(),
maker_account,
AssetId::Asset(1),
Decimal::from(100),
);
let taker_ingress_message = IngressMessages::Deposit(
H160::zero(),
taker_account,
AssetId::Polkadex,
Decimal::from(100),
);
<IngressMessagesStorage<Test>>::insert(
block_no,
vec![maker_ingress_message, taker_ingress_message],
Expand Down
92 changes: 74 additions & 18 deletions pallets/ocex/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ use frame_support::traits::fungible::Inspect as InspectNative;
use frame_system::pallet_prelude::BlockNumberFor;
use orderbook_primitives::lmp::LMPMarketConfig;
use orderbook_primitives::ocex::TradingPairConfig;
use orderbook_primitives::traits::OrderbookOperations;
use orderbook_primitives::{
types::{AccountAsset, TradingPair},
SnapshotSummary, ValidatorSet, GENESIS_AUTHORITY_SET_ID,
};
use sp_core::H160;
use sp_std::vec::Vec;

#[cfg(test)]
Expand Down Expand Up @@ -144,6 +146,7 @@ pub trait OcexWeightInfo {
#[frame_support::pallet]
pub mod pallet {
use orderbook_primitives::traits::LiquidityMiningCrowdSourcePallet;
use polkadex_primitives::withdrawal::WithdrawalDestination;
use sp_std::collections::btree_map::BTreeMap;
// Import various types used to declare pallet in scope.
use super::*;
Expand All @@ -168,6 +171,7 @@ pub mod pallet {
};
use parity_scale_codec::Compact;
use polkadex_primitives::auction::AuctionInfo;
use polkadex_primitives::traits::CrossChainWithdraw;
use polkadex_primitives::{assets::AssetId, withdrawal::Withdrawal, ProxyLimit, UNIT_BALANCE};
use rust_decimal::{prelude::ToPrimitive, Decimal};
use sp_application_crypto::RuntimeAppPublic;
Expand Down Expand Up @@ -278,6 +282,9 @@ pub mod pallet {
<Self as frame_system::Config>::AccountId,
>;

/// CrossChain Withdrawal
type CrossChainGadget: CrossChainWithdraw<Self::AccountId>;

/// Type representing the weight of this pallet
type WeightInfo: OcexWeightInfo;
}
Expand Down Expand Up @@ -729,7 +736,7 @@ pub mod pallet {
#[pallet::compact] amount: BalanceOf<T>,
) -> DispatchResult {
let user = ensure_signed(origin)?;
Self::do_deposit(user, asset, amount)?;
Self::do_deposit(Self::new_random_id(None), user, asset, amount)?;
Ok(())
}

Expand Down Expand Up @@ -1082,6 +1089,7 @@ pub mod pallet {
quote: AssetId,
},
DepositSuccessful {
id: H160,
user: T::AccountId,
asset: AssetId,
amount: BalanceOf<T>,
Expand Down Expand Up @@ -1114,7 +1122,7 @@ pub mod pallet {
/// AllowlistedTokenRemoved
AllowlistedTokenRemoved(AssetId),
/// Withdrawal ready to claim
WithdrawalReady(u64, Withdrawal<T::AccountId>),
WithdrawalReady(u64, Box<Withdrawal<T::AccountId>>),
/// Exchange state has been updated
ExchangeStateUpdated(bool),
/// DisputePeriod has been updated
Expand Down Expand Up @@ -1313,6 +1321,16 @@ pub mod pallet {
StorageValue<_, AuctionInfo<T::AccountId, BalanceOf<T>>, OptionQuery>;

impl<T: crate::pallet::Config> crate::pallet::Pallet<T> {
pub fn new_random_id(prefix: Option<[u8; 4]>) -> H160 {
let mut entropy: [u8; 20] = [0u8; 20];
if let Some(prefix) = prefix {
entropy[0..4].copy_from_slice(&prefix);
}
let current_blk = frame_system::Pallet::<T>::current_block_number();
entropy[4..].copy_from_slice(&sp_io::hashing::blake2_128(&((current_blk).encode())));
H160::from(entropy)
}

pub fn do_withdraw(
snapshot_id: u64,
mut withdrawal_vector: Vec<Withdrawal<T::AccountId>>,
Expand All @@ -1323,14 +1341,14 @@ pub mod pallet {
// Perform pop operation to ensure we do not leave any withdrawal left
// for a double spend
if let Some(withdrawal) = withdrawal_vector.pop() {
if Self::on_idle_withdrawal_processor(withdrawal.clone()) {
if Self::on_idle_withdrawal_processor(withdrawal.clone()).is_ok() {
processed_withdrawals.push(withdrawal.to_owned());
} else {
// Storing the failed withdrawals back into the storage item
failed_withdrawals.push(withdrawal.to_owned());
Self::deposit_event(Event::WithdrawalReady(
snapshot_id,
withdrawal.to_owned(),
Box::from(withdrawal.to_owned()),
));
}
}
Expand Down Expand Up @@ -1700,6 +1718,7 @@ pub mod pallet {
}

pub fn do_deposit(
id: H160,
user: T::AccountId,
asset: AssetId,
amount: BalanceOf<T>,
Expand Down Expand Up @@ -1728,12 +1747,13 @@ pub mod pallet {
let current_blk = frame_system::Pallet::<T>::current_block_number();
<IngressMessages<T>>::mutate(current_blk, |ingress_messages| {
ingress_messages.push(orderbook_primitives::ingress::IngressMessages::Deposit(
id,
user.clone(),
asset,
converted_amount,
));
});
Self::deposit_event(Event::DepositSuccessful { user, asset, amount });
Self::deposit_event(Event::DepositSuccessful { id, user, asset, amount });
Ok(())
}

Expand Down Expand Up @@ -1812,22 +1832,52 @@ pub mod pallet {

/// Performs actual transfer of assets from pallet account to target destination
/// Used to finalize withdrawals in extrinsic or on_idle
#[transactional]
fn on_idle_withdrawal_processor(
withdrawal: Withdrawal<<T as frame_system::Config>::AccountId>,
) -> bool {
if let Some(converted_withdrawal) =
withdrawal.amount.saturating_mul(Decimal::from(UNIT_BALANCE)).to_u128()
{
Self::transfer_asset(
&Self::get_pallet_account(),
&withdrawal.main_account,
converted_withdrawal.saturated_into(),
withdrawal.asset,
)
.is_ok()
} else {
false
) -> DispatchResult {
let converted_withdrawal = withdrawal
.amount
.saturating_mul(Decimal::from(UNIT_BALANCE))
.to_u128()
.ok_or(Error::<T>::FailedToConvertDecimaltoBalance)?;

Self::transfer_asset(
&Self::get_pallet_account(),
&withdrawal.main_account,
converted_withdrawal.saturated_into(),
withdrawal.asset,
)?;

// on_idle_withdrawal_processor is called in a transacitonal manner so it is okay.
if let Some(destination) = withdrawal.destination {
match destination {
WithdrawalDestination::Polkadot(multi_location, None) => {
T::CrossChainGadget::parachain_withdraw(
withdrawal.main_account,
withdrawal.asset,
converted_withdrawal,
multi_location,
None,
None,
withdrawal.id,
)?
},
WithdrawalDestination::Polkadot(
multi_location,
Some((fee_asset_id, fee_amount)),
) => T::CrossChainGadget::parachain_withdraw(
withdrawal.main_account,
withdrawal.asset,
converted_withdrawal,
multi_location,
Some(fee_asset_id),
Some(fee_amount),
withdrawal.id,
)?,
}
}
Ok(())
}

/// Collects onchain registered main and proxy accounts
Expand Down Expand Up @@ -2395,3 +2445,9 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {

fn on_disabled(_i: u32) {}
}

impl<T: Config> OrderbookOperations<T::AccountId> for Pallet<T> {
fn deposit(id: H160, main: T::AccountId, asset: AssetId, amount: u128) -> DispatchResult {
Self::do_deposit(id, main, asset, amount.saturated_into())
}
}
14 changes: 12 additions & 2 deletions pallets/ocex/src/lmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,12 +482,22 @@ impl<T: Config> LiquidityMining<T::AccountId, BalanceOf<T>> for Pallet<T> {
.saturating_mul(unit)
.to_u128()
.ok_or(Error::<T>::FailedToConvertDecimaltoBalance)?;
Self::do_deposit(pool.clone(), market.base, base_amount_in_u128.saturated_into())?;
Self::do_deposit(
Self::new_random_id(None),
pool.clone(),
market.base,
base_amount_in_u128.saturated_into(),
)?;
let quote_amount_in_u128 = quote_amount
.saturating_mul(unit)
.to_u128()
.ok_or(Error::<T>::FailedToConvertDecimaltoBalance)?;
Self::do_deposit(pool.clone(), market.quote, quote_amount_in_u128.saturated_into())?;
Self::do_deposit(
Self::new_random_id(None),
pool.clone(),
market.quote,
quote_amount_in_u128.saturated_into(),
)?;
let current_blk = frame_system::Pallet::<T>::current_block_number();
<IngressMessages<T>>::mutate(current_blk, |messages| {
messages.push(orderbook_primitives::ingress::IngressMessages::AddLiquidity(
Expand Down
1 change: 1 addition & 0 deletions pallets/ocex/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ impl Config for Test {
type CrowdSourceLiqudityMining = LiqudityMining;
type WeightInfo = crate::weights::WeightInfo<Test>;
type OBWithdrawalLimit = OBWithdrawalLimit;
type CrossChainGadget = ();
}

parameter_types! {
Expand Down
8 changes: 6 additions & 2 deletions pallets/ocex/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,12 @@ impl<T: Config> Pallet<T> {
let ingress_msgs =
<IngressMessages<T>>::get(blk.saturated_into::<BlockNumberFor<T>>());
for msg in ingress_msgs {
if let orderbook_primitives::ingress::IngressMessages::Deposit(_, asset, amt) =
msg
if let orderbook_primitives::ingress::IngressMessages::Deposit(
_,
_,
asset,
amt,
) = msg
{
onchain_inventory
.entry(asset)
Expand Down
Loading

0 comments on commit 6046b3a

Please sign in to comment.