Skip to content

Commit

Permalink
Refactor: Extract swapping part from FI into pallet-swaps (#1724)
Browse files Browse the repository at this point in the history
* pallet structure

* finished implementation

* adapt pallets to trait changes

* Use swapping in FI from pallet-swaps

* adapt runtimes

* adapt integration-tests

* taplo fmt

* fix clippy

* fix IT

* fix typo

* change pallet index
  • Loading branch information
lemunozm authored Feb 16, 2024
1 parent db2209f commit 55cc271
Show file tree
Hide file tree
Showing 32 changed files with 1,115 additions and 783 deletions.
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ members = [
"pallets/pool-registry",
"pallets/restricted-tokens",
"pallets/restricted-xtokens",
"pallets/transfer-allowlist",
"pallets/rewards",
"pallets/swaps",
"pallets/transfer-allowlist",
"runtime/altair",
"runtime/centrifuge",
"runtime/development",
Expand Down Expand Up @@ -286,6 +287,7 @@ pallet-pool-system = { path = "pallets/pool-system", default-features = false }
pallet-restricted-tokens = { path = "pallets/restricted-tokens", default-features = false }
pallet-restricted-xtokens = { path = "pallets/restricted-xtokens", default-features = false }
pallet-rewards = { path = "pallets/rewards", default-features = false }
pallet-swaps = { path = "pallets/swaps", default-features = false }
pallet-transfer-allowlist = { path = "pallets/transfer-allowlist", default-features = false }

# Centrifuge libs
Expand Down
10 changes: 5 additions & 5 deletions libs/mocks/src/token_swaps.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[frame_support::pallet]
pub mod pallet {
use cfg_traits::{OrderRatio, TokenSwaps};
use cfg_traits::{OrderRatio, Swap, TokenSwaps};
use frame_support::pallet_prelude::*;
use mock_builder::{execute_call, register_call};

Expand All @@ -11,7 +11,6 @@ pub mod pallet {
type BalanceOut;
type Ratio;
type OrderId;
type OrderDetails;
}

#[pallet::pallet]
Expand Down Expand Up @@ -59,7 +58,9 @@ pub mod pallet {
register_call!(move |(a, b)| f(a, b));
}

pub fn mock_get_order_details(f: impl Fn(T::OrderId) -> Option<T::OrderDetails> + 'static) {
pub fn mock_get_order_details(
f: impl Fn(T::OrderId) -> Option<Swap<T::BalanceOut, T::CurrencyId>> + 'static,
) {
register_call!(f);
}

Expand All @@ -79,7 +80,6 @@ pub mod pallet {
type BalanceIn = T::BalanceOut;
type BalanceOut = T::BalanceIn;
type CurrencyId = T::CurrencyId;
type OrderDetails = T::OrderDetails;
type OrderId = T::OrderId;
type Ratio = T::Ratio;

Expand Down Expand Up @@ -109,7 +109,7 @@ pub mod pallet {
execute_call!((a, b))
}

fn get_order_details(a: Self::OrderId) -> Option<Self::OrderDetails> {
fn get_order_details(a: Self::OrderId) -> Option<Swap<Self::BalanceOut, Self::CurrencyId>> {
execute_call!(a)
}

Expand Down
104 changes: 102 additions & 2 deletions libs/traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,13 +510,41 @@ pub enum OrderRatio<Ratio> {
Custom(Ratio),
}

/// A simple representation of a currency swap.
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct Swap<Amount, Currency> {
/// The incoming currency, i.e. the desired one.
pub currency_in: Currency,

/// The outgoing currency, i.e. the one which should be replaced.
pub currency_out: Currency,

/// The amount of outcoming currency that will be swapped.
pub amount_out: Amount,
}

impl<Amount, Currency: PartialEq> Swap<Amount, Currency> {
pub fn has_same_currencies(&self) -> bool {
self.currency_in == self.currency_out
}

pub fn is_same_direction(&self, other: &Self) -> Result<bool, DispatchError> {
if self.currency_in == other.currency_in && self.currency_out == other.currency_out {
Ok(true)
} else if self.currency_in == other.currency_out && self.currency_out == other.currency_in {
Ok(false)
} else {
Err(DispatchError::Other("Swap contains different currencies"))
}
}
}

pub trait TokenSwaps<Account> {
type CurrencyId;
type BalanceOut;
type BalanceIn;
type Ratio;
type OrderId;
type OrderDetails;

/// Swap tokens selling `amount_out` of `currency_out` and buying
/// `currency_in` given an order ratio.
Expand Down Expand Up @@ -544,7 +572,7 @@ pub trait TokenSwaps<Account> {
fn cancel_order(order: Self::OrderId) -> DispatchResult;

/// Retrieve the details of the order if it exists.
fn get_order_details(order: Self::OrderId) -> Option<Self::OrderDetails>;
fn get_order_details(order: Self::OrderId) -> Option<Swap<Self::BalanceOut, Self::CurrencyId>>;

/// Makes a conversion between 2 currencies using the market ratio between
/// them
Expand All @@ -555,6 +583,78 @@ pub trait TokenSwaps<Account> {
) -> Result<Self::BalanceIn, DispatchError>;
}

/// A representation of a currency swap in process.
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct SwapState<AmountIn, AmountOut, Currency> {
/// Swap not yet processed with the pending outcomming amount
pub remaining: Swap<AmountOut, Currency>,

/// Amount of incoming currency already swapped
pub swapped_in: AmountIn,

/// Amount of incoming currency already swapped denominated in outgoing
/// currency
pub swapped_out: AmountOut,
}

/// Used as result of `Pallet::apply_swap()`
/// Amounts are donominated referenced by the `new_swap` paramenter given to
/// `apply_swap()`
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct SwapStatus<Amount> {
/// The incoming amount already swapped and available to use.
pub swapped: Amount,

/// The outgoing amount pending to be swapped
pub pending: Amount,
}

/// Trait to perform swaps without handling directly an order book
pub trait Swaps<AccountId> {
type Amount;
type CurrencyId;
type SwapId;

/// Apply a swap over a current possible swap state.
/// - If there was no previous swap, it adds it.
/// - If there was a swap in the same direction, it increments it.
/// - If there was a swap in the opposite direction:
/// - If the amount is smaller, it decrements it.
/// - If the amount is the same, it removes the inverse swap.
/// - If the amount is greater, it removes the inverse swap and create
/// another with the excess
///
/// The returned status contains the swapped amount after this call
/// (denominated in the incoming currency) and the pending amounts to be
/// swapped.
fn apply_swap(
who: &AccountId,
swap_id: Self::SwapId,
swap: Swap<Self::Amount, Self::CurrencyId>,
) -> Result<SwapStatus<Self::Amount>, DispatchError>;

/// Returns the pending amount for a pending swap. The direction of the swap
/// is determined by the `from_currency` parameter. The amount returned is
/// denominated in the same currency as the given `from_currency`.
fn pending_amount(
who: &AccountId,
swap_id: Self::SwapId,
from_currency: Self::CurrencyId,
) -> Result<Self::Amount, DispatchError>;

/// Check that validates that if swapping pair is supported.
fn valid_pair(currency_in: Self::CurrencyId, currency_out: Self::CurrencyId) -> bool;

/// Makes a conversion between 2 currencies using the market ratio between
/// them
// TODO: Should be removed after #1723
fn convert_by_market(
currency_in: Self::CurrencyId,
currency_out: Self::CurrencyId,
amount_out: Self::Amount,
) -> Result<Self::Amount, DispatchError>;
}

/// Trait to transmit a change of status for anything uniquely identifiable.
///
/// NOTE: The main use case to handle asynchronous operations.
Expand Down
43 changes: 2 additions & 41 deletions libs/types/src/investments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
// GNU General Public License for more details.

use cfg_primitives::OrderId;
use frame_support::{dispatch::fmt::Debug, RuntimeDebug};
use frame_support::RuntimeDebug;
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_runtime::{
traits::{EnsureAddAssign, Zero},
DispatchError, DispatchResult,
DispatchResult,
};
use sp_std::cmp::PartialEq;

Expand Down Expand Up @@ -142,45 +142,6 @@ impl<Collected: EnsureAddAssign + Copy, Payment: EnsureAddAssign + Copy>
}
}

/// A simple representation of a currency swap.
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct Swap<Balance, Currency> {
/// The incoming currency, i.e. the desired one.
pub currency_in: Currency,
/// The outgoing currency, i.e. the one which should be replaced.
pub currency_out: Currency,
/// The amount of outcoming currency that will be swapped.
pub amount_out: Balance,
}

impl<Balance, Currency: PartialEq> Swap<Balance, Currency> {
pub fn has_same_currencies(&self) -> bool {
self.currency_in == self.currency_out
}

pub fn is_same_direction(&self, other: &Self) -> Result<bool, DispatchError> {
if self.currency_in == other.currency_in && self.currency_out == other.currency_out {
Ok(true)
} else if self.currency_in == other.currency_out && self.currency_out == other.currency_in {
Ok(false)
} else {
Err(DispatchError::Other("Swap contains different currencies"))
}
}
}

/// A representation of a currency swap in process.
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct SwapState<BalanceIn, BalanceOut, Currency> {
/// Swap not yet processed with the pending outcomming amount
pub remaining: Swap<BalanceOut, Currency>,
/// Amount of incoming currency already swapped
pub swapped_in: BalanceIn,
/// Amount of incoming currency already swapped denominated in outgoing
/// currency
pub swapped_out: BalanceOut,
}

/// A representation of an executed investment decrement.
#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)]
pub struct ExecutedForeignDecreaseInvest<Balance, Currency> {
Expand Down
3 changes: 3 additions & 0 deletions pallets/foreign-investments/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ sp-core = { workspace = true, default-features = true }
sp-io = { workspace = true, default-features = true }

cfg-mocks = { workspace = true, default-features = true }
pallet-swaps = { workspace = true, default-features = true }

[features]
default = ["std"]
Expand All @@ -54,6 +55,7 @@ runtime-benchmarks = [
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"cfg-mocks/runtime-benchmarks",
"pallet-swaps/runtime-benchmarks",
]
try-runtime = [
"cfg-traits/try-runtime",
Expand All @@ -62,4 +64,5 @@ try-runtime = [
"frame-system/try-runtime",
"sp-runtime/try-runtime",
"cfg-mocks/try-runtime",
"pallet-swaps/try-runtime",
]
Loading

0 comments on commit 55cc271

Please sign in to comment.