From 0aedeefb76aa97fbf4ff5e8880585b9a92c5af03 Mon Sep 17 00:00:00 2001 From: Dmitry Lavrenov Date: Fri, 30 Jun 2023 16:21:44 +0300 Subject: [PATCH 1/8] Init basic structure --- Cargo.lock | 9 ++++++ crates/bridge-pot-currency-swap/Cargo.toml | 17 +++++++++++ crates/bridge-pot-currency-swap/src/lib.rs | 35 ++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 crates/bridge-pot-currency-swap/Cargo.toml create mode 100644 crates/bridge-pot-currency-swap/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 7cbe180bf..53448d395 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -776,6 +776,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "bridge-pot-currency-swap" +version = "0.1.0" +dependencies = [ + "frame-support", + "primitives-currency-swap", + "sp-std", +] + [[package]] name = "bs58" version = "0.4.0" diff --git a/crates/bridge-pot-currency-swap/Cargo.toml b/crates/bridge-pot-currency-swap/Cargo.toml new file mode 100644 index 000000000..a765f3ebc --- /dev/null +++ b/crates/bridge-pot-currency-swap/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "bridge-pot-currency-swap" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +primitives-currency-swap = { version = "0.1", path = "../primitives-currency-swap", default-features = false } + +frame-support = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" } +sp-std = { 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", "sp-std/std"] +try-runtime = ["frame-support/try-runtime", "primitives-currency-swap/try-runtime"] diff --git a/crates/bridge-pot-currency-swap/src/lib.rs b/crates/bridge-pot-currency-swap/src/lib.rs new file mode 100644 index 000000000..dec837a2a --- /dev/null +++ b/crates/bridge-pot-currency-swap/src/lib.rs @@ -0,0 +1,35 @@ +//! Bridge pot currency swap implementation. + +// 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::{traits::Currency, sp_runtime::DispatchError}; +use primitives_currency_swap::CurrencySwap; +use sp_std::marker::PhantomData; + +pub struct OneToOne( + PhantomData<(AccountIdFrom, AccountIdTo, CurrencyFrom, CurrencyTo)>, +) +where + CurrencyFrom: Currency, + CurrencyTo: Currency; + +impl CurrencySwap + for OneToOne +where + CurrencyFrom: Currency, + CurrencyTo: Currency, +{ + type From = CurrencyFrom; + type To = CurrencyTo; + type Error = DispatchError; + + fn swap( + imbalance: >::NegativeImbalance, + ) -> Result< + >::NegativeImbalance, + Self::Error, + > { + todo!() + } +} From 07d3fd1a4936ca2de13c34f1026ae5800f9120a5 Mon Sep 17 00:00:00 2001 From: Dmitry Lavrenov Date: Fri, 30 Jun 2023 16:43:23 +0300 Subject: [PATCH 2/8] Implement swap logic --- crates/bridge-pot-currency-swap/src/lib.rs | 42 ++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/crates/bridge-pot-currency-swap/src/lib.rs b/crates/bridge-pot-currency-swap/src/lib.rs index dec837a2a..c3f344f85 100644 --- a/crates/bridge-pot-currency-swap/src/lib.rs +++ b/crates/bridge-pot-currency-swap/src/lib.rs @@ -3,22 +3,41 @@ // 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::{traits::Currency, sp_runtime::DispatchError}; +use frame_support::{ + sp_runtime::DispatchError, + traits::{Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons}, +}; use primitives_currency_swap::CurrencySwap; use sp_std::marker::PhantomData; -pub struct OneToOne( - PhantomData<(AccountIdFrom, AccountIdTo, CurrencyFrom, CurrencyTo)>, +pub trait Config { + type PotFrom: Get; + + type PotTo: Get; +} + +pub struct OneToOne( + PhantomData<( + AccountIdFrom, + AccountIdTo, + ConfigT, + CurrencyFrom, + CurrencyTo, + )>, ) where + ConfigT: Config, CurrencyFrom: Currency, CurrencyTo: Currency; -impl CurrencySwap - for OneToOne +impl + CurrencySwap + for OneToOne where + ConfigT: Config, CurrencyFrom: Currency, CurrencyTo: Currency, + CurrencyTo::Balance: From, { type From = CurrencyFrom; type To = CurrencyTo; @@ -30,6 +49,17 @@ where >::NegativeImbalance, Self::Error, > { - todo!() + let amount = imbalance.peek(); + + CurrencyFrom::resolve_creating(&ConfigT::PotFrom::get(), imbalance); + + let imbalance = CurrencyTo::withdraw( + &ConfigT::PotTo::get(), + amount.into(), + WithdrawReasons::TRANSFER, + ExistenceRequirement::AllowDeath, + )?; + + Ok(imbalance) } } From 0406a82ae42f73c53bc80cbc214258c0af985bee Mon Sep 17 00:00:00 2001 From: Dmitry Lavrenov Date: Fri, 30 Jun 2023 16:53:51 +0300 Subject: [PATCH 3/8] Add docs --- crates/bridge-pot-currency-swap/Cargo.toml | 1 - crates/bridge-pot-currency-swap/src/lib.rs | 11 ++++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/bridge-pot-currency-swap/Cargo.toml b/crates/bridge-pot-currency-swap/Cargo.toml index a765f3ebc..109234f10 100644 --- a/crates/bridge-pot-currency-swap/Cargo.toml +++ b/crates/bridge-pot-currency-swap/Cargo.toml @@ -10,7 +10,6 @@ primitives-currency-swap = { version = "0.1", path = "../primitives-currency-swa frame-support = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" } sp-std = { 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", "sp-std/std"] diff --git a/crates/bridge-pot-currency-swap/src/lib.rs b/crates/bridge-pot-currency-swap/src/lib.rs index c3f344f85..35dab8a56 100644 --- a/crates/bridge-pot-currency-swap/src/lib.rs +++ b/crates/bridge-pot-currency-swap/src/lib.rs @@ -10,12 +10,16 @@ use frame_support::{ use primitives_currency_swap::CurrencySwap; use sp_std::marker::PhantomData; +/// The config for the generic bridge pot currency swap logic. pub trait Config { + /// The pot account used to receive withdrawed balances to. type PotFrom: Get; + /// The pot account used to send deposited balances from. type PotTo: Get; } +/// One to one bridge pot currency swap logic. pub struct OneToOne( PhantomData<( AccountIdFrom, @@ -44,11 +48,8 @@ where type Error = DispatchError; fn swap( - imbalance: >::NegativeImbalance, - ) -> Result< - >::NegativeImbalance, - Self::Error, - > { + imbalance: CurrencyFrom::NegativeImbalance, + ) -> Result { let amount = imbalance.peek(); CurrencyFrom::resolve_creating(&ConfigT::PotFrom::get(), imbalance); From ca88520488d142323cacc9ef50b4390735b607d2 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 30 Jun 2023 17:50:54 -0300 Subject: [PATCH 4/8] Redo the implementation --- .../src/existence_optional.rs | 37 +++++++++ .../src/existence_required.rs | 57 +++++++++++++ crates/bridge-pot-currency-swap/src/lib.rs | 80 +++++++------------ 3 files changed, 125 insertions(+), 49 deletions(-) create mode 100644 crates/bridge-pot-currency-swap/src/existence_optional.rs create mode 100644 crates/bridge-pot-currency-swap/src/existence_required.rs diff --git a/crates/bridge-pot-currency-swap/src/existence_optional.rs b/crates/bridge-pot-currency-swap/src/existence_optional.rs new file mode 100644 index 000000000..a8fcdc318 --- /dev/null +++ b/crates/bridge-pot-currency-swap/src/existence_optional.rs @@ -0,0 +1,37 @@ +//! An implementation that does not require pot account existence and can potentially kill the +//! pot account by withdrawing all the funds from it. + +use frame_support::{ + sp_runtime::{traits::Convert, DispatchError}, + traits::{Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons}, +}; + +use super::{Config, CurrencySwap}; + +/// A marker type for the implementation that does not require pot accounts existence. +pub enum Marker {} + +impl primitives_currency_swap::CurrencySwap + for CurrencySwap +{ + type From = T::CurrencyFrom; + type To = T::CurrencyTo; + type Error = DispatchError; + + fn swap( + imbalance: >::NegativeImbalance, + ) -> Result<>::NegativeImbalance, Self::Error> { + let amount = imbalance.peek(); + + T::CurrencyFrom::resolve_creating(&T::PotFrom::get(), imbalance); + + let imbalance = T::CurrencyTo::withdraw( + &T::PotTo::get(), + T::BalanceCoverter::convert(amount), + WithdrawReasons::TRANSFER, + ExistenceRequirement::AllowDeath, + )?; + + Ok(imbalance) + } +} diff --git a/crates/bridge-pot-currency-swap/src/existence_required.rs b/crates/bridge-pot-currency-swap/src/existence_required.rs new file mode 100644 index 000000000..1d2a3f167 --- /dev/null +++ b/crates/bridge-pot-currency-swap/src/existence_required.rs @@ -0,0 +1,57 @@ +//! An implementation that requires and ensures pot account existence. + +use frame_support::{ + sp_runtime::{traits::Convert, DispatchError}, + traits::{Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons}, +}; + +use super::{Config, CurrencySwap}; + +/// A marker type for the implementation that requires pot accounts existence. +pub enum Marker {} + +/// An error that can occur while doing the swap operation. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Error { + /// Unable to resolve the incoming balance into the corresponding pot. + ResolvingIncomingImbalance(ImbalanceFrom), + /// Unable to withdraw the outpoing balance from the corresponding pot. + IssuingOutgoingImbalance(DispatchError), +} + +impl From> for DispatchError { + fn from(value: Error) -> Self { + match value { + Error::ResolvingIncomingImbalance(_) => DispatchError::NoProviders, + Error::IssuingOutgoingImbalance(err) => err, + } + } +} + +impl primitives_currency_swap::CurrencySwap + for CurrencySwap +{ + type From = T::CurrencyFrom; + type To = T::CurrencyTo; + type Error = + Error<<::CurrencyFrom as Currency>::NegativeImbalance>; + + fn swap( + imbalance: >::NegativeImbalance, + ) -> Result<>::NegativeImbalance, Self::Error> { + let amount = imbalance.peek(); + + T::CurrencyFrom::resolve_into_existing(&T::PotFrom::get(), imbalance) + .map_err(Error::ResolvingIncomingImbalance)?; + + let imbalance = T::CurrencyTo::withdraw( + &T::PotTo::get(), + T::BalanceCoverter::convert(amount), + WithdrawReasons::TRANSFER, + ExistenceRequirement::KeepAlive, + ) + .map_err(Error::IssuingOutgoingImbalance)?; + + Ok(imbalance) + } +} diff --git a/crates/bridge-pot-currency-swap/src/lib.rs b/crates/bridge-pot-currency-swap/src/lib.rs index 35dab8a56..303c5adbc 100644 --- a/crates/bridge-pot-currency-swap/src/lib.rs +++ b/crates/bridge-pot-currency-swap/src/lib.rs @@ -4,63 +4,45 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::{ - sp_runtime::DispatchError, - traits::{Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons}, + sp_runtime::traits::Convert, + traits::{Currency, Get}, }; -use primitives_currency_swap::CurrencySwap; use sp_std::marker::PhantomData; -/// The config for the generic bridge pot currency swap logic. -pub trait Config { - /// The pot account used to receive withdrawed balances to. - type PotFrom: Get; +pub mod existence_optional; +pub mod existence_required; - /// The pot account used to send deposited balances from. - type PotTo: Get; -} +pub use existence_optional::Marker as ExistenceOptional; +pub use existence_required::Marker as ExistenceRequired; -/// One to one bridge pot currency swap logic. -pub struct OneToOne( - PhantomData<( - AccountIdFrom, - AccountIdTo, - ConfigT, - CurrencyFrom, - CurrencyTo, - )>, -) -where - ConfigT: Config, - CurrencyFrom: Currency, - CurrencyTo: Currency; +/// The config for the generic bridge pot currency swap logic. +pub trait Config { + /// The type representing the account for the currency to swap from. + type AccountFrom; -impl - CurrencySwap - for OneToOne -where - ConfigT: Config, - CurrencyFrom: Currency, - CurrencyTo: Currency, - CurrencyTo::Balance: From, -{ - type From = CurrencyFrom; - type To = CurrencyTo; - type Error = DispatchError; + /// The type representing the account for the currency to swap to. + type AccountTo; - fn swap( - imbalance: CurrencyFrom::NegativeImbalance, - ) -> Result { - let amount = imbalance.peek(); + /// The currency to swap from. + type CurrencyFrom: Currency; - CurrencyFrom::resolve_creating(&ConfigT::PotFrom::get(), imbalance); + /// The currency to swap to. + type CurrencyTo: Currency; - let imbalance = CurrencyTo::withdraw( - &ConfigT::PotTo::get(), - amount.into(), - WithdrawReasons::TRANSFER, - ExistenceRequirement::AllowDeath, - )?; + /// The converter to determine how the balance amount should be converted from one currency to + /// another. + type BalanceCoverter: Convert< + >::Balance, + >::Balance, + >; - Ok(imbalance) - } + /// The account to land the balances to when receiving the funds as part of the swap operation. + type PotFrom: Get; + + /// The account to take the balances from when sending the funds as part of the swap operation. + type PotTo: Get; } + +/// A [`primitives_currency_swap::CurrencySwap`] implementation that does the swap using two +/// "pot" accounts for each of end swaped currencies. +pub struct CurrencySwap(PhantomData<(T, ExistenceRequirement)>); From 36945357ee5ebcc3b24775c82c631127ea00c982 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 30 Jun 2023 17:52:23 -0300 Subject: [PATCH 5/8] Eliminate one redundant dependency --- Cargo.lock | 1 - crates/bridge-pot-currency-swap/Cargo.toml | 3 +-- crates/bridge-pot-currency-swap/src/lib.rs | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53448d395..2ec96fc9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -782,7 +782,6 @@ version = "0.1.0" dependencies = [ "frame-support", "primitives-currency-swap", - "sp-std", ] [[package]] diff --git a/crates/bridge-pot-currency-swap/Cargo.toml b/crates/bridge-pot-currency-swap/Cargo.toml index 109234f10..e02df5338 100644 --- a/crates/bridge-pot-currency-swap/Cargo.toml +++ b/crates/bridge-pot-currency-swap/Cargo.toml @@ -8,9 +8,8 @@ publish = false primitives-currency-swap = { version = "0.1", path = "../primitives-currency-swap", default-features = false } frame-support = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" } -sp-std = { 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", "sp-std/std"] +std = ["frame-support/std", "primitives-currency-swap/std"] try-runtime = ["frame-support/try-runtime", "primitives-currency-swap/try-runtime"] diff --git a/crates/bridge-pot-currency-swap/src/lib.rs b/crates/bridge-pot-currency-swap/src/lib.rs index 303c5adbc..3886165a0 100644 --- a/crates/bridge-pot-currency-swap/src/lib.rs +++ b/crates/bridge-pot-currency-swap/src/lib.rs @@ -5,9 +5,9 @@ use frame_support::{ sp_runtime::traits::Convert, + sp_std::marker::PhantomData, traits::{Currency, Get}, }; -use sp_std::marker::PhantomData; pub mod existence_optional; pub mod existence_required; From 383fdae392f27916db3cfe8fe118613a3220db7a Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Fri, 30 Jun 2023 19:10:22 -0300 Subject: [PATCH 6/8] Fix the account id associated type names --- .../src/existence_optional.rs | 6 +++--- .../src/existence_required.rs | 8 ++++---- crates/bridge-pot-currency-swap/src/lib.rs | 20 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/crates/bridge-pot-currency-swap/src/existence_optional.rs b/crates/bridge-pot-currency-swap/src/existence_optional.rs index a8fcdc318..27db74dcf 100644 --- a/crates/bridge-pot-currency-swap/src/existence_optional.rs +++ b/crates/bridge-pot-currency-swap/src/existence_optional.rs @@ -11,7 +11,7 @@ use super::{Config, CurrencySwap}; /// A marker type for the implementation that does not require pot accounts existence. pub enum Marker {} -impl primitives_currency_swap::CurrencySwap +impl primitives_currency_swap::CurrencySwap for CurrencySwap { type From = T::CurrencyFrom; @@ -19,8 +19,8 @@ impl primitives_currency_swap::CurrencySwap>::NegativeImbalance, - ) -> Result<>::NegativeImbalance, Self::Error> { + imbalance: >::NegativeImbalance, + ) -> Result<>::NegativeImbalance, Self::Error> { let amount = imbalance.peek(); T::CurrencyFrom::resolve_creating(&T::PotFrom::get(), imbalance); diff --git a/crates/bridge-pot-currency-swap/src/existence_required.rs b/crates/bridge-pot-currency-swap/src/existence_required.rs index 1d2a3f167..d08b49cba 100644 --- a/crates/bridge-pot-currency-swap/src/existence_required.rs +++ b/crates/bridge-pot-currency-swap/src/existence_required.rs @@ -28,17 +28,17 @@ impl From> for DispatchError { } } -impl primitives_currency_swap::CurrencySwap +impl primitives_currency_swap::CurrencySwap for CurrencySwap { type From = T::CurrencyFrom; type To = T::CurrencyTo; type Error = - Error<<::CurrencyFrom as Currency>::NegativeImbalance>; + Error<<::CurrencyFrom as Currency>::NegativeImbalance>; fn swap( - imbalance: >::NegativeImbalance, - ) -> Result<>::NegativeImbalance, Self::Error> { + imbalance: >::NegativeImbalance, + ) -> Result<>::NegativeImbalance, Self::Error> { let amount = imbalance.peek(); T::CurrencyFrom::resolve_into_existing(&T::PotFrom::get(), imbalance) diff --git a/crates/bridge-pot-currency-swap/src/lib.rs b/crates/bridge-pot-currency-swap/src/lib.rs index 3886165a0..11c601ba7 100644 --- a/crates/bridge-pot-currency-swap/src/lib.rs +++ b/crates/bridge-pot-currency-swap/src/lib.rs @@ -17,30 +17,30 @@ pub use existence_required::Marker as ExistenceRequired; /// The config for the generic bridge pot currency swap logic. pub trait Config { - /// The type representing the account for the currency to swap from. - type AccountFrom; + /// The type representing the account key for the currency to swap from. + type AccountIdFrom; - /// The type representing the account for the currency to swap to. - type AccountTo; + /// The type representing the account key for the currency to swap to. + type AccountIdTo; /// The currency to swap from. - type CurrencyFrom: Currency; + type CurrencyFrom: Currency; /// The currency to swap to. - type CurrencyTo: Currency; + type CurrencyTo: Currency; /// The converter to determine how the balance amount should be converted from one currency to /// another. type BalanceCoverter: Convert< - >::Balance, - >::Balance, + >::Balance, + >::Balance, >; /// The account to land the balances to when receiving the funds as part of the swap operation. - type PotFrom: Get; + type PotFrom: Get; /// The account to take the balances from when sending the funds as part of the swap operation. - type PotTo: Get; + type PotTo: Get; } /// A [`primitives_currency_swap::CurrencySwap`] implementation that does the swap using two From 67bec669eec40b815765e0a1ec9b39a235e21896 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Sat, 1 Jul 2023 04:38:50 -0300 Subject: [PATCH 7/8] Update crates/bridge-pot-currency-swap/src/lib.rs Co-authored-by: Dmitry Lavrenov <39522748+dmitrylavrenov@users.noreply.github.com> --- crates/bridge-pot-currency-swap/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bridge-pot-currency-swap/src/lib.rs b/crates/bridge-pot-currency-swap/src/lib.rs index 11c601ba7..36132faea 100644 --- a/crates/bridge-pot-currency-swap/src/lib.rs +++ b/crates/bridge-pot-currency-swap/src/lib.rs @@ -44,5 +44,5 @@ pub trait Config { } /// A [`primitives_currency_swap::CurrencySwap`] implementation that does the swap using two -/// "pot" accounts for each of end swaped currencies. +/// "pot" accounts for each of end swapped currencies. pub struct CurrencySwap(PhantomData<(T, ExistenceRequirement)>); From 4f12d18529a3ef3bc971a5f168d0462fe2e879d8 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Sat, 1 Jul 2023 04:45:28 -0300 Subject: [PATCH 8/8] Update crates/bridge-pot-currency-swap/src/existence_required.rs Co-authored-by: Dmitry Lavrenov <39522748+dmitrylavrenov@users.noreply.github.com> --- crates/bridge-pot-currency-swap/src/existence_required.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bridge-pot-currency-swap/src/existence_required.rs b/crates/bridge-pot-currency-swap/src/existence_required.rs index d08b49cba..12a954508 100644 --- a/crates/bridge-pot-currency-swap/src/existence_required.rs +++ b/crates/bridge-pot-currency-swap/src/existence_required.rs @@ -15,7 +15,7 @@ pub enum Marker {} pub enum Error { /// Unable to resolve the incoming balance into the corresponding pot. ResolvingIncomingImbalance(ImbalanceFrom), - /// Unable to withdraw the outpoing balance from the corresponding pot. + /// Unable to withdraw the outgoing balance from the corresponding pot. IssuingOutgoingImbalance(DispatchError), }