Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feat/collect-for-fore…
Browse files Browse the repository at this point in the history
…ign-investment
  • Loading branch information
wischli committed Sep 21, 2023
2 parents 077abd6 + 71cd8a4 commit 0b6924d
Show file tree
Hide file tree
Showing 10 changed files with 468 additions and 49 deletions.
7 changes: 7 additions & 0 deletions pallets/order-book/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ benchmarks! {

}:fill_order_full(RawOrigin::Signed(account_1.clone()), order_id)

fill_order_partial {
let (account_0, account_1, asset_0, asset_1) = set_up_users_currencies::<T>()?;

let order_id = Pallet::<T>::place_order(account_0.clone(), asset_0, asset_1, 100 * CURRENCY_0, T::SellRatio::saturating_from_integer(2).into(), 10 * CURRENCY_0)?;

}:fill_order_partial(RawOrigin::Signed(account_1.clone()), order_id, 40 * CURRENCY_0)

add_trading_pair {
let asset_0 = CurrencyId::ForeignAsset(1);
let asset_1 = CurrencyId::ForeignAsset(2);
Expand Down
147 changes: 103 additions & 44 deletions pallets/order-book/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub mod pallet {
use frame_system::pallet_prelude::{OriginFor, *};
use orml_traits::asset_registry::{self, Inspect as _};
use scale_info::TypeInfo;
use sp_arithmetic::traits::BaseArithmetic;
use sp_arithmetic::traits::{BaseArithmetic, CheckedSub};
use sp_runtime::{
traits::{
AtLeast32BitUnsigned, EnsureAdd, EnsureDiv, EnsureFixedPointNumber, EnsureMul,
Expand Down Expand Up @@ -353,6 +353,8 @@ pub mod pallet {
/// Error when unable to convert fee balance to asset balance when asset
/// out matches fee currency
BalanceConversionErr,
/// Error when the provided partial buy amount is too large.
BuyAmountTooLarge,
}

#[pallet::call]
Expand Down Expand Up @@ -459,50 +461,9 @@ pub mod pallet {
pub fn fill_order_full(origin: OriginFor<T>, order_id: T::OrderIdNonce) -> DispatchResult {
let account_id = ensure_signed(origin)?;
let order = <Orders<T>>::get(order_id)?;
let buy_amount = order.buy_amount;

ensure!(
T::TradeableAsset::can_hold(order.asset_in_id, &account_id, order.buy_amount),
Error::<T>::InsufficientAssetFunds,
);

Self::unreserve_order(&order)?;
T::TradeableAsset::transfer(
order.asset_in_id,
&account_id,
&order.placing_account,
order.buy_amount,
false,
)?;
T::TradeableAsset::transfer(
order.asset_out_id,
&order.placing_account,
&account_id,
order.max_sell_amount,
false,
)?;
Self::remove_order(order.order_id)?;

T::FulfilledOrderHook::notify_status_change(
order_id,
Swap {
amount: order.buy_amount,
currency_in: order.asset_in_id,
currency_out: order.asset_out_id,
},
)?;

Self::deposit_event(Event::OrderFulfillment {
order_id,
placing_account: order.placing_account,
fulfilling_account: account_id,
partial_fulfillment: false,
currency_in: order.asset_in_id,
currency_out: order.asset_out_id,
fulfillment_amount: order.buy_amount,
sell_rate_limit: order.max_sell_rate,
});

Ok(())
Self::fulfill_order_with_amount(order, buy_amount, account_id)
}

/// Adds a valid trading pair.
Expand Down Expand Up @@ -582,9 +543,107 @@ pub mod pallet {

Ok(())
}

/// Fill an existing order, based on the provided partial buy amount.
#[pallet::call_index(7)]
#[pallet::weight(T::Weights::fill_order_partial())]
pub fn fill_order_partial(
origin: OriginFor<T>,
order_id: T::OrderIdNonce,
buy_amount: T::Balance,
) -> DispatchResult {
let account_id = ensure_signed(origin)?;
let order = <Orders<T>>::get(order_id)?;

Self::fulfill_order_with_amount(order, buy_amount, account_id)
}
}

impl<T: Config> Pallet<T> {
pub fn fulfill_order_with_amount(
order: OrderOf<T>,
buy_amount: T::Balance,
account_id: T::AccountId,
) -> DispatchResult {
ensure!(
buy_amount >= order.min_fulfillment_amount,
Error::<T>::InsufficientOrderSize,
);

ensure!(
T::TradeableAsset::can_hold(order.asset_in_id, &account_id, buy_amount),
Error::<T>::InsufficientAssetFunds,
);

let sell_amount = Self::convert_with_ratio(
order.asset_in_id,
order.asset_out_id,
order.max_sell_rate,
buy_amount,
)?;
let remaining_buy_amount = order
.buy_amount
.checked_sub(&buy_amount)
.ok_or(Error::<T>::BuyAmountTooLarge)?;
let partial_fulfillment = !remaining_buy_amount.is_zero();

if partial_fulfillment {
Self::update_order(
order.placing_account.clone(),
order.order_id,
remaining_buy_amount,
order.max_sell_rate,
remaining_buy_amount.min(order.min_fulfillment_amount),
)?;
} else {
T::TradeableAsset::release(
order.asset_out_id,
&order.placing_account,
sell_amount,
false,
)?;

Self::remove_order(order.order_id)?;
}

T::TradeableAsset::transfer(
order.asset_in_id,
&account_id,
&order.placing_account,
buy_amount,
false,
)?;
T::TradeableAsset::transfer(
order.asset_out_id,
&order.placing_account,
&account_id,
sell_amount,
false,
)?;

T::FulfilledOrderHook::notify_status_change(
order.order_id,
Swap {
amount: buy_amount,
currency_in: order.asset_in_id,
currency_out: order.asset_out_id,
},
)?;

Self::deposit_event(Event::OrderFulfillment {
order_id: order.order_id,
placing_account: order.placing_account,
fulfilling_account: account_id,
partial_fulfillment,
currency_in: order.asset_in_id,
currency_out: order.asset_out_id,
fulfillment_amount: buy_amount,
sell_rate_limit: order.max_sell_rate,
});

Ok(())
}

/// Remove an order from storage
pub fn remove_order(order_id: T::OrderIdNonce) -> DispatchResult {
let order = <Orders<T>>::get(order_id)?;
Expand Down
1 change: 0 additions & 1 deletion pallets/order-book/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ impl orml_tokens::Config for Runtime {
}

parameter_types! {

pub const NativeToken: CurrencyId = CurrencyId::Native;
}

Expand Down
Loading

0 comments on commit 0b6924d

Please sign in to comment.