Skip to content

Commit

Permalink
Merge pull request #216 from galacticcouncil/fix/exchange
Browse files Browse the repository at this point in the history
fix: exchange
  • Loading branch information
Roznovjak authored Nov 9, 2021
2 parents 668acf7 + 833c1fe commit 27be8c5
Show file tree
Hide file tree
Showing 4 changed files with 669 additions and 240 deletions.
194 changes: 127 additions & 67 deletions pallets/exchange/src/direct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,40 +56,7 @@ impl<'a, T: Config> DirectTradeData<'a, T> {
return false;
}

if !Self::reserve_if_can(
self.intention_a.assets.asset_in,
&self.intention_a.who,
self.amount_from_a,
) {
return false;
}
if !Self::reserve_if_can(
self.intention_a.assets.asset_out,
&self.intention_b.who,
self.amount_from_b,
) {
return false;
}

let transfer = Transfer::<T> {
from: &self.intention_a.who,
to: &self.intention_b.who,
asset: self.intention_a.assets.asset_in,
amount: self.amount_from_a,
fee_transfer: false,
};
self.transfers.push(transfer);
let transfer = Transfer::<T> {
from: &self.intention_b.who,
to: &self.intention_a.who,
asset: self.intention_a.assets.asset_out,
amount: self.amount_from_b,
fee_transfer: false,
};
self.transfers.push(transfer);

// Let's handle the fees now for registered transfers.

let fee_a = self.amount_from_a.just_fee(Fee::default());
let fee_b = self.amount_from_b.just_fee(Fee::default());

