Skip to content

Commit 8228f16

Browse files
committed
refactor
1 parent 01cc158 commit 8228f16

File tree

16 files changed

+973
-567
lines changed

16 files changed

+973
-567
lines changed

Cargo.lock

Lines changed: 21 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ serde = { version = "1.0.197", default-features = false }
3030
serde_json = { version = "1.0.114", default-features = false }
3131
hex-literal = { version = "0.4.1", default-features = false }
3232

33+
# Db
34+
nomt = { git = "https://github.com/thrumdev/nomt.git", tag = "v1.0.0-preview" }
35+
3336
# Polkadot Dependency
3437
polkadot-parachain-primitives = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
3538
polkadot-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
@@ -49,10 +52,10 @@ cumulus-relay-chain-interface = { git = "https://github.com/paritytech/polkadot-
4952
cumulus-pallet-aura-ext = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
5053
cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
5154
cumulus-pallet-session-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
55+
cumulus-pallet-weight-reclaim = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
5256
cumulus-pallet-xcm = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
5357
cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
5458
cumulus-primitives-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
55-
cumulus-primitives-storage-weight-reclaim = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
5659
cumulus-primitives-utility = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
5760

5861
# Client
@@ -119,6 +122,7 @@ pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "p
119122
pallet-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
120123
pallet-transaction-payment = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
121124
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
125+
pallet-utility = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
122126
substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2503", default-features = false }
123127

124128
# XCM

pallets/hybrid-orderbook/src/critbit.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,10 @@ where
607607
CritbitTree::new()
608608
}
609609

610+
fn size(&self) -> usize {
611+
self.size()
612+
}
613+
610614
fn is_empty(&self) -> bool {
611615
self.is_empty()
612616
}

pallets/hybrid-orderbook/src/lib.rs

