Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.lock

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

15 changes: 15 additions & 0 deletions crates/primitives-currency-swap-proxy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "primitives-currency-swap-proxy"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
primitives-currency-swap = { version = "0.1", path = "../primitives-currency-swap" }

frame-support = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" }

[features]
default = ["std"]
std = ["frame-support/std", "primitives-currency-swap/std"]
try-runtime = ["frame-support/try-runtime", "primitives-currency-swap/try-runtime"]
75 changes: 75 additions & 0 deletions crates/primitives-currency-swap-proxy/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//! Currency swap proxy related primitives.

// Either generate code at stadard mode, or `no_std`, based on the `std` feature presence.
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::{
sp_std::marker::PhantomData,
traits::{Currency, OnUnbalanced},
};
use primitives_currency_swap::CurrencySwap;

/// A utility type alias for easy access to [`CurrencySwap::From`] of [`Config::CurrencySwap`].
type CurrencyFromFor<T> = <<T as Config>::CurrencySwap as CurrencySwap<
<T as Config>::AccountIdFrom,
<T as Config>::AccountIdTo,
>>::From;

/// A utility type alias for easy access to [`CurrencySwap::To`] of [`Config::CurrencySwap`].
type CurrencyToFor<T> = <<T as Config>::CurrencySwap as CurrencySwap<
<T as Config>::AccountIdFrom,
<T as Config>::AccountIdTo,
>>::To;

/// A utility type alias for easy access to [`Currency::NegativeImbalance`] of
/// [`CurrencySwap::From`] of [`Config::CurrencySwap`].
type CurrencyFromNegativeImbalanceFor<T> =
<CurrencyFromFor<T> as Currency<<T as Config>::AccountIdFrom>>::NegativeImbalance;

/// A utility type alias for easy access to [`Currency::NegativeImbalance`] of
/// [`CurrencySwap::To`] of [`Config::CurrencySwap`].
type CurrencyToNegativeImbalanceFor<T> =
<CurrencyToFor<T> as Currency<<T as Config>::AccountIdTo>>::NegativeImbalance;

/// The general config for the currency swap proxy implementations.
pub trait Config {
/// The type used as an Account ID for the currency we proxy from.
type AccountIdFrom;
/// The type used as an Account ID for the currency we proxy to.
type AccountIdTo;

/// The curreny swap implementation to use for proxying.
type CurrencySwap: CurrencySwap<Self::AccountIdFrom, Self::AccountIdTo>;
}

/// An [`OnUnbalanced`] implementation that routes the imbalance through the currency swap and
/// passes the resulting imbalance to the `To`.
/// If swap fails, will try to pass the original imbalance to the `Fallback`.
pub struct SwapUnbalanced<T, To, Fallback>(PhantomData<(T, To, Fallback)>);

impl<T, To, Fallback> OnUnbalanced<CurrencyFromNegativeImbalanceFor<T>>
for SwapUnbalanced<T, To, Fallback>
where
T: Config,
To: OnUnbalanced<CurrencyToNegativeImbalanceFor<T>>,
Fallback: OnUnbalanced<CurrencyFromNegativeImbalanceFor<T>>,
{
fn on_nonzero_unbalanced(amount: CurrencyFromNegativeImbalanceFor<T>) {
let amount = match T::CurrencySwap::swap(amount) {
Ok(amount) => amount,
Err(primitives_currency_swap::Error {
cause: error,
incoming_imbalance,
}) => {
let error: frame_support::sp_runtime::DispatchError = error.into();
frame_support::sp_tracing::error!(
message = "unable to route the funds through the swap",
?error
);
Fallback::on_unbalanceds(std::iter::once(incoming_imbalance));
return;
}
};
To::on_unbalanceds(std::iter::once(amount))
}
}