Expand All @@ -100,6 +67,9 @@ impl<'a, T: Config> DirectTradeData<'a, T> {
// Unwrapping is correct as None case is handled in previous statement.
let transfer_a_fee = fee_a.unwrap();
let transfer_b_fee = fee_b.unwrap();
if transfer_a_fee > self.amount_from_a || transfer_b_fee > self.amount_from_b {
return false;
}

// Work out where to take a fee from.
// There are multiple possible scenarios to consider
Expand All @@ -110,39 +80,93 @@ impl<'a, T: Config> DirectTradeData<'a, T> {
// Each one is handled slightly different, hence the complicated match statement.
match (&self.intention_a.sell_or_buy, &self.intention_b.sell_or_buy) {
(IntentionType::SELL, IntentionType::SELL) => {
if !Self::reserve_if_can(self.intention_a.assets.asset_out, &self.intention_a.who, transfer_b_fee) {
return false;
if !Self::reserve_if_can(
self.intention_a.assets.asset_in,
&self.intention_a.who,
self.amount_from_a,
) {
return false;
}
if !Self::reserve_if_can(self.intention_b.assets.asset_out, &self.intention_b.who, transfer_a_fee) {
return false;

if !Self::reserve_if_can(
self.intention_a.assets.asset_out,
&self.intention_b.who,
self.amount_from_b,
) {
return false;
}

let transfer = Transfer::<T> {
from: &self.intention_a.who,
to: &self.intention_b.who,
asset: self.intention_a.assets.asset_in,
amount: self.amount_from_a - transfer_a_fee,
fee_transfer: false,
};
self.transfers.push(transfer);

let transfer = Transfer::<T> {
from: &self.intention_b.who,
to: &self.intention_a.who,
asset: self.intention_a.assets.asset_out,
amount: self.amount_from_b - transfer_b_fee,
fee_transfer: false,
};
self.transfers.push(transfer);

let transfer = Transfer::<T> {
from: &self.intention_a.who,
to: pool_account,
asset: self.intention_a.assets.asset_out,
amount: transfer_b_fee,
asset: self.intention_a.assets.asset_in,
amount: transfer_a_fee,
fee_transfer: true,
};
self.transfers.push(transfer);

let transfer = Transfer::<T> {
from: &self.intention_b.who,
to: pool_account,
asset: self.intention_b.assets.asset_out,
amount: transfer_a_fee,
asset: self.intention_b.assets.asset_in,
amount: transfer_b_fee,
fee_transfer: true,
};
self.transfers.push(transfer);
}
(IntentionType::BUY, IntentionType::BUY) => {
if !Self::reserve_if_can(self.intention_a.assets.asset_in, &self.intention_a.who, transfer_a_fee) {
return false;
if !Self::reserve_if_can(
self.intention_a.assets.asset_in,
&self.intention_a.who,
self.amount_from_a + transfer_a_fee,
) {
return false;
}
if !Self::reserve_if_can(self.intention_b.assets.asset_in, &self.intention_b.who, transfer_b_fee) {
return false;

if !Self::reserve_if_can(
self.intention_a.assets.asset_out,
&self.intention_b.who,
self.amount_from_b + transfer_b_fee,
) {
return false;
}

let transfer = Transfer::<T> {
from: &self.intention_a.who,
to: &self.intention_b.who,
asset: self.intention_a.assets.asset_in,
amount: self.amount_from_a,
fee_transfer: false,
};
self.transfers.push(transfer);

let transfer = Transfer::<T> {
from: &self.intention_b.who,
to: &self.intention_a.who,
asset: self.intention_a.assets.asset_out,
amount: self.amount_from_b,
fee_transfer: false,
};
self.transfers.push(transfer);

let transfer = Transfer::<T> {
from: &self.intention_a.who,
to: pool_account,
Expand All @@ -162,53 +186,89 @@ impl<'a, T: Config> DirectTradeData<'a, T> {
self.transfers.push(transfer);
}
(IntentionType::BUY, IntentionType::SELL) => {
if !Self::reserve_if_can(self.intention_a.assets.asset_in, &self.intention_a.who, transfer_a_fee) {
return false;
if !Self::reserve_if_can(
self.intention_a.assets.asset_in,
&self.intention_a.who,
self.amount_from_a + transfer_a_fee,
) {
return false;
}
if !Self::reserve_if_can(self.intention_b.assets.asset_out, &self.intention_b.who, transfer_b_fee) {
return false;

if !Self::reserve_if_can(
self.intention_a.assets.asset_out,
&self.intention_b.who,
self.amount_from_b,
) {
return false;
}

let transfer = Transfer::<T> {
from: &self.intention_a.who,
to: pool_account,
asset: self.intention_a.assets.asset_in,
amount: transfer_a_fee,
fee_transfer: true,
from: &self.intention_a.who,
to: &self.intention_b.who,
asset: self.intention_a.assets.asset_in,
amount: self.amount_from_a - transfer_a_fee,
fee_transfer: false,
};
self.transfers.push(transfer);

let transfer = Transfer::<T> {
from: &self.intention_b.who,
from: &self.intention_b.who,
to: &self.intention_a.who,
asset: self.intention_a.assets.asset_out,
amount: self.amount_from_b,
fee_transfer: false,
};
self.transfers.push(transfer);

let transfer = Transfer::<T> {
from: &self.intention_a.who,
to: pool_account,
asset: self.intention_b.assets.asset_out,
amount: transfer_b_fee,
asset: self.intention_a.assets.asset_in,
amount: 2 * transfer_a_fee,
fee_transfer: true,
};
self.transfers.push(transfer);
}
(IntentionType::SELL, IntentionType::BUY) => {
if !Self::reserve_if_can(self.intention_a.assets.asset_out, &self.intention_a.who, transfer_a_fee) {
return false;
if !Self::reserve_if_can(
self.intention_a.assets.asset_in,
&self.intention_a.who,
self.amount_from_a,
) {
return false;
}
if !Self::reserve_if_can(self.intention_b.assets.asset_in, &self.intention_b.who, transfer_b_fee) {
return false;

if !Self::reserve_if_can(
self.intention_a.assets.asset_out,
&self.intention_b.who,
self.amount_from_b + transfer_b_fee,
) {
return false;
}

let transfer = Transfer::<T> {
from: &self.intention_a.who,
to: pool_account,
asset: self.intention_a.assets.asset_out,
amount: transfer_a_fee,
fee_transfer: true,
from: &self.intention_a.who,
to: &self.intention_b.who,
asset: self.intention_a.assets.asset_in,
amount: self.amount_from_a,
fee_transfer: false,
};
self.transfers.push(transfer);

let transfer = Transfer::<T> {
from: &self.intention_b.who,
to: &self.intention_a.who,
asset: self.intention_a.assets.asset_out,
amount: self.amount_from_b - transfer_b_fee,
fee_transfer: false,
};
self.transfers.push(transfer);

let transfer = Transfer::<T> {
from: &self.intention_b.who,
to: pool_account,
asset: self.intention_b.assets.asset_in,
amount: transfer_b_fee,
amount: 2 * transfer_b_fee,
fee_transfer: true,
};
self.transfers.push(transfer);
Expand Down
17 changes: 12 additions & 5 deletions pallets/exchange/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ pub type Intention<T> = ExchangeIntention<<T as system::Config>::AccountId, Bala

// Re-export pallet items so that they can be accessed from the crate namespace.
pub use pallet::*;
use frame_support::pallet_prelude::*;

#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::OriginFor;

#[pallet::pallet]
Expand Down Expand Up @@ -193,6 +193,9 @@ pub mod pallet {

/// Trade amount is too low.
MinimumTradeLimitNotReached,

/// Overflow
IntentionCountOverflow
}

/// Intention count for current block
Expand Down Expand Up @@ -349,7 +352,7 @@ impl<T: Config> Pallet<T> {
amount_out: Balance,
limit: Balance,
discount: bool,
) -> dispatch::DispatchResult {
) -> DispatchResult {
let intention_count = ExchangeAssetsIntentionCount::<T>::get(assets.ordered_pair());

let intention_id = Self::generate_intention_id(who, intention_count, &assets);
Expand All @@ -364,11 +367,15 @@ impl<T: Config> Pallet<T> {
intention_id,
trade_limit: limit,
};

ExchangeAssetsIntentionCount::<T>::try_mutate(assets.ordered_pair(), |total| -> DispatchResult {
*total = total.checked_add(1).ok_or(Error::<T>::IntentionCountOverflow)?;
Ok(())
})?;

// Note: cannot use ordered tuple pair, as this must be stored as (in,out) pair
<ExchangeAssetsIntentions<T>>::append((assets.asset_in, assets.asset_out), intention);

ExchangeAssetsIntentionCount::<T>::mutate(assets.ordered_pair(), |total| *total += 1u32);

match intention_type {
IntentionType::SELL => {
Self::deposit_event(Event::IntentionRegistered(
Expand Down Expand Up @@ -453,7 +460,7 @@ impl<T: Config> Pallet<T> {
amm_tranfer_type: IntentionType,
intention_id: IntentionId<T>,
transfer: &AMMTransfer<T::AccountId, AssetId, AssetPair, Balance>,
) -> dispatch::DispatchResult {
) -> DispatchResult {
match amm_tranfer_type {
IntentionType::SELL => {
T::AMMPool::execute_sell(transfer)?;
Expand Down
Loading

0 comments on commit 27be8c5

Please sign in to comment.