From 014d7d6b37ad8055232ae95ed6ccad673cac580b Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 30 Jun 2023 19:31:57 -0300 Subject: [PATCH 1/2] Initial implementation of primitives-currency-swap-proxy --- Cargo.lock | 8 ++ .../primitives-currency-swap-proxy/Cargo.toml | 15 ++++ .../primitives-currency-swap-proxy/src/lib.rs | 76 +++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 crates/primitives-currency-swap-proxy/Cargo.toml create mode 100644 crates/primitives-currency-swap-proxy/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 2ec96fc9d..048f68bee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6839,6 +6839,14 @@ dependencies = [ "frame-support", ] +[[package]] +name = "primitives-currency-swap-proxy" +version = "0.1.0" +dependencies = [ + "frame-support", + "primitives-currency-swap", +] + [[package]] name = "primitives-ethereum" version = "0.1.0" diff --git a/crates/primitives-currency-swap-proxy/Cargo.toml b/crates/primitives-currency-swap-proxy/Cargo.toml new file mode 100644 index 000000000..42f02b79d --- /dev/null +++ b/crates/primitives-currency-swap-proxy/Cargo.toml @@ -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"] diff --git a/crates/primitives-currency-swap-proxy/src/lib.rs b/crates/primitives-currency-swap-proxy/src/lib.rs new file mode 100644 index 000000000..63fd487ef --- /dev/null +++ b/crates/primitives-currency-swap-proxy/src/lib.rs @@ -0,0 +1,76 @@ +//! 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::Error`] of [`Config::CurrencySwap`]. +type CurrencySwapErrorFor = <::CurrencySwap as CurrencySwap< + ::AccountIdFrom, + ::AccountIdTo, +>>::Error; + +/// A utility type alias for easy access to [`CurrencySwap::From`] of [`Config::CurrencySwap`]. +type CurrencyFromFor = <::CurrencySwap as CurrencySwap< + ::AccountIdFrom, + ::AccountIdTo, +>>::From; + +/// A utility type alias for easy access to [`CurrencySwap::To`] of [`Config::CurrencySwap`]. +type CurrencyToFor = <::CurrencySwap as CurrencySwap< + ::AccountIdFrom, + ::AccountIdTo, +>>::To; + +/// A utility type alias for easy access to [`Currency::NegativeImbalance`] of +/// [`CurrencySwap::From`] of [`Config::CurrencySwap`]. +type CurrencyFromNegativeImbalanceFor = + as Currency<::AccountIdFrom>>::NegativeImbalance; + +/// A utility type alias for easy access to [`Currency::NegativeImbalance`] of +/// [`CurrencySwap::To`] of [`Config::CurrencySwap`]. +type CurrencyToNegativeImbalanceFor = + as Currency<::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; +} + +/// 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(PhantomData<(T, To, Fallback)>); + +impl OnUnbalanced> + for SwapUnbalanced +where + T: Config, + To: OnUnbalanced>, + Fallback: OnUnbalanced>, + CurrencySwapErrorFor: Into>>, +{ + fn on_nonzero_unbalanced(amount: CurrencyFromNegativeImbalanceFor) { + let amount = match T::CurrencySwap::swap(amount) { + Ok(amount) => amount, + Err(error) => { + if let Some(amount) = error.into() { + Fallback::on_unbalanceds(std::iter::once(amount)); + } + return; + } + }; + To::on_unbalanceds(std::iter::once(amount)) + } +} From d3422cea9db257b604b3bf7aaa2f0b4fefc67231 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Sat, 1 Jul 2023 11:54:42 -0300 Subject: [PATCH 2/2] Adjust the implementation for the currency swap fix --- .../primitives-currency-swap-proxy/src/lib.rs | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/crates/primitives-currency-swap-proxy/src/lib.rs b/crates/primitives-currency-swap-proxy/src/lib.rs index 63fd487ef..0b1373712 100644 --- a/crates/primitives-currency-swap-proxy/src/lib.rs +++ b/crates/primitives-currency-swap-proxy/src/lib.rs @@ -9,12 +9,6 @@ use frame_support::{ }; use primitives_currency_swap::CurrencySwap; -/// A utility type alias for easy access to [`CurrencySwap::Error`] of [`Config::CurrencySwap`]. -type CurrencySwapErrorFor = <::CurrencySwap as CurrencySwap< - ::AccountIdFrom, - ::AccountIdTo, ->>::Error; - /// A utility type alias for easy access to [`CurrencySwap::From`] of [`Config::CurrencySwap`]. type CurrencyFromFor = <::CurrencySwap as CurrencySwap< ::AccountIdFrom, @@ -59,15 +53,20 @@ where T: Config, To: OnUnbalanced>, Fallback: OnUnbalanced>, - CurrencySwapErrorFor: Into>>, { fn on_nonzero_unbalanced(amount: CurrencyFromNegativeImbalanceFor) { let amount = match T::CurrencySwap::swap(amount) { Ok(amount) => amount, - Err(error) => { - if let Some(amount) = error.into() { - Fallback::on_unbalanceds(std::iter::once(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; } };