Lines changed: 87 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use frame_support::{
7777
ensure,
7878
storage::{with_storage_layer, with_transaction},
7979
traits::{
80-
fungibles::{Balanced, Create, Credit, Inspect, Mutate, MutateFreeze, metadata::Inspect as InspectMetadata},
80+
fungibles::{Balanced, Create, Credit, Inspect, Mutate, MutateFreeze},
8181
tokens::{
8282
AssetId, Balance,
8383
Fortitude::Polite,
@@ -150,8 +150,7 @@ pub mod pallet {
150150
type Assets: Inspect<Self::AccountId, AssetId = Self::AssetKind, Balance = Self::Unit>
151151
+ Mutate<Self::AccountId>
152152
+ AccountTouch<Self::AssetKind, Self::AccountId, Balance = Self::Unit>
153-
+ Balanced<Self::AccountId>
154-
+ InspectMetadata<Self::AccountId>;
153+
+ Balanced<Self::AccountId>;
155154

156155
type AssetsFreezer: MutateFreeze<
157156
Self::AccountId,
@@ -216,7 +215,7 @@ pub mod pallet {
216215
type MaxSwapPathLength: Get<u32>;
217216

218217
#[pallet::constant]
219-
type StandardDecimals: Get<u8>;
218+
type StandardDecimals: Get<u8>;
220219

221220
/// The pallet's id, used for deriving its sovereign account ID.
222221
#[pallet::constant]
@@ -454,6 +453,10 @@ pub mod pallet {
454453
ConversionError,
455454
/// Operation can't be done
456455
NoOps,
456+
/// Invalid tick size
457+
InvalidTickSize,
458+
/// Invalid lot size
459+
InvalidLotSize,
457460
}
458461

459462
#[pallet::hooks]
@@ -478,14 +481,18 @@ pub mod pallet {
478481
pub fn create_pool(
479482
origin: OriginFor<T>,
480483
base_asset: Box<T::AssetKind>,
484+
base_decimals: u8,
481485
quote_asset: Box<T::AssetKind>,
486+
quote_decimals: u8,
482487
taker_fee_rate: Permill,
483488
tick_size: T::Unit,
484489
lot_size: T::Unit,
490+
pool_decimals: u8,
485491
) -> DispatchResult {
486492
let sender = ensure_signed(origin)?;
487493
ensure!(base_asset != quote_asset, Error::<T>::InvalidAssetPair);
488-
494+
ensure!(tick_size > Zero::zero(), Error::<T>::InvalidTickSize);
495+
ensure!(lot_size > Zero::zero(), Error::<T>::InvalidLotSize);
489496
// prepare pool_id
490497
let pool_id = T::PoolLocator::pool_id(&base_asset, &quote_asset)
491498
.map_err(|_| Error::<T>::InvalidAssetPair)?;
@@ -503,9 +510,13 @@ pub mod pallet {
503510
)?;
504511
T::PoolSetupFeeTarget::on_unbalanced(fee);
505512

506-
507-
let b_decimals_adjustment = Self::get_decimals(&base_asset);
508-
let q_decimals_adjustment = Self::get_decimals(&quote_asset);
513+
let mut base_decimals_adjustment = None;
514+
let mut quote_decimals_adjustment = None;
515+
if base_decimals > quote_decimals {
516+
base_decimals_adjustment = Some(base_decimals - quote_decimals);
517+
} else if base_decimals < quote_decimals {
518+
quote_decimals_adjustment = Some(quote_decimals - base_decimals);
519+
}
509520

510521
if T::Assets::should_touch(*base_asset.clone(), &pool_account) {
511522
T::Assets::touch(*base_asset, &pool_account, &sender)?
@@ -535,8 +546,9 @@ pub mod pallet {
535546
taker_fee_rate,
536547
tick_size,
537548
lot_size,
538-
b_decimals_adjustment,
539-
q_decimals_adjustment,
549+
pool_decimals,
550+
base_decimals_adjustment,
551+
quote_decimals_adjustment,
540552
),
541553
);
542554
Self::deposit_event(Event::PoolCreated {
@@ -901,27 +913,24 @@ pub mod pallet {
901913
}
902914

903915
impl<T: Config> Pallet<T> {
904-
fn account_id() -> T::AccountId {
916+
fn _account_id() -> T::AccountId {
905917
T::PalletId::get().into_account_truncating()
906918
}
907919

908-
fn get_pool(
920+
pub fn get_pool_query(
909921
base_asset: &T::AssetKind,
910922
quote_asset: &T::AssetKind,
911-
) -> Result<Pool<T>, DispatchError> {
912-
let pool_id = T::PoolLocator::pool_id(base_asset, quote_asset)
913-
.map_err(|_| Error::<T>::InvalidAssetPair)?;
914-
Pools::<T>::get(&pool_id).ok_or(Error::<T>::PoolNotFound.into())
915-
}
916-
917-
fn get_decimals(asset_kind: &T::AssetKind) -> u8 {
918-
let asset_decimals = T::Assets::decimals(asset_kind.clone());
919-
let n_decimals = if T::StandardDecimals::get() > asset_decimals {
920-
T::StandardDecimals::get()
921-
} else {
922-
asset_decimals - T::StandardDecimals::get()
923-
};
924-
n_decimals
923+
) -> Result<PoolQuery<T::OrderBook, T::Unit>, DispatchError> {
924+
let pool_id = T::PoolLocator::pool_id(base_asset, quote_asset).map_err(|_| Error::<T>::PoolNotFound)?;
925+
let pool_account = T::PoolLocator::pool_address(&base_asset, &quote_asset).map_err(|_| Error::<T>::PoolNotFound)?;
926+
let pool = Pools::<T>::get(&pool_id).ok_or(Error::<T>::PoolNotFound)?;
927+
let base_asset_reserve = Self::get_balance(&pool_account, &base_asset);
928+
let quote_asset_reserve = Self::get_balance(&pool_account, &quote_asset);
929+
let pool_decimals = pool.pool_decimals;
930+
let base_adjustment = pool.base_adjustment;
931+
let quote_adjustment = pool.quote_adjustment;
932+
let pool_price = Self::pool_price(base_asset, pool_decimals, base_adjustment, quote_asset, quote_adjustment)?;
933+
return Ok(pool.to_pool_query(base_asset_reserve, quote_asset_reserve, pool_price));
925934
}
926935

927936
fn freeze_asset(
@@ -981,16 +990,19 @@ pub mod pallet {
981990
quote_asset: &T::AssetKind,
982991
quantity: T::Unit,
983992
) -> DispatchResult {
984-
// Order quantity should be greater than 0
985993
ensure!(quantity > Zero::zero(), Error::<T>::WrongDesiredAmount);
986994
let pool_id = T::PoolLocator::pool_id(base_asset, quote_asset)
987995
.map_err(|_| Error::<T>::InvalidAssetPair)?;
988-
let mut pool = Pools::<T>::get(&pool_id).ok_or(Error::<T>::PoolNotFound)?;
989-
Self::do_match_order(is_bid, taker, &mut pool, base_asset, quote_asset, quantity)?;
990-
Pools::<T>::insert(pool_id, pool);
991-
Self::deposit_event(Event::<T>::MarketOrder {
992-
taker: taker.clone(),
993-
});
996+
Pools::<T>::try_mutate_exists(pool_id, |maybe_pool| -> DispatchResult {
997+
let mut pool = maybe_pool.take().ok_or(Error::<T>::PoolNotFound)?;
998+
ensure!(pool.is_valid_order_quantity(quantity), Error::<T>::InvalidOrderQuantity);
999+
Self::do_match_order(is_bid, taker, &mut pool, base_asset, quote_asset, quantity)?;
1000+
*maybe_pool = Some(pool);
1001+
Self::deposit_event(Event::<T>::MarketOrder {
1002+
taker: taker.clone(),
1003+
});
1004+
Ok(())
1005+
})?;
9941006
Ok(())
9951007
}
9961008

@@ -1011,28 +1023,25 @@ pub mod pallet {
10111023
base_asset: &T::AssetKind,
10121024
quote_asset: &T::AssetKind,
10131025
) -> DispatchResult {
1014-
// Validity check
10151026
let pool_id = T::PoolLocator::pool_id(base_asset, quote_asset)
10161027
.map_err(|_| Error::<T>::InvalidAssetPair)?;
10171028
let mut pool = Pools::<T>::get(&pool_id).ok_or(Error::<T>::PoolNotFound)?;
1018-
let pool_price =
1019-
Self::pool_price(base_asset, pool.base_adjustment, quote_asset, pool.quote_adjustment).map_err(|_| Error::<T>::ZeroLiquidity)?;
1020-
ensure!(
1021-
order_quantity > Zero::zero(),
1022-
Error::<T>::WrongDesiredAmount
1023-
);
1024-
ensure!(order_price > Zero::zero(), Error::<T>::InvalidOrderPrice);
1025-
// Price of order could only be set to the multiple of `tick_size`
1029+
let pool_price = Self::pool_price(
1030+
base_asset,
1031+
pool.pool_decimals,
1032+
pool.base_adjustment,
1033+
quote_asset,
1034+
pool.quote_adjustment,
1035+
)
1036+
.map_err(|_| Error::<T>::ZeroLiquidity)?;
10261037
ensure!(
1027-
order_price % pool.tick_size == Zero::zero(),
1038+
pool.is_valid_order_price(order_price),
10281039
Error::<T>::InvalidOrderPrice
10291040
);
1030-
// Quantity of order could only be set to the multiple of `lot_size`
10311041
ensure!(
1032-
order_quantity >= pool.lot_size && order_quantity % pool.lot_size == Zero::zero(),
1042+
pool.is_valid_order_quantity(order_quantity),
10331043
Error::<T>::InvalidOrderQuantity
10341044
);
1035-
10361045
// Check whether order should be matched
10371046
let should_match_order = if is_bid {
10381047
order_price >= pool_price
@@ -1164,6 +1173,7 @@ pub mod pallet {
11641173
let max_swap_quantity = Self::find_max_swap_quantity(
11651174
is_bid,
11661175
orderbook_price,
1176+
pool.pool_decimals,
11671177
base_asset,
11681178
pool.base_adjustment,
11691179
quote_asset,
@@ -1307,15 +1317,19 @@ pub mod pallet {
13071317
/// 1 * quote_reserve / base_reserve
13081318
pub fn pool_price(
13091319
base_asset: &T::AssetKind,
1310-
base_decimals_adjustment: u8,
1320+
pool_decimals: Option<u8>,
1321+
base_decimals_adjustment: Option<u8>,
13111322
quote_asset: &T::AssetKind,
1312-
quote_decimals_adjustment: u8,
1323+
quote_decimals_adjustment: Option<u8>,
13131324
) -> Result<T::Unit, Error<T>> {
13141325
let (base_reserve, quote_reserve) = Self::get_reserves(base_asset, quote_asset)?;
1315-
Self::quote(
1316-
&One::one(),
1317-
&base_reserve.normalize(base_decimals_adjustment),
1318-
&quote_reserve.normalize(quote_decimals_adjustment)
1326+
Ok(
1327+
Self::quote(
1328+
&One::one(),
1329+
&base_reserve.normalize(base_decimals_adjustment),
1330+
&quote_reserve.normalize(quote_decimals_adjustment),
1331+
)?
1332+
.normalize(pool_decimals)
13191333
)
13201334
}
13211335

@@ -1328,10 +1342,11 @@ pub mod pallet {
13281342
pub(crate) fn find_max_swap_quantity(
13291343
is_bid: bool,
13301344
target: T::Unit,
1345+
pool_decimals: Option<u8>,
13311346
base_asset: &T::AssetKind,
1332-
base_decimals_adjustment: u8,
1347+
base_decimals_adjustment: Option<u8>,
13331348
quote_asset: &T::AssetKind,
1334-
quote_decimals_adjustment: u8,
1349+
quote_decimals_adjustment: Option<u8>,
13351350
order_quantity: T::Unit,
13361351
) -> Result<T::Unit, Error<T>> {
13371352
let (b_r, q_r) = Self::get_reserves(base_asset, quote_asset)?;
@@ -1345,13 +1360,23 @@ pub mod pallet {
13451360
// of `base_asset` quantity of `base_asset`
13461361
let amount_in = Self::get_amount_in(&mid, &q_r, &b_r)?;
13471362
if_std! { println!("Bid order: amount_in => {:?}, K = {:?}", amount_in, ((b_r-mid)*(q_r+amount_in)));}
1348-
Self::quote(&One::one(), &(b_r - mid).normalize(base_decimals_adjustment), &(q_r + amount_in).normalize(quote_decimals_adjustment))?
1363+
Self::quote(
1364+
&One::one(),
1365+
&(b_r - mid).normalize(base_decimals_adjustment),
1366+
&(q_r + amount_in).normalize(quote_decimals_adjustment),
1367+
)?
1368+
.normalize(pool_decimals)
13491369
} else {
13501370
// If it is ask order, get `amount_out` of `quote_asset` with given `amount_in`
13511371
// of `base_asset`
13521372
let amount_out = Self::get_amount_out(&mid, &b_r, &q_r)?;
13531373
if_std! { println!("Ask order: amount_out => {:?}", amount_out);}
1354-
Self::quote(&One::one(), &(b_r + mid).normalize(base_decimals_adjustment), &(q_r - amount_out).normalize(quote_decimals_adjustment))?
1374+
Self::quote(
1375+
&One::one(),
1376+
&(b_r + mid).normalize(base_decimals_adjustment),
1377+
&(q_r - amount_out).normalize(quote_decimals_adjustment),
1378+
)?
1379+
.normalize(pool_decimals)
13551380
};
13561381
if_std! {
13571382
println!("Pool Price => {:?}, Mid => {:?}", pool_price, mid);
@@ -2021,10 +2046,11 @@ pub mod pallet {
20212046
sp_api::decl_runtime_apis! {
20222047
/// This runtime api allows people to query the size of the liquidity pools
20232048
/// and quote prices for swaps.
2024-
pub trait HybridOrderbookApi<Balance, AssetId>
2049+
pub trait HybridOrderbookApi<Balance, AssetId, Orderbook>
20252050
where
20262051
Balance: frame_support::traits::tokens::Balance + MaybeDisplay,
20272052
AssetId: Codec,
2053+
Orderbook: Codec,
20282054
{
20292055
/// Provides a quote for [`Pallet::swap_tokens_for_exact_tokens`].
20302056
///
@@ -2052,7 +2078,10 @@ sp_api::decl_runtime_apis! {
20522078
fn get_reserves(asset1: AssetId, asset2: AssetId) -> Option<(Balance, Balance)>;
20532079

20542080
/// Returns the price of the given asset pair.
2055-
fn get_pool_price(base: AssetId, quote: AssetId) -> Option<Balance>;
2081+
fn get_pool_price(base: AssetId, pool_decimals: Option<u8>, base_decimal_diff: Option<u8>, quote: AssetId, quote_decimal_diff: Option<u8>) -> Option<Balance>;
2082+
2083+
/// Returns query of the `pool`
2084+
fn get_pool_query(base: AssetId, quote: AssetId) -> Option<PoolQuery<Orderbook, Balance>>;
20562085
}
20572086
}
20582087

pallets/hybrid-orderbook/src/mock.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use frame_support::{
3535
};
3636
use frame_system::{EnsureSigned, EnsureSignedBy};
3737
use sp_arithmetic::Permill;
38-
use sp_core::ConstU64;
38+
use sp_core::{ConstU64, ConstU8};
3939
use sp_runtime::{
4040
traits::{AccountIdConversion, IdentityLookup},
4141
BuildStorage,
@@ -181,6 +181,7 @@ impl Config for Test {
181181
type WeightInfo = ();
182182
type LPFee = ConstU32<3>; // means 0.3%
183183
type LiquidityWithdrawalFee = LiquidityWithdrawalFee;
184+
type StandardDecimals = ConstU8<10>;
184185
type MaxSwapPathLength = ConstU32<4>;
185186
type MintMinLiquidity = ConstU64<100>; // 100 is good enough when the main currency has 12 decimals.
186187
#[cfg(feature = "runtime-benchmarks")]

0 commit comments

Comments
 (0)