From 0198a0786a84effccc89970dd950ff75c6b2c201 Mon Sep 17 00:00:00 2001 From: lemunozm Date: Wed, 19 Jun 2024 08:43:07 +0200 Subject: [PATCH 01/17] prepare mock for UTs and simplify some minor things --- Cargo.lock | 9 +- .../src/{try_convert.rs => converter.rs} | 18 +- libs/mocks/src/foreign_investment.rs | 159 ++++++++++++++++++ libs/mocks/src/lib.rs | 5 +- libs/mocks/src/outbound_queue.rs | 37 ++++ libs/traits/src/lib.rs | 10 ++ pallets/liquidity-pools-gateway/src/mock.rs | 12 +- pallets/liquidity-pools/Cargo.toml | 45 +---- pallets/liquidity-pools/src/contract.rs | 63 ------- pallets/liquidity-pools/src/lib.rs | 50 +++--- pallets/liquidity-pools/src/mock.rs | 141 ++++++++++++++++ pallets/liquidity-pools/src/routers.rs | 35 ---- pallets/liquidity-pools/src/tests.rs | 0 runtime/altair/src/lib.rs | 2 - runtime/centrifuge/src/lib.rs | 2 - runtime/common/src/account_conversion.rs | 12 +- runtime/common/src/xcm.rs | 35 ++-- runtime/development/src/lib.rs | 2 - 18 files changed, 412 insertions(+), 225 deletions(-) rename libs/mocks/src/{try_convert.rs => converter.rs} (64%) create mode 100644 libs/mocks/src/foreign_investment.rs create mode 100644 libs/mocks/src/outbound_queue.rs delete mode 100644 pallets/liquidity-pools/src/contract.rs create mode 100644 pallets/liquidity-pools/src/mock.rs delete mode 100644 pallets/liquidity-pools/src/routers.rs create mode 100644 pallets/liquidity-pools/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 18559e03f9..5f272b6ec9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8215,22 +8215,16 @@ dependencies = [ name = "pallet-liquidity-pools" version = "0.0.1" dependencies = [ + "cfg-mocks", "cfg-primitives", "cfg-traits", "cfg-types", "cfg-utils", - "ethabi", - "fp-self-contained", - "frame-benchmarking", "frame-support", "frame-system", "hex", "orml-tokens", "orml-traits", - "pallet-balances", - "pallet-ethereum", - "pallet-timestamp", - "pallet-uniques", "parity-scale-codec", "scale-info", "sp-core", @@ -8238,7 +8232,6 @@ dependencies = [ "sp-runtime", "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.7.2)", "staging-xcm", - "xcm-primitives", ] [[package]] diff --git a/libs/mocks/src/try_convert.rs b/libs/mocks/src/converter.rs similarity index 64% rename from libs/mocks/src/try_convert.rs rename to libs/mocks/src/converter.rs index 99fc901812..4882151717 100644 --- a/libs/mocks/src/try_convert.rs +++ b/libs/mocks/src/converter.rs @@ -3,14 +3,12 @@ pub mod pallet { use cfg_traits::TryConvert; use frame_support::pallet_prelude::*; use mock_builder::{execute_call_instance, register_call_instance}; + use sp_runtime::traits::Convert; #[pallet::config] pub trait Config: frame_system::Config { type From; - type To; - - type Error; } #[pallet::pallet] @@ -20,16 +18,26 @@ pub mod pallet { type CallIds, I: 'static = ()> = StorageMap<_, _, String, mock_builder::CallId>; impl, I: 'static> Pallet { - pub fn mock_try_convert(f: impl Fn(T::From) -> Result + 'static) { + pub fn mock_try_convert(f: impl Fn(T::From) -> Result + 'static) { + register_call_instance!(f); + } + + pub fn mock_convert(f: impl Fn(T::From) -> T::To + 'static) { register_call_instance!(f); } } impl, I: 'static> TryConvert for Pallet { - type Error = T::Error; + type Error = DispatchError; fn try_convert(from: T::From) -> Result { execute_call_instance!(from) } } + + impl, I: 'static> Convert for Pallet { + fn convert(from: T::From) -> T::To { + execute_call_instance!(from) + } + } } diff --git a/libs/mocks/src/foreign_investment.rs b/libs/mocks/src/foreign_investment.rs new file mode 100644 index 0000000000..8dd0471caa --- /dev/null +++ b/libs/mocks/src/foreign_investment.rs @@ -0,0 +1,159 @@ +#[frame_support::pallet(dev_mode)] +pub mod pallet { + use cfg_traits::investments::ForeignInvestment; + use frame_support::pallet_prelude::*; + use mock_builder::{execute_call, register_call}; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Amount; + type TrancheAmount; + type CurrencyId; + type InvestmentId; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::storage] + type CallIds = StorageMap<_, _, String, mock_builder::CallId>; + + impl Pallet { + pub fn mock_increase_foreign_investment( + f: impl Fn(&T::AccountId, T::InvestmentId, T::Amount, T::CurrencyId) -> DispatchResult + + 'static, + ) { + register_call!(move |(a, b, c, d)| f(a, b, c, d)); + } + + pub fn mock_decrease_foreign_investment( + f: impl Fn(&T::AccountId, T::InvestmentId, T::Amount, T::CurrencyId) -> DispatchResult + + 'static, + ) { + register_call!(move |(a, b, c, d)| f(a, b, c, d)); + } + + pub fn mock_increase_foreign_redemption( + f: impl Fn( + &T::AccountId, + T::InvestmentId, + T::TrancheAmount, + T::CurrencyId, + ) -> DispatchResult + + 'static, + ) { + register_call!(move |(a, b, c, d)| f(a, b, c, d)); + } + + pub fn mock_decrease_foreign_redemption( + f: impl Fn( + &T::AccountId, + T::InvestmentId, + T::TrancheAmount, + T::CurrencyId, + ) -> DispatchResult + + 'static, + ) { + register_call!(move |(a, b, c, d)| f(a, b, c, d)); + } + + pub fn mock_collect_foreign_investment( + f: impl Fn(&T::AccountId, T::InvestmentId, T::CurrencyId) -> DispatchResult + 'static, + ) { + register_call!(move |(a, b, c)| f(a, b, c)); + } + + pub fn mock_collect_foreign_redemption( + f: impl Fn(&T::AccountId, T::InvestmentId, T::CurrencyId) -> DispatchResult + 'static, + ) { + register_call!(move |(a, b, c)| f(a, b, c)); + } + + pub fn mock_investment( + f: impl Fn(&T::AccountId, T::InvestmentId) -> Result + 'static, + ) { + register_call!(move |(a, b)| f(a, b)); + } + + pub fn mock_redemption( + f: impl Fn(&T::AccountId, T::InvestmentId) -> Result + + 'static, + ) { + register_call!(move |(a, b)| f(a, b)); + } + } + + impl ForeignInvestment for Pallet { + type Amount = T::Amount; + type CurrencyId = T::CurrencyId; + type Error = DispatchError; + type InvestmentId = T::InvestmentId; + type TrancheAmount = T::TrancheAmount; + + fn increase_foreign_investment( + a: &T::AccountId, + b: Self::InvestmentId, + c: Self::Amount, + d: Self::CurrencyId, + ) -> DispatchResult { + execute_call!((a, b, c, d)) + } + + fn decrease_foreign_investment( + a: &T::AccountId, + b: Self::InvestmentId, + c: Self::Amount, + d: Self::CurrencyId, + ) -> DispatchResult { + execute_call!((a, b, c, d)) + } + + fn increase_foreign_redemption( + a: &T::AccountId, + b: Self::InvestmentId, + c: Self::TrancheAmount, + d: Self::CurrencyId, + ) -> DispatchResult { + execute_call!((a, b, c, d)) + } + + fn decrease_foreign_redemption( + a: &T::AccountId, + b: Self::InvestmentId, + c: Self::TrancheAmount, + d: Self::CurrencyId, + ) -> DispatchResult { + execute_call!((a, b, c, d)) + } + + fn collect_foreign_investment( + a: &T::AccountId, + b: Self::InvestmentId, + c: Self::CurrencyId, + ) -> DispatchResult { + execute_call!((a, b, c)) + } + + fn collect_foreign_redemption( + a: &T::AccountId, + b: Self::InvestmentId, + c: Self::CurrencyId, + ) -> DispatchResult { + execute_call!((a, b, c)) + } + + fn investment( + a: &T::AccountId, + b: Self::InvestmentId, + ) -> Result { + execute_call!((a, b)) + } + + fn redemption( + a: &T::AccountId, + b: Self::InvestmentId, + ) -> Result { + execute_call!((a, b)) + } + } +} diff --git a/libs/mocks/src/lib.rs b/libs/mocks/src/lib.rs index eec8873049..de52496021 100644 --- a/libs/mocks/src/lib.rs +++ b/libs/mocks/src/lib.rs @@ -1,11 +1,14 @@ pub mod asset_registry; pub mod change_guard; +pub mod converter; pub mod currency_conversion; pub mod data; pub mod fees; +pub mod foreign_investment; pub mod investment; pub mod liquidity_pools; pub mod liquidity_pools_gateway_routers; +pub mod outbound_queue; pub mod pay_fee; pub mod permissions; pub mod pools; @@ -14,7 +17,6 @@ pub mod rewards; pub mod status_notification; pub mod time; pub mod token_swaps; -pub mod try_convert; pub mod value_provider; pub mod write_off_policy; @@ -33,7 +35,6 @@ pub use rewards::pallet as pallet_mock_rewards; pub use status_notification::pallet as pallet_mock_status_notification; pub use time::pallet as pallet_mock_time; pub use token_swaps::pallet as pallet_mock_token_swaps; -pub use try_convert::pallet as pallet_mock_try_convert; pub use value_provider::pallet as pallet_mock_value_provider; pub use write_off_policy::pallet as pallet_mock_write_off_policy; diff --git a/libs/mocks/src/outbound_queue.rs b/libs/mocks/src/outbound_queue.rs new file mode 100644 index 0000000000..986f4acd55 --- /dev/null +++ b/libs/mocks/src/outbound_queue.rs @@ -0,0 +1,37 @@ +#[frame_support::pallet(dev_mode)] +pub mod pallet { + use cfg_traits::liquidity_pools::OutboundQueue; + use frame_support::pallet_prelude::*; + use mock_builder::{execute_call, register_call}; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Sender; + type Destination; + type Message; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::storage] + type CallIds = StorageMap<_, _, String, mock_builder::CallId>; + + impl Pallet { + pub fn mock_submit( + f: impl Fn(T::Sender, T::Destination, T::Message) -> DispatchResult + 'static, + ) { + register_call!(move |(a, b, c)| f(a, b, c)); + } + } + + impl OutboundQueue for Pallet { + type Destination = T::Destination; + type Message = T::Message; + type Sender = T::Sender; + + fn submit(a: Self::Sender, b: Self::Destination, c: Self::Message) -> DispatchResult { + execute_call!((a, b, c)) + } + } +} diff --git a/libs/traits/src/lib.rs b/libs/traits/src/lib.rs index ec97102eb5..460c54456a 100644 --- a/libs/traits/src/lib.rs +++ b/libs/traits/src/lib.rs @@ -309,6 +309,16 @@ impl PreConditions for Always { } } +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +pub struct AlwaysOk; +impl PreConditions for AlwaysOk { + type Result = DispatchResult; + + fn check(_t: T) -> DispatchResult { + Ok(()) + } +} + #[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] pub struct Never; impl PreConditions for Never { diff --git a/pallets/liquidity-pools-gateway/src/mock.rs b/pallets/liquidity-pools-gateway/src/mock.rs index b99959e456..4f0f2c78de 100644 --- a/pallets/liquidity-pools-gateway/src/mock.rs +++ b/pallets/liquidity-pools-gateway/src/mock.rs @@ -1,13 +1,10 @@ -use cfg_mocks::{ - pallet_mock_liquidity_pools, pallet_mock_routers, pallet_mock_try_convert, MessageMock, - RouterMock, -}; +use cfg_mocks::{pallet_mock_liquidity_pools, pallet_mock_routers, MessageMock, RouterMock}; use cfg_primitives::OutboundMessageNonce; use cfg_types::domain_address::DomainAddress; use frame_support::derive_impl; use frame_system::EnsureRoot; use sp_core::{crypto::AccountId32, ConstU128, H256}; -use sp_runtime::{traits::IdentityLookup, BuildStorage, DispatchError}; +use sp_runtime::{traits::IdentityLookup, BuildStorage}; use crate::{pallet as pallet_liquidity_pools_gateway, EnsureLocal}; @@ -26,7 +23,7 @@ frame_support::construct_runtime!( Balances: pallet_balances, MockLiquidityPools: pallet_mock_liquidity_pools, MockRouters: pallet_mock_routers, - MockOriginRecovery: pallet_mock_try_convert, + MockOriginRecovery: cfg_mocks::converter::pallet, LiquidityPoolsGateway: pallet_liquidity_pools_gateway, } ); @@ -55,8 +52,7 @@ impl pallet_mock_liquidity_pools::Config for Runtime { impl pallet_mock_routers::Config for Runtime {} -impl pallet_mock_try_convert::Config for Runtime { - type Error = DispatchError; +impl cfg_mocks::converter::pallet::Config for Runtime { type From = (Vec, Vec); type To = DomainAddress; } diff --git a/pallets/liquidity-pools/Cargo.toml b/pallets/liquidity-pools/Cargo.toml index 1bbbad918b..a0191f014b 100644 --- a/pallets/liquidity-pools/Cargo.toml +++ b/pallets/liquidity-pools/Cargo.toml @@ -13,7 +13,6 @@ documentation.workspace = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -ethabi = { workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } hex = { workspace = true } @@ -22,15 +21,8 @@ parity-scale-codec = { workspace = true } scale-info = { workspace = true } sp-runtime = { workspace = true } sp-std = { workspace = true } - -# Substrate crates sp-core = { workspace = true } - -# Optional dependencies for benchmarking -frame-benchmarking = { workspace = true, optional = true } -orml-tokens = { workspace = true, optional = true } -pallet-balances = { workspace = true, optional = true } -pallet-uniques = { workspace = true, optional = true } +staging-xcm = { workspace = true } # Our custom pallets cfg-primitives = { workspace = true } @@ -38,27 +30,16 @@ cfg-traits = { workspace = true } cfg-types = { workspace = true } cfg-utils = { workspace = true } -# Polkadot -staging-xcm = { workspace = true } - -fp-self-contained = { workspace = true } -pallet-ethereum = { workspace = true } -xcm-primitives = { workspace = true } - [dev-dependencies] -hex = { workspace = true, default-features = true } - -# Substrate crates & pallets -pallet-balances = { workspace = true } -pallet-timestamp = { workspace = true } -pallet-uniques = { workspace = true } -sp-core = { workspace = true } +orml-tokens = { workspace = true, default-features = true } sp-io = { workspace = true } +cfg-mocks = { workspace = true, default-features = true } [features] default = ["std"] std = [ "parity-scale-codec/std", + "cfg-primitives/std", "cfg-types/std", "cfg-traits/std", "cfg-utils/std", @@ -66,22 +47,11 @@ std = [ "frame-system/std", "sp-std/std", "sp-runtime/std", - "orml-tokens/std", "orml-traits/std", - "pallet-balances/std", "staging-xcm/std", - "pallet-ethereum/std", - "xcm-primitives/std", - "ethabi/std", - "pallet-uniques/std", - "cfg-primitives/std", - "frame-benchmarking/std", "scale-info/std", - "fp-self-contained/std", ] runtime-benchmarks = [ - "frame-benchmarking/runtime-benchmarks", - "pallet-balances/runtime-benchmarks", "orml-tokens/runtime-benchmarks", "cfg-primitives/runtime-benchmarks", "cfg-traits/runtime-benchmarks", @@ -89,9 +59,8 @@ runtime-benchmarks = [ "cfg-utils/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", - "pallet-ethereum/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "xcm-primitives/runtime-benchmarks", + "cfg-mocks/runtime-benchmarks", ] try-runtime = [ "cfg-primitives/try-runtime", @@ -101,8 +70,6 @@ try-runtime = [ "cfg-types/try-runtime", "cfg-utils/try-runtime", "frame-system/try-runtime", - "pallet-ethereum/try-runtime", - "pallet-balances/try-runtime", - "fp-self-contained/try-runtime", "sp-runtime/try-runtime", + "cfg-mocks/try-runtime", ] diff --git a/pallets/liquidity-pools/src/contract.rs b/pallets/liquidity-pools/src/contract.rs deleted file mode 100644 index 852b6e1fc8..0000000000 --- a/pallets/liquidity-pools/src/contract.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2021 Centrifuge Foundation (centrifuge.io). -// This file is part of Centrifuge chain project. - -// Centrifuge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version (see http://www.gnu.org/licenses). - -// Centrifuge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -use ethabi::{Bytes, Contract}; -use sp_std::{vec, vec::Vec}; - -/// The solidity LiquidityPools' XCMRouter handle function name. -static HANDLE_FUNCTION: &str = "handle"; - -/// Return the encoded contract call, i.e, -/// LiquidityPoolsXcmRouter::handle(encoded_msg). -pub fn encoded_contract_call(encoded_msg: Vec) -> Bytes { - let contract = xcm_router_contract(); - let encoded_contract_call = contract - .function(HANDLE_FUNCTION) - .expect("Known at compilation time") - .encode_input(&[ethabi::Token::Bytes(encoded_msg)]) - .expect("Known at compilation time"); - - encoded_contract_call -} - -/// The LiquidityPoolsXcmRouter Abi as in ethabi::Contract. -/// Note: We only concern ourselves with the `handle` function of the contract -/// since that's all we need to build the calls for remote EVM execution. -pub fn xcm_router_contract() -> Contract { - use sp_std::collections::btree_map::BTreeMap; - - let mut functions = BTreeMap::new(); - #[allow(deprecated)] - functions.insert( - "handle".into(), - vec![ethabi::Function { - name: HANDLE_FUNCTION.into(), - inputs: vec![ethabi::Param { - name: "message".into(), - kind: ethabi::ParamType::Bytes, - internal_type: None, - }], - outputs: vec![], - constant: Some(false), - state_mutability: Default::default(), - }], - ); - - ethabi::Contract { - constructor: None, - functions, - events: Default::default(), - errors: Default::default(), - receive: false, - fallback: false, - } -} diff --git a/pallets/liquidity-pools/src/lib.rs b/pallets/liquidity-pools/src/lib.rs index 2d1a0dea54..70d3c1abbe 100644 --- a/pallets/liquidity-pools/src/lib.rs +++ b/pallets/liquidity-pools/src/lib.rs @@ -41,7 +41,10 @@ #![cfg_attr(not(feature = "std"), no_std)] use core::convert::TryFrom; -use cfg_traits::liquidity_pools::{InboundQueue, OutboundQueue}; +use cfg_traits::{ + liquidity_pools::{InboundQueue, OutboundQueue}, + PreConditions, +}; use cfg_types::{ domain_address::{Domain, DomainAddress}, tokens::GeneralCurrencyIndex, @@ -73,17 +76,14 @@ use staging_xcm::{ pub mod defensive_weights; mod message; -pub use message::*; - -mod routers; -pub use routers::*; - -mod contract; -pub use contract::*; +pub use message::Message; pub mod hooks; mod inbound; +#[cfg(test)] +mod mock; + /// The Parachains that Centrifuge Liquidity Pools support. #[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Debug))] @@ -113,8 +113,7 @@ pub type GeneralCurrencyIndexOf = pub mod pallet { use cfg_traits::{ investments::{ForeignInvestment, TrancheCurrency}, - CurrencyInspect, Permissions, PoolInspect, PreConditions, Seconds, TimeAsSecs, - TrancheTokenPrice, + CurrencyInspect, Permissions, PoolInspect, Seconds, TimeAsSecs, TrancheTokenPrice, }; use cfg_types::{ permissions::{PermissionScope, PoolRole, Role}, @@ -172,10 +171,6 @@ pub mod pallet { + FixedPointNumber + TypeInfo; - /// The origin allowed to make admin-like changes, such calling - /// `set_domain_router`. - type AdminOrigin: EnsureOrigin; - /// The source of truth for pool inspection operations such as its /// existence, the corresponding tranche token or the investment /// currency. @@ -256,10 +251,6 @@ pub mod pallet { /// The converter from a DomainAddress to a Substrate AccountId. type DomainAddressToAccountId: Convert; - /// The converter from a Domain and 32 byte array to Substrate - /// AccountId. - type DomainAccountToAccountId: Convert<(Domain, [u8; 32]), Self::AccountId>; - /// The converter from a Domain and a 32 byte array to DomainAddress. type DomainAccountToDomainAddress: Convert<(Domain, [u8; 32]), DomainAddress>; @@ -274,13 +265,13 @@ pub mod pallet { #[pallet::constant] type GeneralCurrencyPrefix: Get<[u8; 12]>; - #[pallet::constant] /// The type for paying the transaction fees for the dispatch of /// `Executed*` and `ScheduleUpgrade` messages. /// /// NOTE: We need to make sure to collect the appropriate amount /// beforehand as part of receiving the corresponding investment /// message. + #[pallet::constant] type TreasuryAccount: Get; type PreTransferFilter: PreConditions< @@ -954,6 +945,11 @@ pub mod pallet { Ok((currency, chain_id)) } + + fn domain_account_to_account_id(domain_account: (Domain, [u8; 32])) -> T::AccountId { + let domain_address = T::DomainAccountToDomainAddress::convert(domain_account); + T::DomainAddressToAccountId::convert(domain_address) + } } impl InboundQueue for Pallet @@ -1000,7 +996,7 @@ pub mod pallet { } => Self::handle_increase_invest_order( pool_id, tranche_id, - T::DomainAccountToAccountId::convert((sender.domain(), investor)), + Self::domain_account_to_account_id((sender.domain(), investor)), currency.into(), amount, ), @@ -1013,7 +1009,7 @@ pub mod pallet { } => Self::handle_decrease_invest_order( pool_id, tranche_id, - T::DomainAccountToAccountId::convert((sender.domain(), investor)), + Self::domain_account_to_account_id((sender.domain(), investor)), currency.into(), amount, ), @@ -1026,7 +1022,7 @@ pub mod pallet { } => Self::handle_increase_redeem_order( pool_id, tranche_id, - T::DomainAccountToAccountId::convert((sender.domain(), investor)), + Self::domain_account_to_account_id((sender.domain(), investor)), amount, currency.into(), sender, @@ -1040,7 +1036,7 @@ pub mod pallet { } => Self::handle_decrease_redeem_order( pool_id, tranche_id, - T::DomainAccountToAccountId::convert((sender.domain(), investor)), + Self::domain_account_to_account_id((sender.domain(), investor)), amount, currency.into(), sender, @@ -1053,7 +1049,7 @@ pub mod pallet { } => Self::handle_collect_investment( pool_id, tranche_id, - T::DomainAccountToAccountId::convert((sender.domain(), investor)), + Self::domain_account_to_account_id((sender.domain(), investor)), currency.into(), ), Message::CollectRedeem { @@ -1064,7 +1060,7 @@ pub mod pallet { } => Self::handle_collect_redemption( pool_id, tranche_id, - T::DomainAccountToAccountId::convert((sender.domain(), investor)), + Self::domain_account_to_account_id((sender.domain(), investor)), currency.into(), ), Message::CancelInvestOrder { @@ -1075,7 +1071,7 @@ pub mod pallet { } => Self::handle_cancel_invest_order( pool_id, tranche_id, - T::DomainAccountToAccountId::convert((sender.domain(), investor)), + Self::domain_account_to_account_id((sender.domain(), investor)), currency.into(), ), Message::CancelRedeemOrder { @@ -1086,7 +1082,7 @@ pub mod pallet { } => Self::handle_cancel_redeem_order( pool_id, tranche_id, - T::DomainAccountToAccountId::convert((sender.domain(), investor)), + Self::domain_account_to_account_id((sender.domain(), investor)), currency.into(), sender, ), diff --git a/pallets/liquidity-pools/src/mock.rs b/pallets/liquidity-pools/src/mock.rs new file mode 100644 index 0000000000..9270135482 --- /dev/null +++ b/pallets/liquidity-pools/src/mock.rs @@ -0,0 +1,141 @@ +use cfg_primitives::{PoolId, TrancheId}; +use cfg_traits::{AlwaysOk, Millis}; +use cfg_types::{ + domain_address::{Domain, DomainAddress}, + permissions::PermissionScope, + tokens::{CurrencyId, CustomMetadata, TrancheCurrency}, +}; +use frame_support::derive_impl; +use orml_traits::parameter_type_with_key; +use sp_runtime::{ + traits::{ConstU32, IdentityLookup}, + AccountId32, FixedU64, +}; + +use crate::pallet as pallet_liquidity_pools; + +pub type Balance = u128; +pub type AccountId = AccountId32; +pub type Ratio = FixedU64; +pub type Message = crate::Message; + +frame_support::construct_runtime!( + pub enum Runtime { + System: frame_system, + Time: cfg_mocks::time::pallet, + Permissions: cfg_mocks::permissions::pallet, + Pools: cfg_mocks::pools::pallet, + AssetRegistry: cfg_mocks::asset_registry::pallet, + ForeignInvestment: cfg_mocks::foreign_investment::pallet, + Gateway: cfg_mocks::outbound_queue::pallet, + DomainAddressToAccountId: cfg_mocks::converter::pallet::, + DomainAccountToDomainAddress: cfg_mocks::converter::pallet::, + Tokens: orml_tokens, + LiquidityPools: pallet_liquidity_pools, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Runtime { + type AccountId = AccountId; + type Block = frame_system::mocking::MockBlock; + type Lookup = IdentityLookup; +} + +impl cfg_mocks::time::pallet::Config for Runtime { + type Moment = Millis; +} + +impl cfg_mocks::permissions::pallet::Config for Runtime { + type Scope = PermissionScope; +} + +impl cfg_mocks::pools::pallet::Config for Runtime { + type Balance = Balance; + type BalanceRatio = Ratio; + type CurrencyId = CurrencyId; + type PoolId = PoolId; + type TrancheCurrency = TrancheCurrency; + type TrancheId = TrancheId; +} + +impl cfg_mocks::asset_registry::pallet::Config for Runtime { + type AssetId = CurrencyId; + type Balance = Balance; + type CustomMetadata = CustomMetadata; + type StringLimit = ConstU32<64>; +} + +impl cfg_mocks::foreign_investment::pallet::Config for Runtime { + type Amount = Balance; + type CurrencyId = CurrencyId; + type InvestmentId = TrancheCurrency; + type TrancheAmount = Balance; +} + +impl cfg_mocks::outbound_queue::pallet::Config for Runtime { + type Destination = Domain; + type Message = Message; + type Sender = AccountId; +} + +type I1 = cfg_mocks::converter::pallet::Instance1; +impl cfg_mocks::converter::pallet::Config for Runtime { + type From = DomainAddress; + type To = AccountId; +} + +type I3 = cfg_mocks::converter::pallet::Instance3; +impl cfg_mocks::converter::pallet::Config for Runtime { + type From = (Domain, [u8; 32]); + type To = DomainAddress; +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + Default::default() + }; +} + +impl orml_tokens::Config for Runtime { + type Amount = i64; + type Balance = Balance; + type CurrencyHooks = (); + type CurrencyId = CurrencyId; + type DustRemovalWhitelist = frame_support::traits::Nothing; + type ExistentialDeposits = ExistentialDeposits; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); +} + +frame_support::parameter_types! { + pub CurrencyPrefix: [u8; 12] = [1; 12]; + pub TreasuryAccount: AccountId = [2; 32].into(); +} + +impl pallet_liquidity_pools::Config for Runtime { + type AssetRegistry = AssetRegistry; + type Balance = Balance; + type BalanceRatio = Ratio; + type CurrencyId = CurrencyId; + type DomainAccountToDomainAddress = DomainAccountToDomainAddress; + type DomainAddressToAccountId = DomainAddressToAccountId; + type ForeignInvestment = ForeignInvestment; + type GeneralCurrencyPrefix = CurrencyPrefix; + type OutboundQueue = Gateway; + type Permission = Permissions; + type PoolId = PoolId; + type PoolInspect = Pools; + type PreTransferFilter = AlwaysOk; + type RuntimeEvent = RuntimeEvent; + type Time = Time; + type Tokens = Tokens; + type TrancheCurrency = TrancheCurrency; + type TrancheId = TrancheId; + type TrancheTokenPrice = Pools; + type TreasuryAccount = TreasuryAccount; + type WeightInfo = (); +} diff --git a/pallets/liquidity-pools/src/routers.rs b/pallets/liquidity-pools/src/routers.rs deleted file mode 100644 index 15d16e4dec..0000000000 --- a/pallets/liquidity-pools/src/routers.rs +++ /dev/null @@ -1,35 +0,0 @@ -use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -use scale_info::TypeInfo; -use sp_core::H160; -use sp_runtime::{traits::ConstU32, BoundedVec}; -use sp_std::boxed::Box; -use staging_xcm::VersionedLocation; - -#[allow(clippy::derive_partial_eq_without_eq)] // XcmDomain does not impl Eq -#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen)] -#[cfg_attr(feature = "std", derive(Debug))] -pub enum Router { - // An XCM-based router - Xcm(XcmDomain), -} - -/// XcmDomain gathers all the required fields to build and send remote -/// calls to a specific XCM-based Domain. -#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -#[cfg_attr(feature = "std", derive(Debug))] -pub struct XcmDomain { - /// the xcm multilocation of the domain - pub location: Box, - /// The ethereum_xcm::Call::transact call index on a given domain. - /// It should contain the pallet index + the `transact` call index, to which - /// we will append the eth_tx param. You can obtain this value by building - /// an ethereum_xcm::transact call with Polkadot JS on the target chain. - pub ethereum_xcm_transact_call_index: - BoundedVec>, - /// The LiquidityPoolsXcmRouter contract address on a given domain - pub contract_address: H160, - /// The currency in which execution fees will be paid on - pub fee_currency: CurrencyId, - /// The max gas_limit we want to propose for a remote evm execution - pub max_gas_limit: u64, -} diff --git a/pallets/liquidity-pools/src/tests.rs b/pallets/liquidity-pools/src/tests.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/runtime/altair/src/lib.rs b/runtime/altair/src/lib.rs index 64983606ee..47e5215723 100644 --- a/runtime/altair/src/lib.rs +++ b/runtime/altair/src/lib.rs @@ -1779,12 +1779,10 @@ parameter_types! { } impl pallet_liquidity_pools::Config for Runtime { - type AdminOrigin = EnsureRoot; type AssetRegistry = OrmlAssetRegistry; type Balance = Balance; type BalanceRatio = Ratio; type CurrencyId = CurrencyId; - type DomainAccountToAccountId = AccountConverter; type DomainAccountToDomainAddress = AccountConverter; type DomainAddressToAccountId = AccountConverter; type ForeignInvestment = ForeignInvestments; diff --git a/runtime/centrifuge/src/lib.rs b/runtime/centrifuge/src/lib.rs index 0d9855ff58..e4e1da995d 100644 --- a/runtime/centrifuge/src/lib.rs +++ b/runtime/centrifuge/src/lib.rs @@ -1877,12 +1877,10 @@ parameter_types! { } impl pallet_liquidity_pools::Config for Runtime { - type AdminOrigin = EnsureRootOr; type AssetRegistry = OrmlAssetRegistry; type Balance = Balance; type BalanceRatio = Ratio; type CurrencyId = CurrencyId; - type DomainAccountToAccountId = AccountConverter; type DomainAccountToDomainAddress = AccountConverter; type DomainAddressToAccountId = AccountConverter; type ForeignInvestment = ForeignInvestments; diff --git a/runtime/common/src/account_conversion.rs b/runtime/common/src/account_conversion.rs index 9e896c9db5..fe58534116 100644 --- a/runtime/common/src/account_conversion.rs +++ b/runtime/common/src/account_conversion.rs @@ -90,16 +90,8 @@ impl Convert<(Domain, [u8; 32]), DomainAddress> for AccountConverter { } impl Convert<(Domain, [u8; 32]), AccountId32> for AccountConverter { - fn convert((domain, account): (Domain, [u8; 32])) -> AccountId32 { - match domain { - Domain::Centrifuge => AccountId32::new(account), - // EVM AccountId20 addresses are right-padded to 32 bytes - Domain::EVM(chain_id) => { - let mut bytes20 = [0; 20]; - bytes20.copy_from_slice(&account[..20]); - Self::convert_evm_address(chain_id, bytes20) - } - } + fn convert(pair: (Domain, [u8; 32])) -> AccountId32 { + Self::convert(>::convert(pair)) } } diff --git a/runtime/common/src/xcm.rs b/runtime/common/src/xcm.rs index dbba874d87..aa82c339de 100644 --- a/runtime/common/src/xcm.rs +++ b/runtime/common/src/xcm.rs @@ -272,10 +272,7 @@ pub type LocationToAccountId = ( #[cfg(test)] mod test { - use cfg_mocks::{ - pallet_mock_liquidity_pools, pallet_mock_routers, pallet_mock_try_convert, MessageMock, - RouterMock, - }; + use cfg_mocks::{pallet_mock_liquidity_pools, pallet_mock_routers, MessageMock, RouterMock}; use cfg_primitives::OutboundMessageNonce; use frame_support::{assert_ok, derive_impl, traits::EnsureOrigin}; use frame_system::EnsureRoot; @@ -288,18 +285,14 @@ mod test { type AccountId = u64; - pub fn new_test_ext() -> sp_io::TestExternalities { - System::externalities() - } - // For testing the pallet, we construct a mock runtime. frame_support::construct_runtime!( pub enum Runtime { System: frame_system, Gateway: pallet_liquidity_pools_gateway, MockLP: pallet_mock_liquidity_pools, - MockParaAsEvmChain: pallet_mock_try_convert::, - MockOriginRecovery: pallet_mock_try_convert::, + MockParaAsEvmChain: cfg_mocks::converter::pallet::, + MockOriginRecovery: cfg_mocks::converter::pallet::, } ); @@ -308,14 +301,12 @@ mod test { type Block = frame_system::mocking::MockBlock; } - impl pallet_mock_try_convert::Config for Runtime { - type Error = (); + impl cfg_mocks::converter::pallet::Config for Runtime { type From = ParaId; type To = EVMChainId; } - impl pallet_mock_try_convert::Config for Runtime { - type Error = DispatchError; + impl cfg_mocks::converter::pallet::Config for Runtime { type From = (Vec, Vec); type To = DomainAddress; } @@ -348,7 +339,7 @@ mod test { #[test] fn lp_instance_relayer_converts_correctly() { - new_test_ext().execute_with(|| { + System::externalities().execute_with(|| { let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); assert_ok!(Gateway::add_relayer( @@ -387,7 +378,7 @@ mod test { #[test] fn lp_instance_relayer_fails_with_wrong_location() { - new_test_ext().execute_with(|| { + System::externalities().execute_with(|| { let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); assert_ok!(Gateway::add_relayer( @@ -415,7 +406,7 @@ mod test { #[test] fn lp_instance_relayer_fails_if_relayer_not_set() { - new_test_ext().execute_with(|| { + System::externalities().execute_with(|| { MockParaAsEvmChain::mock_try_convert(|from| { assert_eq!(from, RELAYER_PARA_ID); Ok(RELAYER_EVM_ID) @@ -445,7 +436,7 @@ mod test { #[test] fn lp_instance_relayer_fails_if_para_to_evm_fails() { - new_test_ext().execute_with(|| { + System::externalities().execute_with(|| { let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); assert_ok!(Gateway::add_relayer( @@ -455,7 +446,7 @@ mod test { MockParaAsEvmChain::mock_try_convert(|from| { assert_eq!(from, RELAYER_PARA_ID); - Err(()) + Err(DispatchError::Other("")) }); let location = Location::new( @@ -482,7 +473,7 @@ mod test { #[test] fn lp_instance_relayer_fails_if_wrong_para() { - new_test_ext().execute_with(|| { + System::externalities().execute_with(|| { let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); assert_ok!(Gateway::add_relayer( @@ -492,7 +483,7 @@ mod test { MockParaAsEvmChain::mock_try_convert(|from| { assert_eq!(from, 1); - Err(()) + Err(DispatchError::Other("")) }); let location = Location::new( @@ -519,7 +510,7 @@ mod test { #[test] fn lp_instance_relayer_fails_if_wrong_address() { - new_test_ext().execute_with(|| { + System::externalities().execute_with(|| { let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); assert_ok!(Gateway::add_relayer( diff --git a/runtime/development/src/lib.rs b/runtime/development/src/lib.rs index 00bddcbde6..0e46c15183 100644 --- a/runtime/development/src/lib.rs +++ b/runtime/development/src/lib.rs @@ -1882,12 +1882,10 @@ parameter_types! { } impl pallet_liquidity_pools::Config for Runtime { - type AdminOrigin = EnsureRoot; type AssetRegistry = OrmlAssetRegistry; type Balance = Balance; type BalanceRatio = Ratio; type CurrencyId = CurrencyId; - type DomainAccountToAccountId = AccountConverter; type DomainAccountToDomainAddress = AccountConverter; type DomainAddressToAccountId = AccountConverter; type ForeignInvestment = ForeignInvestments; From 03f6fc75333b23fafff0f14b8a2d5d1a70ddcda6 Mon Sep 17 00:00:00 2001 From: lemunozm Date: Wed, 19 Jun 2024 09:22:24 +0200 Subject: [PATCH 02/17] normal function instead of Convert trait --- runtime/common/src/account_conversion.rs | 13 ++- .../src/generic/cases/liquidity_pools.rs | 98 +++++++++++-------- 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/runtime/common/src/account_conversion.rs b/runtime/common/src/account_conversion.rs index fe58534116..e1524383e9 100644 --- a/runtime/common/src/account_conversion.rs +++ b/runtime/common/src/account_conversion.rs @@ -13,7 +13,7 @@ use cfg_primitives::AccountId; use cfg_types::domain_address::{Domain, DomainAddress}; use pallet_evm::AddressMapping; -use sp_core::{crypto::AccountId32, Get, H160}; +use sp_core::{Get, H160}; use sp_runtime::traits::Convert; use staging_xcm::v4::{Junction::AccountKey20, Location, NetworkId::Ethereum}; use staging_xcm_executor::traits::ConvertLocation; @@ -65,6 +65,11 @@ impl AccountConverter { let chain_id = pallet_evm_chain_id::Pallet::::get(); Self::convert_evm_address(chain_id, address.0) } + + pub fn domain_account_to_account(domain: Domain, account_id: AccountId) -> AccountId { + let domain_address = Self::convert((domain, account_id.into())); + Self::convert(domain_address) + } } impl Convert for AccountConverter { @@ -89,12 +94,6 @@ impl Convert<(Domain, [u8; 32]), DomainAddress> for AccountConverter { } } -impl Convert<(Domain, [u8; 32]), AccountId32> for AccountConverter { - fn convert(pair: (Domain, [u8; 32])) -> AccountId32 { - Self::convert(>::convert(pair)) - } -} - // A type that use AccountConverter to carry along with it the Runtime type and // offer an `AddressMapping` implementation. // Required by `pallet_evm` diff --git a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs index 19985385f8..da62f5d4fc 100644 --- a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs +++ b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs @@ -1670,8 +1670,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let amount = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; @@ -1720,8 +1720,8 @@ mod foreign_investments { let invest_amount: u128 = 10 * decimals(12); let decrease_amount = invest_amount / 3; let final_amount = invest_amount - decrease_amount; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id: CurrencyId = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; @@ -1811,8 +1811,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let invest_amount = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; @@ -1911,8 +1911,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let amount = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let sending_domain_locator = @@ -2058,8 +2058,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let invest_amount = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let sending_domain_locator = @@ -2290,8 +2290,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let amount = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; @@ -2345,8 +2345,8 @@ mod foreign_investments { let redeem_amount = 10 * decimals(12); let decrease_amount = redeem_amount / 3; let final_amount = redeem_amount - decrease_amount; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let sending_domain_locator = @@ -2463,8 +2463,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let redeem_amount = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let sending_domain_locator = @@ -2561,8 +2561,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let amount = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let pool_account = pallet_pool_system::pool_types::PoolLocator { pool_id } @@ -2711,8 +2711,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let redeem_amount = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let pool_account = pallet_pool_system::pool_types::PoolLocator { pool_id } @@ -2922,8 +2922,10 @@ mod foreign_investments { let pool_id = POOL_ID; let invest_amount: u128 = 10 * decimals(12); let decrease_amount = invest_amount + 1; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = AccountConverter::domain_account_to_account( + DOMAIN_MOONBEAM, + Keyring::Bob.id(), + ); let currency_id: CurrencyId = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; create_currency_pool::(pool_id, currency_id, currency_decimals.into()); @@ -2968,8 +2970,10 @@ mod foreign_investments { let pool_id = POOL_ID; let redeem_amount: u128 = 10 * decimals(12); let decrease_amount = redeem_amount + 1; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = AccountConverter::domain_account_to_account( + DOMAIN_MOONBEAM, + Keyring::Bob.id(), + ); let currency_id: CurrencyId = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; create_currency_pool::(pool_id, currency_id, currency_decimals.into()); @@ -3016,8 +3020,10 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let amount: u128 = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = AccountConverter::domain_account_to_account( + DOMAIN_MOONBEAM, + Keyring::Bob.id(), + ); let currency_id: CurrencyId = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; create_currency_pool::(pool_id, currency_id, currency_decimals.into()); @@ -3095,8 +3101,10 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; let amount: u128 = 10 * decimals(12); - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = AccountConverter::domain_account_to_account( + DOMAIN_MOONBEAM, + Keyring::Bob.id(), + ); let currency_id: CurrencyId = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; create_currency_pool::(pool_id, currency_id, currency_decimals.into()); @@ -3184,8 +3192,10 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = AccountConverter::domain_account_to_account( + DOMAIN_MOONBEAM, + Keyring::Bob.id(), + ); let pool_currency = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let foreign_currency: CurrencyId = USDT_CURRENCY_ID; @@ -3260,8 +3270,10 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = AccountConverter::domain_account_to_account( + DOMAIN_MOONBEAM, + Keyring::Bob.id(), + ); let pool_currency = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let foreign_currency: CurrencyId = USDT_CURRENCY_ID; @@ -3340,8 +3352,10 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = AccountConverter::domain_account_to_account( + DOMAIN_MOONBEAM, + Keyring::Bob.id(), + ); let pool_currency = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let foreign_currency: CurrencyId = USDT_CURRENCY_ID; @@ -3413,8 +3427,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let pool_currency: CurrencyId = AUSD_CURRENCY_ID; let foreign_currency: CurrencyId = USDT_CURRENCY_ID; let pool_currency_decimals = currency_decimals::AUSD; @@ -3527,8 +3541,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let pool_currency: CurrencyId = AUSD_CURRENCY_ID; let foreign_currency: CurrencyId = USDT_CURRENCY_ID; let pool_currency_decimals = currency_decimals::AUSD; @@ -3666,8 +3680,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let trader: AccountId = Keyring::Alice.into(); let pool_currency: CurrencyId = AUSD_CURRENCY_ID; let foreign_currency: CurrencyId = USDT_CURRENCY_ID; @@ -3781,8 +3795,8 @@ mod foreign_investments { env.parachain_state_mut(|| { let pool_id = POOL_ID; - let investor: AccountId = - AccountConverter::convert((DOMAIN_MOONBEAM, Keyring::Bob.into())); + let investor = + AccountConverter::domain_account_to_account(DOMAIN_MOONBEAM, Keyring::Bob.id()); let pool_currency: CurrencyId = AUSD_CURRENCY_ID; let foreign_currency: CurrencyId = USDT_CURRENCY_ID; let pool_currency_decimals = currency_decimals::AUSD; From c6350042278a3507b17ccf85074ae22da7509345 Mon Sep 17 00:00:00 2001 From: lemunozm Date: Wed, 19 Jun 2024 09:36:29 +0200 Subject: [PATCH 03/17] rename into_account_id() to evm_to_account() --- runtime/common/src/account_conversion.rs | 4 ++-- runtime/common/src/gateway.rs | 2 +- runtime/integration-tests/src/utils/accounts.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/common/src/account_conversion.rs b/runtime/common/src/account_conversion.rs index e1524383e9..3603cd2e60 100644 --- a/runtime/common/src/account_conversion.rs +++ b/runtime/common/src/account_conversion.rs @@ -61,7 +61,7 @@ impl AccountConverter { } } - pub fn into_account_id(address: H160) -> AccountId { + pub fn evm_to_account(address: H160) -> AccountId { let chain_id = pallet_evm_chain_id::Pallet::::get(); Self::convert_evm_address(chain_id, address.0) } @@ -101,7 +101,7 @@ pub struct RuntimeAccountConverter(sp_std::marker::PhantomData); impl AddressMapping for RuntimeAccountConverter { fn into_account_id(address: H160) -> AccountId { - AccountConverter::into_account_id::(address) + AccountConverter::evm_to_account::(address) } } diff --git a/runtime/common/src/gateway.rs b/runtime/common/src/gateway.rs index 4129eec96c..a753a66313 100644 --- a/runtime/common/src/gateway.rs +++ b/runtime/common/src/gateway.rs @@ -25,5 +25,5 @@ pub fn get_gateway_account>::as_ref(&sender_account)[0..20]); - AccountConverter::into_account_id::(truncated_sender_account) + AccountConverter::evm_to_account::(truncated_sender_account) } diff --git a/runtime/integration-tests/src/utils/accounts.rs b/runtime/integration-tests/src/utils/accounts.rs index 46f28d84b8..8b8ac2cbf0 100644 --- a/runtime/integration-tests/src/utils/accounts.rs +++ b/runtime/integration-tests/src/utils/accounts.rs @@ -44,7 +44,7 @@ impl Keyring { /// NOTE: Needs to be executed in an externalities environment pub fn id_ecdsa(self) -> AccountId32 { - runtime_common::account_conversion::AccountConverter::into_account_id::(self.into()) + runtime_common::account_conversion::AccountConverter::evm_to_account::(self.into()) } pub fn as_multi(self) -> sp_runtime::MultiSigner { From 8618a5cf1171d432d10b7b3db83f089bd0e9980c Mon Sep 17 00:00:00 2001 From: lemunozm Date: Wed, 19 Jun 2024 13:20:20 +0200 Subject: [PATCH 04/17] add UTs for transfer --- libs/traits/src/lib.rs | 10 - libs/types/src/domain_address.rs | 22 ++ libs/types/src/tokens.rs | 12 + pallets/liquidity-pools/src/lib.rs | 25 +- pallets/liquidity-pools/src/mock.rs | 22 +- pallets/liquidity-pools/src/tests.rs | 261 ++++++++++++++++++ .../src/generic/cases/assets.rs | 6 +- .../src/generic/cases/currency_conversions.rs | 4 +- .../src/generic/cases/liquidity_pools.rs | 186 ------------- .../src/generic/cases/restricted_transfers.rs | 5 +- .../src/generic/utils/currency.rs | 11 - .../src/generic/utils/xcm.rs | 6 +- 12 files changed, 321 insertions(+), 249 deletions(-) diff --git a/libs/traits/src/lib.rs b/libs/traits/src/lib.rs index 460c54456a..ec97102eb5 100644 --- a/libs/traits/src/lib.rs +++ b/libs/traits/src/lib.rs @@ -309,16 +309,6 @@ impl PreConditions for Always { } } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] -pub struct AlwaysOk; -impl PreConditions for AlwaysOk { - type Result = DispatchResult; - - fn check(_t: T) -> DispatchResult { - Ok(()) - } -} - #[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] pub struct Never; impl PreConditions for Never { diff --git a/libs/types/src/domain_address.rs b/libs/types/src/domain_address.rs index dc450b683a..a9d738661a 100644 --- a/libs/types/src/domain_address.rs +++ b/libs/types/src/domain_address.rs @@ -118,3 +118,25 @@ impl DomainAddress { self.clone().into() } } + +#[cfg(test)] +mod tests { + use parity_scale_codec::{Decode, Encode}; + + use super::*; + + #[test] + fn test_domain_encode_decode() { + test_domain_identity(Domain::Centrifuge); + test_domain_identity(Domain::EVM(1284)); + test_domain_identity(Domain::EVM(1)); + } + + /// Test that (decode . encode) results in the original value + fn test_domain_identity(domain: Domain) { + let encoded = domain.encode(); + let decoded = Domain::decode(&mut encoded.as_slice()).unwrap(); + + assert_eq!(domain, decoded); + } +} diff --git a/libs/types/src/tokens.rs b/libs/types/src/tokens.rs index 77c2737b2a..824e6a5608 100644 --- a/libs/types/src/tokens.rs +++ b/libs/types/src/tokens.rs @@ -321,6 +321,18 @@ pub struct CustomMetadata { pub local_representation: Option, } +#[cfg(feature = "std")] +pub fn default_metadata() -> AssetMetadata { + AssetMetadata { + decimals: 0, + name: Default::default(), + symbol: Default::default(), + existential_deposit: 0, + location: None, + additional: Default::default(), + } +} + /// The Cross Chain Transferability property of an asset describes the way(s), /// if any, that said asset is cross-chain transferable. It may currently be /// transferable through Xcm, Centrifuge Liquidity Pools, or All . diff --git a/pallets/liquidity-pools/src/lib.rs b/pallets/liquidity-pools/src/lib.rs index 70d3c1abbe..c2bf86f2d1 100644 --- a/pallets/liquidity-pools/src/lib.rs +++ b/pallets/liquidity-pools/src/lib.rs @@ -84,6 +84,9 @@ mod inbound; #[cfg(test)] mod mock; +#[cfg(test)] +mod tests; + /// The Parachains that Centrifuge Liquidity Pools support. #[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Debug))] @@ -1093,25 +1096,3 @@ pub mod pallet { } } } - -#[cfg(test)] -mod tests { - use parity_scale_codec::{Decode, Encode}; - - use crate::Domain; - - #[test] - fn test_domain_encode_decode() { - test_domain_identity(Domain::Centrifuge); - test_domain_identity(Domain::EVM(1284)); - test_domain_identity(Domain::EVM(1)); - } - - /// Test that decode . encode results in the original value - fn test_domain_identity(domain: Domain) { - let encoded = domain.encode(); - let decoded: Domain = Domain::decode(&mut encoded.as_slice()).expect(""); - - assert_eq!(domain, decoded); - } -} diff --git a/pallets/liquidity-pools/src/mock.rs b/pallets/liquidity-pools/src/mock.rs index 9270135482..ba54341479 100644 --- a/pallets/liquidity-pools/src/mock.rs +++ b/pallets/liquidity-pools/src/mock.rs @@ -1,23 +1,19 @@ use cfg_primitives::{PoolId, TrancheId}; -use cfg_traits::{AlwaysOk, Millis}; +use cfg_traits::Millis; use cfg_types::{ domain_address::{Domain, DomainAddress}, permissions::PermissionScope, - tokens::{CurrencyId, CustomMetadata, TrancheCurrency}, + tokens::{AssetStringLimit, CurrencyId, CustomMetadata, TrancheCurrency}, }; use frame_support::derive_impl; use orml_traits::parameter_type_with_key; -use sp_runtime::{ - traits::{ConstU32, IdentityLookup}, - AccountId32, FixedU64, -}; +use sp_runtime::{traits::IdentityLookup, AccountId32, DispatchResult, FixedU64}; use crate::pallet as pallet_liquidity_pools; pub type Balance = u128; pub type AccountId = AccountId32; pub type Ratio = FixedU64; -pub type Message = crate::Message; frame_support::construct_runtime!( pub enum Runtime { @@ -30,6 +26,7 @@ frame_support::construct_runtime!( Gateway: cfg_mocks::outbound_queue::pallet, DomainAddressToAccountId: cfg_mocks::converter::pallet::, DomainAccountToDomainAddress: cfg_mocks::converter::pallet::, + TransferFilter: cfg_mocks::pre_conditions::pallet, Tokens: orml_tokens, LiquidityPools: pallet_liquidity_pools, } @@ -63,7 +60,7 @@ impl cfg_mocks::asset_registry::pallet::Config for Runtime { type AssetId = CurrencyId; type Balance = Balance; type CustomMetadata = CustomMetadata; - type StringLimit = ConstU32<64>; + type StringLimit = AssetStringLimit; } impl cfg_mocks::foreign_investment::pallet::Config for Runtime { @@ -75,7 +72,7 @@ impl cfg_mocks::foreign_investment::pallet::Config for Runtime { impl cfg_mocks::outbound_queue::pallet::Config for Runtime { type Destination = Domain; - type Message = Message; + type Message = crate::MessageOf; type Sender = AccountId; } @@ -91,6 +88,11 @@ impl cfg_mocks::converter::pallet::Config for Runtime { type To = DomainAddress; } +impl cfg_mocks::pre_conditions::pallet::Config for Runtime { + type Conditions = (AccountId, DomainAddress, CurrencyId); + type Result = DispatchResult; +} + parameter_type_with_key! { pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { Default::default() @@ -129,7 +131,7 @@ impl pallet_liquidity_pools::Config for Runtime { type Permission = Permissions; type PoolId = PoolId; type PoolInspect = Pools; - type PreTransferFilter = AlwaysOk; + type PreTransferFilter = TransferFilter; type RuntimeEvent = RuntimeEvent; type Time = Time; type Tokens = Tokens; diff --git a/pallets/liquidity-pools/src/tests.rs b/pallets/liquidity-pools/src/tests.rs index e69de29bb2..204ffa945d 100644 --- a/pallets/liquidity-pools/src/tests.rs +++ b/pallets/liquidity-pools/src/tests.rs @@ -0,0 +1,261 @@ +use cfg_traits::liquidity_pools::InboundQueue; +use cfg_types::{ + domain_address::DomainAddress, + tokens::{ + default_metadata, AssetMetadata, CrossChainTransferability, CurrencyId, CustomMetadata, + }, +}; +use frame_support::{ + assert_noop, assert_ok, + traits::{fungibles::Mutate as _, PalletInfo as _}, +}; +use sp_runtime::{DispatchError, TokenError}; +use staging_xcm::{ + v4::{Junction::*, Location, NetworkId}, + VersionedLocation, +}; + +use crate::{mock::*, Error, GeneralCurrencyIndexOf, Message}; + +const CHAIN_ID: u64 = 1; +const ALICE: AccountId = AccountId::new([1; 32]); +const CONTRACT_ACCOUNT: [u8; 20] = [1; 20]; +const EVM_ADDRESS: DomainAddress = DomainAddress::EVM(CHAIN_ID, CONTRACT_ACCOUNT); +const AMOUNT: Balance = 100; +const CURRENCY_ID: CurrencyId = CurrencyId::ForeignAsset(1); + +fn transferable_metadata() -> AssetMetadata { + AssetMetadata { + additional: CustomMetadata { + transferability: CrossChainTransferability::LiquidityPools, + ..Default::default() + }, + ..default_metadata() + } +} + +fn wrapped_transferable_metadata() -> AssetMetadata { + let pallet_index = PalletInfo::index::(); + AssetMetadata { + location: Some(VersionedLocation::V4(Location::new( + 0, + [ + PalletInstance(pallet_index.unwrap() as u8), + GlobalConsensus(NetworkId::Ethereum { chain_id: CHAIN_ID }), + AccountKey20 { + network: None, + key: CONTRACT_ACCOUNT, + }, + ], + ))), + ..transferable_metadata() + } +} + +fn currency_index(currency_id: CurrencyId) -> u128 { + GeneralCurrencyIndexOf::::try_from(currency_id) + .unwrap() + .index +} + +mod erroring_out_when { + use super::*; + + #[test] + fn receiving_output_message() { + System::externalities().execute_with(|| { + let msg = Message::AddPool { pool_id: 123 }; + + assert_noop!( + LiquidityPools::submit(EVM_ADDRESS, msg), + Error::::InvalidIncomingMessage, + ); + }) + } + + mod transfer { + use super::*; + + #[test] + fn zero_balance() { + System::externalities().execute_with(|| { + assert_noop!( + LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CURRENCY_ID, + EVM_ADDRESS, + 0 + ), + Error::::InvalidTransferAmount, + ); + }) + } + + #[test] + fn tranche_currency() { + System::externalities().execute_with(|| { + assert_noop!( + LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CurrencyId::Tranche(42, [0; 16]), + EVM_ADDRESS, + AMOUNT + ), + Error::::InvalidTransferCurrency, + ); + }) + } + + #[test] + fn with_no_metadata() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| None); + + assert_noop!( + LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CURRENCY_ID, + EVM_ADDRESS, + AMOUNT + ), + Error::::AssetNotFound, + ); + }) + } + + #[test] + fn with_unsupported_token() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| Some(default_metadata())); + + assert_noop!( + LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CurrencyId::Native, + EVM_ADDRESS, + AMOUNT + ), + TokenError::Unsupported, + ); + }) + } + + #[test] + fn no_transferible_asset() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| Some(default_metadata())); + + assert_noop!( + LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CURRENCY_ID, + EVM_ADDRESS, + AMOUNT + ), + Error::::AssetNotLiquidityPoolsTransferable, + ); + }) + } + + #[test] + fn without_correct_location() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| Some(transferable_metadata())); + + assert_noop!( + LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CURRENCY_ID, + EVM_ADDRESS, + AMOUNT + ), + Error::::AssetNotLiquidityPoolsWrappedToken + ); + }) + } + + #[test] + fn without_correct_domain() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); + + assert_noop!( + LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CURRENCY_ID, + DomainAddress::Centrifuge([2; 32]), + AMOUNT + ), + Error::::InvalidDomain + ); + }) + } + + #[test] + fn without_satisfy_lp_filter() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); + TransferFilter::mock_check(|_| Err(DispatchError::Other("Err"))); + + assert_noop!( + LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CURRENCY_ID, + EVM_ADDRESS, + AMOUNT + ), + DispatchError::Other("Err"), + ); + }) + } + + #[test] + fn without_sufficient_balance() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); + TransferFilter::mock_check(|_| Ok(())); + + assert_noop!( + LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CURRENCY_ID, + EVM_ADDRESS, + AMOUNT + ), + Error::::BalanceTooLow + ); + }) + } + } +} + +#[test] +fn correct_transfer() { + System::externalities().execute_with(|| { + AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); + TransferFilter::mock_check(|_| Ok(())); + Tokens::mint_into(CURRENCY_ID, &ALICE, AMOUNT).unwrap(); + + Gateway::mock_submit(|sender, destination, msg| { + assert_eq!(sender, ALICE); + assert_eq!(destination, EVM_ADDRESS.domain()); + assert_eq!( + msg, + Message::Transfer { + currency: currency_index(CURRENCY_ID), + sender: ALICE.into(), + receiver: EVM_ADDRESS.address(), + amount: AMOUNT + } + ); + Ok(()) + }); + + assert_ok!(LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CurrencyId::ForeignAsset(1), + EVM_ADDRESS, + AMOUNT + )); + }) +} diff --git a/runtime/integration-tests/src/generic/cases/assets.rs b/runtime/integration-tests/src/generic/cases/assets.rs index 56cf7e24bd..093cb4f842 100644 --- a/runtime/integration-tests/src/generic/cases/assets.rs +++ b/runtime/integration-tests/src/generic/cases/assets.rs @@ -1,11 +1,9 @@ -use cfg_types::tokens::CurrencyId; +use cfg_types::tokens::{default_metadata, CurrencyId}; use frame_support::{assert_noop, assert_ok, dispatch::RawOrigin}; use sp_runtime::{DispatchError, DispatchError::BadOrigin}; use crate::{ - generic::{ - config::Runtime, env::Env, envs::runtime_env::RuntimeEnv, utils::currency::default_metadata, - }, + generic::{config::Runtime, env::Env, envs::runtime_env::RuntimeEnv}, utils::orml_asset_registry, }; diff --git a/runtime/integration-tests/src/generic/cases/currency_conversions.rs b/runtime/integration-tests/src/generic/cases/currency_conversions.rs index a690165203..4cbed8080f 100644 --- a/runtime/integration-tests/src/generic/cases/currency_conversions.rs +++ b/runtime/integration-tests/src/generic/cases/currency_conversions.rs @@ -1,4 +1,4 @@ -use cfg_types::tokens::CurrencyId; +use cfg_types::tokens::{default_metadata, CurrencyId}; use orml_traits::asset_registry::AssetMetadata; use runtime_common::xcm::CurrencyIdConvert; use sp_runtime::traits::Convert; @@ -12,7 +12,7 @@ use crate::generic::{ env::Env, envs::runtime_env::RuntimeEnv, utils::{ - currency::{default_metadata, CurrencyInfo, CustomCurrency}, + currency::{CurrencyInfo, CustomCurrency}, genesis::{self, Genesis}, xcm::transferable_custom, }, diff --git a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs index da62f5d4fc..f4925af2ce 100644 --- a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs +++ b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs @@ -4308,189 +4308,3 @@ mod routers { } } } - -mod gateway { - use super::*; - - #[test_runtimes([development])] - fn set_domain_router() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::council_members::(get_council_members())) - .storage(), - ); - - let test_domain = Domain::EVM(1); - - let axelar_contract_address = H160::from_low_u64_be(1); - let axelar_contract_code: Vec = vec![0, 0, 0]; - let axelar_contract_hash = BlakeTwo256::hash_of(&axelar_contract_code); - let liquidity_pools_contract_address = H160::from_low_u64_be(2); - - env.parachain_state_mut(|| { - pallet_evm::AccountCodes::::insert(axelar_contract_address, axelar_contract_code) - }); - - let evm_domain = EVMDomain { - target_contract_address: axelar_contract_address, - target_contract_hash: axelar_contract_hash, - fee_values: FeeValues { - value: U256::from(10), - gas_limit: U256::from(1_000_000), - gas_price: U256::from(10), - }, - }; - - let axelar_evm_router = AxelarEVMRouter:: { - router: EVMRouter { - evm_domain, - _marker: Default::default(), - }, - evm_chain: BoundedVec::>::try_from( - "ethereum".as_bytes().to_vec(), - ) - .unwrap(), - _marker: Default::default(), - liquidity_pools_contract_address, - }; - - let test_router = DomainRouter::::AxelarEVM(axelar_evm_router); - - let set_domain_router_call = - set_domain_router_call(test_domain.clone(), test_router.clone()); - - let council_threshold = 2; - let voting_period = 3; - - execute_via_democracy::( - &mut env, - get_council_members(), - set_domain_router_call, - council_threshold, - voting_period, - 0, - 0, - ); - - env.parachain_state(|| { - let router = pallet_liquidity_pools_gateway::Pallet::::domain_routers(test_domain) - .expect("domain router is set"); - - assert!(router.eq(&test_router)); - }); - } - - #[test_runtimes([development])] - fn add_remove_instances() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::council_members::(get_council_members())) - .storage(), - ); - - let test_instance = DomainAddress::EVM(1, [0; 20]); - - let add_instance_call = add_instance_call::(test_instance.clone()); - - let council_threshold = 2; - let voting_period = 3; - - let (prop_index, ref_index) = execute_via_democracy::( - &mut env, - get_council_members(), - add_instance_call, - council_threshold, - voting_period, - 0, - 0, - ); - - env.parachain_state(|| { - assert!( - pallet_liquidity_pools_gateway::Allowlist::::contains_key( - test_instance.domain(), - test_instance.clone() - ) - ); - }); - - let remove_instance_call = remove_instance_call::(test_instance.clone()); - - execute_via_democracy::( - &mut env, - get_council_members(), - remove_instance_call, - council_threshold, - voting_period, - prop_index, - ref_index, - ); - - env.parachain_state(|| { - assert!( - !pallet_liquidity_pools_gateway::Allowlist::::contains_key( - test_instance.domain(), - test_instance.clone() - ) - ); - }); - } - - #[test_runtimes([development])] - fn process_msg() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::council_members::(get_council_members())) - .storage(), - ); - - let test_instance = DomainAddress::EVM(1, [0; 20]); - - let add_instance_call = add_instance_call::(test_instance.clone()); - - let council_threshold = 2; - let voting_period = 3; - - execute_via_democracy::( - &mut env, - get_council_members(), - add_instance_call, - council_threshold, - voting_period, - 0, - 0, - ); - - env.parachain_state(|| { - assert!( - pallet_liquidity_pools_gateway::Allowlist::::contains_key( - test_instance.domain(), - test_instance.clone() - ) - ); - }); - - let msg = LiquidityPoolMessage::AddPool { pool_id: 123 }; - - let encoded_msg = msg.serialize(); - - let gateway_msg = BoundedVec::< - u8, - ::MaxIncomingMessageSize, - >::try_from(encoded_msg) - .unwrap(); - - env.parachain_state_mut(|| { - assert_noop!( - pallet_liquidity_pools_gateway::Pallet::::process_msg( - GatewayOrigin::Domain(test_instance).into(), - gateway_msg, - ), - pallet_liquidity_pools::Error::::InvalidIncomingMessage, - ); - }); - } -} diff --git a/runtime/integration-tests/src/generic/cases/restricted_transfers.rs b/runtime/integration-tests/src/generic/cases/restricted_transfers.rs index 3d7725c20a..30f3e2d6e7 100644 --- a/runtime/integration-tests/src/generic/cases/restricted_transfers.rs +++ b/runtime/integration-tests/src/generic/cases/restricted_transfers.rs @@ -15,7 +15,8 @@ use cfg_types::{ domain_address::DomainAddress, locations::RestrictedTransferLocation, tokens::{ - AssetMetadata, CrossChainTransferability, CurrencyId, CustomMetadata, FilterCurrency, + default_metadata, AssetMetadata, CrossChainTransferability, CurrencyId, CustomMetadata, + FilterCurrency, }, }; use cumulus_primitives_core::WeightLimit; @@ -33,7 +34,7 @@ use crate::{ env::Env, envs::runtime_env::RuntimeEnv, utils::{ - currency::{cfg, default_metadata, CurrencyInfo, CustomCurrency}, + currency::{cfg, CurrencyInfo, CustomCurrency}, genesis, genesis::Genesis, xcm::{account_location, transferable_metadata}, diff --git a/runtime/integration-tests/src/generic/utils/currency.rs b/runtime/integration-tests/src/generic/utils/currency.rs index bec217c89e..40e0a3d2da 100644 --- a/runtime/integration-tests/src/generic/utils/currency.rs +++ b/runtime/integration-tests/src/generic/utils/currency.rs @@ -9,17 +9,6 @@ use staging_xcm::VersionedLocation; use crate::generic::config::Runtime; -pub fn default_metadata() -> AssetMetadata { - AssetMetadata { - decimals: 0, - name: Default::default(), - symbol: Default::default(), - existential_deposit: 0, - location: None, - additional: Default::default(), - } -} - const fn amount_pow(amount: Balance, exp: u32) -> Balance { amount * 10u128.pow(exp) } diff --git a/runtime/integration-tests/src/generic/utils/xcm.rs b/runtime/integration-tests/src/generic/utils/xcm.rs index 9f6b4d7f07..2ecc0b2a06 100644 --- a/runtime/integration-tests/src/generic/utils/xcm.rs +++ b/runtime/integration-tests/src/generic/utils/xcm.rs @@ -1,5 +1,7 @@ use cfg_primitives::AccountId; -use cfg_types::tokens::{AssetMetadata, CrossChainTransferability, CustomMetadata}; +use cfg_types::tokens::{ + default_metadata, AssetMetadata, CrossChainTransferability, CustomMetadata, +}; use frame_support::{assert_ok, dispatch::RawOrigin}; use polkadot_parachain_primitives::primitives::Id; use staging_xcm::{ @@ -12,7 +14,7 @@ use crate::generic::{ config::Runtime, env::{Blocks, Env}, envs::fudge_env::{ - handle::{PARA_ID, SIBLING_ID}, + handle::{FudgeHandle, PARA_ID, SIBLING_ID}, FudgeEnv, FudgeSupport, RelayRuntime, }, utils::currency::default_metadata, From d3349be5a9c318bdbc537e896b2dae1258be9f8d Mon Sep 17 00:00:00 2001 From: lemunozm Date: Wed, 19 Jun 2024 13:20:29 +0200 Subject: [PATCH 05/17] simplify account conversion --- pallets/liquidity-pools/src/lib.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pallets/liquidity-pools/src/lib.rs b/pallets/liquidity-pools/src/lib.rs index c2bf86f2d1..b1db5100f2 100644 --- a/pallets/liquidity-pools/src/lib.rs +++ b/pallets/liquidity-pools/src/lib.rs @@ -581,10 +581,7 @@ pub mod pallet { tranche_id, amount, domain: domain_address.domain(), - sender: who - .encode() - .try_into() - .map_err(|_| DispatchError::Other("Conversion to 32 bytes failed"))?, + sender: who.into(), receiver: domain_address.address(), }, )?; @@ -659,10 +656,7 @@ pub mod pallet { Message::Transfer { amount, currency, - sender: who - .encode() - .try_into() - .map_err(|_| DispatchError::Other("Conversion to 32 bytes failed"))?, + sender: who.into(), receiver: receiver.address(), }, )?; From 45d03d121a290379b8e64c4fb3c1234be74b185f Mon Sep 17 00:00:00 2001 From: lemunozm Date: Wed, 19 Jun 2024 13:40:41 +0200 Subject: [PATCH 06/17] remove unused CurrencyIdOf --- pallets/liquidity-pools/src/lib.rs | 46 +++++++++++++----------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/pallets/liquidity-pools/src/lib.rs b/pallets/liquidity-pools/src/lib.rs index b1db5100f2..6c9a2831b2 100644 --- a/pallets/liquidity-pools/src/lib.rs +++ b/pallets/liquidity-pools/src/lib.rs @@ -105,8 +105,6 @@ pub type MessageOf = Message< ::BalanceRatio, >; -pub type CurrencyIdOf = ::CurrencyId; - pub type GeneralCurrencyIndexType = u128; pub type GeneralCurrencyIndexOf = @@ -179,14 +177,14 @@ pub mod pallet { /// currency. type PoolInspect: PoolInspect< Self::AccountId, - CurrencyIdOf, + Self::CurrencyId, PoolId = Self::PoolId, TrancheId = Self::TrancheId, >; type TrancheTokenPrice: TrancheTokenPrice< Self::AccountId, - CurrencyIdOf, + Self::CurrencyId, BalanceRatio = Self::BalanceRatio, PoolId = Self::PoolId, TrancheId = Self::TrancheId, @@ -196,7 +194,7 @@ pub mod pallet { /// The source of truth for investment permissions. type Permission: Permissions< Self::AccountId, - Scope = PermissionScope>, + Scope = PermissionScope, Role = Role, Error = DispatchError, >; @@ -208,15 +206,11 @@ pub mod pallet { /// The type for handling transfers, burning and minting of /// multi-assets. type Tokens: Mutate - + Inspect< - Self::AccountId, - AssetId = CurrencyIdOf, - Balance = ::Balance, - >; + + Inspect; /// The currency type of investments. type TrancheCurrency: TrancheCurrency - + Into> + + Into + Clone; /// Enables investing and redeeming into investment classes with foreign @@ -225,7 +219,7 @@ pub mod pallet { Self::AccountId, Amount = Self::Balance, TrancheAmount = Self::Balance, - CurrencyId = CurrencyIdOf, + CurrencyId = Self::CurrencyId, Error = DispatchError, InvestmentId = ::TrancheCurrency, >; @@ -233,7 +227,7 @@ pub mod pallet { /// The source of truth for the transferability of assets via the /// LiquidityPools feature. type AssetRegistry: asset_registry::Inspect< - AssetId = CurrencyIdOf, + AssetId = Self::CurrencyId, Balance = ::Balance, CustomMetadata = CustomMetadata, >; @@ -249,7 +243,7 @@ pub mod pallet { + TryInto, Error = DispatchError> + TryFrom, Error = DispatchError> // Enables checking whether currency is tranche token - + CurrencyInspect>; + + CurrencyInspect; /// The converter from a DomainAddress to a Substrate AccountId. type DomainAddressToAccountId: Convert; @@ -440,7 +434,7 @@ pub mod pallet { origin: OriginFor, pool_id: T::PoolId, tranche_id: T::TrancheId, - currency_id: CurrencyIdOf, + currency_id: T::CurrencyId, destination: Domain, ) -> DispatchResult { let who = ensure_signed(origin.clone())?; @@ -599,7 +593,7 @@ pub mod pallet { #[pallet::call_index(7)] pub fn transfer( origin: OriginFor, - currency_id: CurrencyIdOf, + currency_id: T::CurrencyId, receiver: DomainAddress, amount: ::Balance, ) -> DispatchResult { @@ -607,7 +601,7 @@ pub mod pallet { ensure!(!amount.is_zero(), Error::::InvalidTransferAmount); ensure!( - !CurrencyIdOf::::is_tranche_token(currency_id), + !T::CurrencyId::is_tranche_token(currency_id), Error::::InvalidTransferCurrency ); let currency = Self::try_get_general_index(currency_id)?; @@ -668,7 +662,7 @@ pub mod pallet { /// from the given currency. #[pallet::weight(10_000 + T::DbWeight::get().writes(1).ref_time())] #[pallet::call_index(8)] - pub fn add_currency(origin: OriginFor, currency_id: CurrencyIdOf) -> DispatchResult { + pub fn add_currency(origin: OriginFor, currency_id: T::CurrencyId) -> DispatchResult { let who = ensure_signed(origin)?; let currency = Self::try_get_general_index(currency_id)?; @@ -697,7 +691,7 @@ pub mod pallet { pub fn allow_investment_currency( origin: OriginFor, pool_id: T::PoolId, - currency_id: CurrencyIdOf, + currency_id: T::CurrencyId, ) -> DispatchResult { // TODO(future): In the future, should be permissioned by trait which // does not exist yet. @@ -803,7 +797,7 @@ pub mod pallet { pub fn disallow_investment_currency( origin: OriginFor, pool_id: T::PoolId, - currency_id: CurrencyIdOf, + currency_id: T::CurrencyId, ) -> DispatchResult { let who = ensure_signed(origin)?; @@ -836,13 +830,13 @@ pub mod pallet { /// Requires the currency to be registered in the `AssetRegistry`. /// /// NOTE: Reverse operation of `try_get_currency_id`. - pub fn try_get_general_index(currency: CurrencyIdOf) -> Result { + pub fn try_get_general_index(currency: T::CurrencyId) -> Result { ensure!( T::AssetRegistry::metadata(¤cy).is_some(), Error::::AssetNotFound ); - let general_index: GeneralCurrencyIndexOf = CurrencyIdOf::::try_into(currency)?; + let general_index: GeneralCurrencyIndexOf = T::CurrencyId::try_into(currency)?; Ok(general_index.index) } @@ -854,8 +848,8 @@ pub mod pallet { /// NOTE: Reverse operation of `try_get_general_index`. pub fn try_get_currency_id( index: GeneralCurrencyIndexOf, - ) -> Result, DispatchError> { - let currency = CurrencyIdOf::::try_from(index)?; + ) -> Result { + let currency = T::CurrencyId::try_from(index)?; ensure!( T::AssetRegistry::metadata(¤cy).is_some(), Error::::AssetNotFound @@ -870,7 +864,7 @@ pub mod pallet { /// /// Requires the currency to be registered in the `AssetRegistry`. pub fn try_get_wrapped_token( - currency_id: &CurrencyIdOf, + currency_id: &T::CurrencyId, ) -> Result { let meta = T::AssetRegistry::metadata(currency_id).ok_or(Error::::AssetNotFound)?; ensure!( @@ -925,7 +919,7 @@ pub mod pallet { /// Performs multiple checks for the provided currency and returns its /// general index and the EVM chain ID associated with it. pub fn validate_investment_currency( - currency_id: CurrencyIdOf, + currency_id: T::CurrencyId, ) -> Result<(u128, EVMChainId), DispatchError> { // Ensure the currency is enabled as pool_currency let metadata = From 72c67ffc8aa7ce2871c39da7dbb5546727978c9b Mon Sep 17 00:00:00 2001 From: lemunozm Date: Wed, 19 Jun 2024 13:42:32 +0200 Subject: [PATCH 07/17] remove already covered tests --- .../src/generic/cases/liquidity_pools.rs | 121 +----------------- 1 file changed, 6 insertions(+), 115 deletions(-) diff --git a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs index f4925af2ce..a41e73ac9d 100644 --- a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs +++ b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs @@ -3,7 +3,7 @@ use cfg_primitives::{ }; use cfg_traits::{ investments::{Investment, OrderManager, TrancheCurrency}, - liquidity_pools::{Codec, InboundQueue, OutboundQueue}, + liquidity_pools::{InboundQueue, OutboundQueue}, IdentityCurrencyConversion, Permissions, PoolInspect, PoolMutate, Seconds, }; use cfg_types::{ @@ -30,7 +30,7 @@ use liquidity_pools_gateway_routers::{ use orml_traits::MultiCurrency; use pallet_investments::CollectOutcome; use pallet_liquidity_pools::Message; -use pallet_liquidity_pools_gateway::{Call as LiquidityPoolsGatewayCall, GatewayOrigin}; +use pallet_liquidity_pools_gateway::Call as LiquidityPoolsGatewayCall; use pallet_pool_system::tranches::{TrancheInput, TrancheLoc, TrancheType}; use polkadot_core_primitives::BlakeTwo256; use runtime_common::{ @@ -51,7 +51,10 @@ use crate::{ generic::{ config::Runtime, env::{Blocks, Env}, - envs::fudge_env::{handle::SIBLING_ID, FudgeEnv, FudgeSupport}, + envs::fudge_env::{ + handle::{FudgeHandle, SIBLING_ID}, + FudgeEnv, FudgeSupport, + }, utils::{ democracy::execute_via_democracy, genesis, genesis::Genesis, xcm::enable_para_to_sibling_communication, @@ -3882,118 +3885,6 @@ mod foreign_investments { } } -mod transfers { - use super::*; - - // TODO: Must be moved to lp/transfers.rs (?) or to UT? It seems more an UT. - - #[test_runtimes([development])] - fn transfer_non_tranche_tokens_from_local() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .storage(), - ); - - setup_test(&mut env); - - env.parachain_state_mut(|| { - let initial_balance = 2 * AUSD_ED; - let amount = initial_balance / 2; - let dest_address = DEFAULT_DOMAIN_ADDRESS_MOONBEAM; - let currency_id = AUSD_CURRENCY_ID; - let source_account = Keyring::Charlie; - - // Mint sufficient balance - assert_eq!( - orml_tokens::Pallet::::free_balance(currency_id, &source_account.into()), - 0 - ); - assert_ok!(orml_tokens::Pallet::::mint_into( - currency_id, - &source_account.into(), - initial_balance - )); - assert_eq!( - orml_tokens::Pallet::::free_balance(currency_id, &source_account.into()), - initial_balance - ); - - // Only `ForeignAsset` can be transferred - assert_noop!( - pallet_liquidity_pools::Pallet::::transfer( - RawOrigin::Signed(source_account.into()).into(), - CurrencyId::Tranche(42u64, [0u8; 16]), - dest_address.clone(), - amount, - ), - pallet_liquidity_pools::Error::::InvalidTransferCurrency - ); - assert_noop!( - pallet_liquidity_pools::Pallet::::transfer( - RawOrigin::Signed(source_account.into()).into(), - CurrencyId::Staking(cfg_types::tokens::StakingCurrency::BlockRewards), - dest_address.clone(), - amount, - ), - pallet_liquidity_pools::Error::::AssetNotFound - ); - assert_noop!( - pallet_liquidity_pools::Pallet::::transfer( - RawOrigin::Signed(source_account.into()).into(), - CurrencyId::Native, - dest_address.clone(), - amount, - ), - pallet_liquidity_pools::Error::::AssetNotFound - ); - - // Cannot transfer as long as cross chain transferability is disabled - assert_noop!( - pallet_liquidity_pools::Pallet::::transfer( - RawOrigin::Signed(source_account.into()).into(), - currency_id, - dest_address.clone(), - initial_balance, - ), - pallet_liquidity_pools::Error::::AssetNotLiquidityPoolsTransferable - ); - - // Enable LiquidityPools transferability - enable_liquidity_pool_transferability::(currency_id); - - // Cannot transfer more than owned - assert_noop!( - pallet_liquidity_pools::Pallet::::transfer( - RawOrigin::Signed(source_account.into()).into(), - currency_id, - dest_address.clone(), - initial_balance.saturating_add(1), - ), - pallet_liquidity_pools::Error::::BalanceTooLow - ); - - let pre_total_issuance = orml_tokens::Pallet::::total_issuance(currency_id); - - assert_ok!(pallet_liquidity_pools::Pallet::::transfer( - RawOrigin::Signed(source_account.into()).into(), - currency_id, - dest_address.clone(), - amount, - )); - - assert_eq!( - orml_tokens::Pallet::::total_issuance(currency_id), - pre_total_issuance - amount - ); - assert_eq!( - orml_tokens::Pallet::::free_balance(currency_id, &source_account.into()), - initial_balance - amount - ); - }); - } -} - mod routers { use super::*; From eabec572490836ee10eb745a7d426e1c51edc4d5 Mon Sep 17 00:00:00 2001 From: lemunozm Date: Wed, 19 Jun 2024 13:47:41 +0200 Subject: [PATCH 08/17] remove democracy utils --- .../src/generic/utils/democracy.rs | 276 ------------------ .../src/generic/utils/mod.rs | 1 - 2 files changed, 277 deletions(-) delete mode 100644 runtime/integration-tests/src/generic/utils/democracy.rs diff --git a/runtime/integration-tests/src/generic/utils/democracy.rs b/runtime/integration-tests/src/generic/utils/democracy.rs deleted file mode 100644 index 0edc63b782..0000000000 --- a/runtime/integration-tests/src/generic/utils/democracy.rs +++ /dev/null @@ -1,276 +0,0 @@ -use std::ops::Add; - -use cfg_primitives::{Balance, BlockNumber, CouncilCollective}; -use frame_support::{dispatch::GetDispatchInfo, traits::Bounded, weights::Weight}; -use pallet_collective::{Call as CouncilCall, MemberCount, ProposalIndex}; -use pallet_democracy::{ - AccountVote, Call as DemocracyCall, Conviction, PropIndex, ReferendumIndex, ReferendumInfo, - Vote, -}; -use pallet_preimage::Call as PreimageCall; -use parity_scale_codec::Encode; -use sp_core::H256; -use sp_runtime::traits::{BlakeTwo256, Hash}; - -use crate::{ - generic::{ - config::Runtime, - env::{Blocks, Env}, - envs::fudge_env::FudgeSupport, - }, - utils::accounts::Keyring, -}; - -pub fn note_preimage(call: T::RuntimeCallExt) -> T::RuntimeCallExt { - let encoded_call = call.encode(); - - PreimageCall::note_preimage { - bytes: encoded_call, - } - .into() -} - -pub fn external_propose_majority(call: T::RuntimeCallExt) -> T::RuntimeCallExt { - let hash = BlakeTwo256::hash_of(&call); - - DemocracyCall::external_propose_majority { - proposal: Bounded::Legacy { - hash, - dummy: Default::default(), - }, - } - .into() -} - -pub fn fast_track( - proposal_hash: H256, - voting_period: BlockNumber, - delay: BlockNumber, -) -> T::RuntimeCallExt { - DemocracyCall::fast_track { - proposal_hash, - voting_period, - delay, - } - .into() -} - -pub fn execute_via_democracy( - env: &mut impl Env, - council_members: Vec, - original_call: T::RuntimeCallExt, - council_threshold: MemberCount, - voting_period: BlockNumber, - starting_prop_index: PropIndex, - starting_ref_index: ReferendumIndex, -) -> (PropIndex, ReferendumIndex) { - let original_call_hash = BlakeTwo256::hash_of(&original_call); - - env.submit_later( - council_members[0].into(), - note_preimage::(original_call.clone()), - ) - .expect("Preimage noting is successful"); - - env.pass(Blocks::UntilEvent { - event: pallet_preimage::Event::::Noted { - hash: original_call_hash, - } - .into(), - limit: 3, - }); - - let external_propose_majority_call = external_propose_majority::(original_call); - - execute_collective_proposal::( - env, - &council_members, - external_propose_majority_call, - council_threshold, - starting_prop_index, - ); - - let fast_track_call = fast_track::(original_call_hash, voting_period, 0); - - execute_collective_proposal::( - env, - &council_members, - fast_track_call, - council_threshold, - starting_prop_index + 1, - ); - - let vote = AccountVote::::Standard { - vote: Vote { - aye: true, - conviction: Conviction::Locked2x, - }, - balance: 1_000_000u128, - }; - - execute_democracy_vote(env, &council_members, starting_ref_index, vote); - - (starting_prop_index + 2, starting_ref_index + 1) -} - -pub fn democracy_vote( - ref_index: ReferendumIndex, - vote: AccountVote, -) -> T::RuntimeCallExt { - DemocracyCall::vote { ref_index, vote }.into() -} - -fn execute_democracy_vote( - env: &mut impl Env, - voters: &Vec, - referendum_index: ReferendumIndex, - acc_vote: AccountVote, -) { - for acc in voters { - let ref_info = env.parachain_state(|| { - pallet_democracy::ReferendumInfoOf::::get(referendum_index).unwrap() - }); - - if let ReferendumInfo::Finished { .. } = ref_info { - // Referendum might be finished by the time all voters get to vote. - break; - } - - env.submit_later(*acc, democracy_vote::(referendum_index, acc_vote)) - .expect("Voting is successful"); - - env.pass(Blocks::UntilEvent { - event: pallet_democracy::Event::::Voted { - voter: acc.id(), - ref_index: referendum_index, - vote: acc_vote, - } - .into(), - limit: 3, - }); - } -} - -pub fn collective_propose( - proposal: T::RuntimeCallExt, - threshold: MemberCount, -) -> T::RuntimeCallExt { - let proposal_len = proposal.encode().len(); - - CouncilCall::propose { - threshold, - proposal: Box::new(proposal), - length_bound: proposal_len as u32, - } - .into() -} - -pub fn collective_vote( - proposal: H256, - index: ProposalIndex, - approve: bool, -) -> T::RuntimeCallExt { - CouncilCall::vote { - proposal, - index, - approve, - } - .into() -} - -pub fn collective_close( - proposal_hash: H256, - index: ProposalIndex, - proposal_weight_bound: Weight, - length_bound: u32, -) -> T::RuntimeCallExt { - CouncilCall::close { - proposal_hash, - index, - proposal_weight_bound, - length_bound, - } - .into() -} - -fn execute_collective_proposal( - env: &mut impl Env, - council_members: &Vec, - proposal: T::RuntimeCallExt, - council_threshold: MemberCount, - prop_index: PropIndex, -) { - let prop_hash = BlakeTwo256::hash_of(&proposal); - - env.submit_later( - council_members[0].into(), - collective_propose::(proposal.clone(), council_threshold), - ) - .expect("Collective proposal is successful"); - - env.pass(Blocks::UntilEvent { - event: pallet_collective::Event::::Proposed { - account: council_members[0].into(), - proposal_index: prop_index, - proposal_hash: prop_hash, - threshold: council_threshold, - } - .into(), - limit: 3, - }); - - for (index, acc) in council_members.iter().enumerate() { - env.submit_later(*acc, collective_vote::(prop_hash, prop_index, true)) - .expect("Collective voting is successful"); - - env.pass(Blocks::UntilEvent { - event: pallet_collective::Event::::Voted { - account: council_members[0].into(), - proposal_hash: prop_hash, - voted: true, - yes: (index + 1) as u32, - no: 0, - } - .into(), - limit: 3, - }); - } - - let proposal_weight = env.parachain_state(|| { - let external_proposal = - pallet_collective::ProposalOf::::get(prop_hash).unwrap(); - - external_proposal.get_dispatch_info().weight - }); - - env.submit_later( - council_members[0].into(), - collective_close::( - prop_hash, - prop_index, - proposal_weight.add(1.into()), - (proposal.encoded_size() + 1) as u32, - ), - ) - .expect("Collective close is successful"); - - env.pass(Blocks::UntilEvent { - event: pallet_collective::Event::::Closed { - proposal_hash: prop_hash, - yes: council_members.len() as u32, - no: 0, - } - .into(), - limit: 3, - }); - - env.check_event(pallet_collective::Event::::Approved { - proposal_hash: prop_hash, - }) - .expect("Approved event is present."); - env.check_event(pallet_collective::Event::::Executed { - proposal_hash: prop_hash, - result: Ok(()), - }) - .expect("Executed event is present."); -} diff --git a/runtime/integration-tests/src/generic/utils/mod.rs b/runtime/integration-tests/src/generic/utils/mod.rs index 992b4916ec..ddc868451d 100644 --- a/runtime/integration-tests/src/generic/utils/mod.rs +++ b/runtime/integration-tests/src/generic/utils/mod.rs @@ -9,7 +9,6 @@ //! Divide this utilities into files when it grows pub mod currency; -pub mod democracy; pub mod evm; pub mod genesis; pub mod pool; From adff1147f61df1b6e24954cd6b46ce273b2c9360 Mon Sep 17 00:00:00 2001 From: lemunozm Date: Wed, 19 Jun 2024 19:01:23 +0200 Subject: [PATCH 09/17] apply Cosmin suggestions --- pallets/liquidity-pools/src/mock.rs | 8 +++----- runtime/common/src/account_conversion.rs | 4 ++-- runtime/common/src/gateway.rs | 2 +- runtime/integration-tests/src/utils/accounts.rs | 3 ++- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/pallets/liquidity-pools/src/mock.rs b/pallets/liquidity-pools/src/mock.rs index ba54341479..aaff960192 100644 --- a/pallets/liquidity-pools/src/mock.rs +++ b/pallets/liquidity-pools/src/mock.rs @@ -25,7 +25,7 @@ frame_support::construct_runtime!( ForeignInvestment: cfg_mocks::foreign_investment::pallet, Gateway: cfg_mocks::outbound_queue::pallet, DomainAddressToAccountId: cfg_mocks::converter::pallet::, - DomainAccountToDomainAddress: cfg_mocks::converter::pallet::, + DomainAccountToDomainAddress: cfg_mocks::converter::pallet::, TransferFilter: cfg_mocks::pre_conditions::pallet, Tokens: orml_tokens, LiquidityPools: pallet_liquidity_pools, @@ -76,14 +76,12 @@ impl cfg_mocks::outbound_queue::pallet::Config for Runtime { type Sender = AccountId; } -type I1 = cfg_mocks::converter::pallet::Instance1; -impl cfg_mocks::converter::pallet::Config for Runtime { +impl cfg_mocks::converter::pallet::Config for Runtime { type From = DomainAddress; type To = AccountId; } -type I3 = cfg_mocks::converter::pallet::Instance3; -impl cfg_mocks::converter::pallet::Config for Runtime { +impl cfg_mocks::converter::pallet::Config for Runtime { type From = (Domain, [u8; 32]); type To = DomainAddress; } diff --git a/runtime/common/src/account_conversion.rs b/runtime/common/src/account_conversion.rs index 3603cd2e60..ded709ec11 100644 --- a/runtime/common/src/account_conversion.rs +++ b/runtime/common/src/account_conversion.rs @@ -61,7 +61,7 @@ impl AccountConverter { } } - pub fn evm_to_account(address: H160) -> AccountId { + pub fn evm_address_to_account(address: H160) -> AccountId { let chain_id = pallet_evm_chain_id::Pallet::::get(); Self::convert_evm_address(chain_id, address.0) } @@ -101,7 +101,7 @@ pub struct RuntimeAccountConverter(sp_std::marker::PhantomData); impl AddressMapping for RuntimeAccountConverter { fn into_account_id(address: H160) -> AccountId { - AccountConverter::evm_to_account::(address) + AccountConverter::evm_address_to_account::(address) } } diff --git a/runtime/common/src/gateway.rs b/runtime/common/src/gateway.rs index a753a66313..5b75077ac7 100644 --- a/runtime/common/src/gateway.rs +++ b/runtime/common/src/gateway.rs @@ -25,5 +25,5 @@ pub fn get_gateway_account>::as_ref(&sender_account)[0..20]); - AccountConverter::evm_to_account::(truncated_sender_account) + AccountConverter::evm_address_to_account::(truncated_sender_account) } diff --git a/runtime/integration-tests/src/utils/accounts.rs b/runtime/integration-tests/src/utils/accounts.rs index 8b8ac2cbf0..4a111daa34 100644 --- a/runtime/integration-tests/src/utils/accounts.rs +++ b/runtime/integration-tests/src/utils/accounts.rs @@ -14,6 +14,7 @@ use ethabi::ethereum_types::{H160, H256}; use frame_support::traits::OriginTrait; +use runtime_common::account_conversion::AccountConverter; use sp_core::{ecdsa, ed25519, sr25519, Hasher, Pair as PairT}; use sp_runtime::AccountId32; @@ -44,7 +45,7 @@ impl Keyring { /// NOTE: Needs to be executed in an externalities environment pub fn id_ecdsa(self) -> AccountId32 { - runtime_common::account_conversion::AccountConverter::evm_to_account::(self.into()) + AccountConverter::evm_address_to_account::(self.into()) } pub fn as_multi(self) -> sp_runtime::MultiSigner { From e37b1f9c3667c9b559beb01cb947254b2848eedf Mon Sep 17 00:00:00 2001 From: lemunozm Date: Thu, 20 Jun 2024 11:22:58 +0200 Subject: [PATCH 10/17] add transfer_tranche_tokens tests --- pallets/liquidity-pools/src/tests.rs | 239 +++++++++++++++--- .../src/generic/cases/lp/transfers.rs | 51 +--- 2 files changed, 202 insertions(+), 88 deletions(-) diff --git a/pallets/liquidity-pools/src/tests.rs b/pallets/liquidity-pools/src/tests.rs index 204ffa945d..c18cf4198c 100644 --- a/pallets/liquidity-pools/src/tests.rs +++ b/pallets/liquidity-pools/src/tests.rs @@ -1,6 +1,8 @@ -use cfg_traits::liquidity_pools::InboundQueue; +use cfg_primitives::{PoolId, TrancheId}; +use cfg_traits::{liquidity_pools::InboundQueue, Millis}; use cfg_types::{ domain_address::DomainAddress, + permissions::{PermissionScope, PoolRole, Role}, tokens::{ default_metadata, AssetMetadata, CrossChainTransferability, CurrencyId, CustomMetadata, }, @@ -18,11 +20,15 @@ use staging_xcm::{ use crate::{mock::*, Error, GeneralCurrencyIndexOf, Message}; const CHAIN_ID: u64 = 1; -const ALICE: AccountId = AccountId::new([1; 32]); +const ALICE: AccountId = AccountId::new([0; 32]); const CONTRACT_ACCOUNT: [u8; 20] = [1; 20]; +const CONTRACT_ACCOUNT_ID: AccountId = AccountId::new([1; 32]); const EVM_ADDRESS: DomainAddress = DomainAddress::EVM(CHAIN_ID, CONTRACT_ACCOUNT); const AMOUNT: Balance = 100; const CURRENCY_ID: CurrencyId = CurrencyId::ForeignAsset(1); +const POOL_ID: PoolId = 1; +const TRANCHE_ID: TrancheId = [1; 16]; +const NOW: Millis = 0; fn transferable_metadata() -> AssetMetadata { AssetMetadata { @@ -58,26 +64,44 @@ fn currency_index(currency_id: CurrencyId) -> u128 { .index } -mod erroring_out_when { +mod transfer { use super::*; #[test] - fn receiving_output_message() { + fn success() { System::externalities().execute_with(|| { - let msg = Message::AddPool { pool_id: 123 }; + AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); + TransferFilter::mock_check(|_| Ok(())); + Tokens::mint_into(CURRENCY_ID, &ALICE, AMOUNT).unwrap(); + Gateway::mock_submit(|sender, destination, msg| { + assert_eq!(sender, ALICE); + assert_eq!(destination, EVM_ADDRESS.domain()); + assert_eq!( + msg, + Message::Transfer { + currency: currency_index(CURRENCY_ID), + sender: ALICE.into(), + receiver: EVM_ADDRESS.address(), + amount: AMOUNT + } + ); + Ok(()) + }); - assert_noop!( - LiquidityPools::submit(EVM_ADDRESS, msg), - Error::::InvalidIncomingMessage, - ); + assert_ok!(LiquidityPools::transfer( + RuntimeOrigin::signed(ALICE), + CurrencyId::ForeignAsset(1), + EVM_ADDRESS, + AMOUNT + )); }) } - mod transfer { + mod erroring_out_when { use super::*; #[test] - fn zero_balance() { + fn with_zero_balance() { System::externalities().execute_with(|| { assert_noop!( LiquidityPools::transfer( @@ -92,7 +116,7 @@ mod erroring_out_when { } #[test] - fn tranche_currency() { + fn with_tranche_currency() { System::externalities().execute_with(|| { assert_noop!( LiquidityPools::transfer( @@ -141,7 +165,7 @@ mod erroring_out_when { } #[test] - fn no_transferible_asset() { + fn with_no_transferible_asset() { System::externalities().execute_with(|| { AssetRegistry::mock_metadata(|_| Some(default_metadata())); @@ -229,33 +253,170 @@ mod erroring_out_when { } } +mod transfer_tranche_tokens { + use super::*; + + #[test] + fn success() { + System::externalities().execute_with(|| { + DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); + Time::mock_now(|| NOW); + Permissions::mock_has(move |scope, who, role| { + assert_eq!(who, CONTRACT_ACCOUNT_ID); + assert!(matches!(scope, PermissionScope::Pool(POOL_ID))); + assert!(matches!( + role, + Role::PoolRole(PoolRole::TrancheInvestor(TRANCHE_ID, NOW)) + )); + true + }); + Pools::mock_pool_exists(|_| true); + Pools::mock_tranche_exists(|_, _| true); + TransferFilter::mock_check(|_| Ok(())); + Tokens::mint_into(CurrencyId::Tranche(POOL_ID, TRANCHE_ID), &ALICE, AMOUNT).unwrap(); + + Gateway::mock_submit(|sender, destination, msg| { + assert_eq!(sender, ALICE); + assert_eq!(destination, EVM_ADDRESS.domain()); + assert_eq!( + msg, + Message::TransferTrancheTokens { + pool_id: POOL_ID, + tranche_id: TRANCHE_ID, + sender: ALICE.into(), + domain: EVM_ADDRESS.domain(), + receiver: EVM_ADDRESS.address(), + amount: AMOUNT + } + ); + Ok(()) + }); + + assert_ok!(LiquidityPools::transfer_tranche_tokens( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS, + AMOUNT + ),); + }) + } + + mod erroring_out_when { + use super::*; + + #[test] + fn with_zero_balance() { + System::externalities().execute_with(|| { + assert_noop!( + LiquidityPools::transfer_tranche_tokens( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS, + 0 + ), + Error::::InvalidTransferAmount, + ); + }) + } + + #[test] + fn with_no_tranche_investor_role() { + System::externalities().execute_with(|| { + DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); + Time::mock_now(|| NOW); + Permissions::mock_has(|_, _, _| false); + + assert_noop!( + LiquidityPools::transfer_tranche_tokens( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS, + AMOUNT + ), + Error::::UnauthorizedTransfer, + ); + }) + } + + #[test] + fn without_correct_pool() { + System::externalities().execute_with(|| { + DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); + Time::mock_now(|| NOW); + Permissions::mock_has(move |_, _, _| true); + Pools::mock_pool_exists(|_| false); + + assert_noop!( + LiquidityPools::transfer_tranche_tokens( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS, + AMOUNT + ), + Error::::PoolNotFound, + ); + }) + } + + #[test] + fn without_correct_tranche_id() { + System::externalities().execute_with(|| { + DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); + Time::mock_now(|| NOW); + Permissions::mock_has(move |_, _, _| true); + Pools::mock_pool_exists(|_| true); + Pools::mock_tranche_exists(|_, _| false); + + assert_noop!( + LiquidityPools::transfer_tranche_tokens( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS, + AMOUNT + ), + Error::::TrancheNotFound, + ); + }) + } + + #[test] + fn without_satisfy_lp_filter() { + System::externalities().execute_with(|| { + DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); + Time::mock_now(|| NOW); + Permissions::mock_has(move |_, _, _| true); + Pools::mock_pool_exists(|_| true); + Pools::mock_tranche_exists(|_, _| true); + TransferFilter::mock_check(|_| Err(DispatchError::Other("Err"))); + + assert_noop!( + LiquidityPools::transfer_tranche_tokens( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS, + AMOUNT + ), + DispatchError::Other("Err"), + ); + }) + } + } +} + #[test] -fn correct_transfer() { +fn receiving_output_message() { System::externalities().execute_with(|| { - AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); - TransferFilter::mock_check(|_| Ok(())); - Tokens::mint_into(CURRENCY_ID, &ALICE, AMOUNT).unwrap(); - - Gateway::mock_submit(|sender, destination, msg| { - assert_eq!(sender, ALICE); - assert_eq!(destination, EVM_ADDRESS.domain()); - assert_eq!( - msg, - Message::Transfer { - currency: currency_index(CURRENCY_ID), - sender: ALICE.into(), - receiver: EVM_ADDRESS.address(), - amount: AMOUNT - } - ); - Ok(()) - }); - - assert_ok!(LiquidityPools::transfer( - RuntimeOrigin::signed(ALICE), - CurrencyId::ForeignAsset(1), - EVM_ADDRESS, - AMOUNT - )); + let msg = Message::AddPool { pool_id: 123 }; + + assert_noop!( + LiquidityPools::submit(EVM_ADDRESS, msg), + Error::::InvalidIncomingMessage, + ); }) } diff --git a/runtime/integration-tests/src/generic/cases/lp/transfers.rs b/runtime/integration-tests/src/generic/cases/lp/transfers.rs index 864f3f43c0..0aff7d8415 100644 --- a/runtime/integration-tests/src/generic/cases/lp/transfers.rs +++ b/runtime/integration-tests/src/generic/cases/lp/transfers.rs @@ -10,15 +10,13 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -use cfg_primitives::{Balance, PoolId}; -use cfg_traits::Seconds; +use cfg_primitives::Balance; use cfg_types::{ domain_address::{Domain, DomainAddress}, - permissions::PoolRole, tokens::CurrencyId, }; use ethabi::{ethereum_types::U256, Token}; -use frame_support::{assert_noop, traits::OriginTrait}; +use frame_support::traits::OriginTrait; use frame_system::pallet_prelude::OriginFor; use pallet_liquidity_pools::Message; use sp_core::ByteArray; @@ -344,48 +342,3 @@ fn transfer_tranche_tokens_domain_to_local() { ); }); } - -#[test_runtimes(all)] -fn transferring_invalid_tranche_tokens_should_fail() { - const INVALID_POOL_ID: PoolId = 100; - const INVALID_TRANCHE_ID: [u8; 16] = [0; 16]; - let mut env = super::setup_full::(); - - env.state_mut(|_| { - crate::generic::utils::pool::give_role::( - lp::utils::remote_account_of::(Keyring::TrancheInvestor(1)), - POOL_A, - PoolRole::TrancheInvestor(INVALID_TRANCHE_ID, Seconds::MAX), - ); - crate::generic::utils::pool::give_role::( - lp::utils::remote_account_of::(Keyring::TrancheInvestor(1)), - INVALID_POOL_ID, - PoolRole::TrancheInvestor(INVALID_TRANCHE_ID, Seconds::MAX), - ); - }); - - let destination = DomainAddress::EVM(EVM_DOMAIN_CHAIN_ID, Keyring::TrancheInvestor(1).into()); - env.state(|_evm| { - assert_noop!( - pallet_liquidity_pools::Pallet::::transfer_tranche_tokens( - OriginFor::::signed(Keyring::TrancheInvestor(1).into()), - INVALID_POOL_ID, - INVALID_TRANCHE_ID, - destination.clone(), - AMOUNT - ), - pallet_liquidity_pools::Error::::PoolNotFound - ); - - assert_noop!( - pallet_liquidity_pools::Pallet::::transfer_tranche_tokens( - OriginFor::::signed(Keyring::TrancheInvestor(1).into()), - POOL_A, - INVALID_TRANCHE_ID, - destination, - AMOUNT - ), - pallet_liquidity_pools::Error::::TrancheNotFound - ); - }); -} From 7a650748824bf0c1da3d17dd3f12874f10cfeb0b Mon Sep 17 00:00:00 2001 From: lemunozm Date: Thu, 20 Jun 2024 11:29:01 +0200 Subject: [PATCH 11/17] minor clean --- pallets/liquidity-pools/src/lib.rs | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/pallets/liquidity-pools/src/lib.rs b/pallets/liquidity-pools/src/lib.rs index 6c9a2831b2..275666aafd 100644 --- a/pallets/liquidity-pools/src/lib.rs +++ b/pallets/liquidity-pools/src/lib.rs @@ -59,8 +59,6 @@ use frame_support::{ }; use orml_traits::asset_registry::{self, Inspect as _}; pub use pallet::*; -use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -use scale_info::TypeInfo; use sp_runtime::{ traits::{AtLeast32BitUnsigned, Convert}, FixedPointNumber, SaturatedConversion, @@ -87,15 +85,6 @@ mod mock; #[cfg(test)] mod tests; -/// The Parachains that Centrifuge Liquidity Pools support. -#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -#[cfg_attr(feature = "std", derive(Debug))] -pub enum ParachainId { - /// Moonbeam - It may be Moonbeam on Polkadot, Moonriver on Kusama, or - /// Moonbase on a testnet. - Moonbeam, -} - // Type aliases pub type MessageOf = Message< Domain, @@ -343,7 +332,7 @@ pub mod pallet { ::AccountId: From<[u8; 32]> + Into<[u8; 32]>, { /// Add a pool to a given domain - #[pallet::weight(< T as Config >::WeightInfo::add_pool())] + #[pallet::weight(T::WeightInfo::add_pool())] #[pallet::call_index(2)] pub fn add_pool( origin: OriginFor, @@ -371,7 +360,7 @@ pub mod pallet { } /// Add a tranche to a given domain - #[pallet::weight(< T as Config >::WeightInfo::add_tranche())] + #[pallet::weight(T::WeightInfo::add_tranche())] #[pallet::call_index(3)] pub fn add_tranche( origin: OriginFor, @@ -428,7 +417,7 @@ pub mod pallet { /// domain, this call origin can be permissionless. /// /// The `currency_id` parameter is necessary for the EVM side. - #[pallet::weight(< T as Config >::WeightInfo::update_token_price())] + #[pallet::weight(T::WeightInfo::update_token_price())] #[pallet::call_index(4)] pub fn update_token_price( origin: OriginFor, @@ -472,7 +461,7 @@ pub mod pallet { } /// Update a member - #[pallet::weight(< T as Config >::WeightInfo::update_member())] + #[pallet::weight(T::WeightInfo::update_member())] #[pallet::call_index(5)] pub fn update_member( origin: OriginFor, @@ -527,7 +516,7 @@ pub mod pallet { /// /// NOTE: The transferring account is not kept alive as we allow its /// death. - #[pallet::weight(< T as Config >::WeightInfo::transfer())] + #[pallet::weight(T::WeightInfo::transfer())] #[pallet::call_index(6)] pub fn transfer_tranche_tokens( origin: OriginFor, @@ -589,7 +578,7 @@ pub mod pallet { /// /// NOTE: The transferring account is not kept alive as we allow its /// death. - #[pallet::weight(< T as Config >::WeightInfo::transfer())] + #[pallet::weight(T::WeightInfo::transfer())] #[pallet::call_index(7)] pub fn transfer( origin: OriginFor, @@ -736,7 +725,7 @@ pub mod pallet { } /// Schedule an upgrade of an EVM-based liquidity pool contract instance - #[pallet::weight(::WeightInfo::cancel_upgrade())] + #[pallet::weight(T::WeightInfo::cancel_upgrade())] #[pallet::call_index(11)] pub fn cancel_upgrade( origin: OriginFor, @@ -757,7 +746,7 @@ pub mod pallet { /// NOTE: Pulls the metadata from the `AssetRegistry` and thus requires /// the pool admin to have updated the tranche tokens metadata there /// beforehand. - #[pallet::weight(::WeightInfo::update_tranche_token_metadata())] + #[pallet::weight(T::WeightInfo::update_tranche_token_metadata())] #[pallet::call_index(12)] pub fn update_tranche_token_metadata( origin: OriginFor, From 24ebf2e294dd167490cb82a3b6b834d11e6472c2 Mon Sep 17 00:00:00 2001 From: lemunozm Date: Thu, 20 Jun 2024 11:37:59 +0200 Subject: [PATCH 12/17] add add_pool tests --- pallets/liquidity-pools/src/tests.rs | 81 +++++++++++++++++-- .../src/generic/cases/liquidity_pools.rs | 50 ------------ 2 files changed, 74 insertions(+), 57 deletions(-) diff --git a/pallets/liquidity-pools/src/tests.rs b/pallets/liquidity-pools/src/tests.rs index c18cf4198c..4e4a7f2e9e 100644 --- a/pallets/liquidity-pools/src/tests.rs +++ b/pallets/liquidity-pools/src/tests.rs @@ -182,7 +182,7 @@ mod transfer { } #[test] - fn without_correct_location() { + fn with_wrong_location() { System::externalities().execute_with(|| { AssetRegistry::mock_metadata(|_| Some(transferable_metadata())); @@ -199,7 +199,7 @@ mod transfer { } #[test] - fn without_correct_domain() { + fn with_wrong_domain() { System::externalities().execute_with(|| { AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); @@ -216,7 +216,7 @@ mod transfer { } #[test] - fn without_satisfy_lp_filter() { + fn without_satisfy_filter() { System::externalities().execute_with(|| { AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); TransferFilter::mock_check(|_| Err(DispatchError::Other("Err"))); @@ -322,7 +322,7 @@ mod transfer_tranche_tokens { } #[test] - fn with_no_tranche_investor_role() { + fn with_wrong_permissions() { System::externalities().execute_with(|| { DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); Time::mock_now(|| NOW); @@ -342,7 +342,7 @@ mod transfer_tranche_tokens { } #[test] - fn without_correct_pool() { + fn with_wrong_pool() { System::externalities().execute_with(|| { DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); Time::mock_now(|| NOW); @@ -363,7 +363,7 @@ mod transfer_tranche_tokens { } #[test] - fn without_correct_tranche_id() { + fn with_wrong_tranche_id() { System::externalities().execute_with(|| { DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); Time::mock_now(|| NOW); @@ -385,7 +385,7 @@ mod transfer_tranche_tokens { } #[test] - fn without_satisfy_lp_filter() { + fn without_satisfy_filter() { System::externalities().execute_with(|| { DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); Time::mock_now(|| NOW); @@ -409,6 +409,73 @@ mod transfer_tranche_tokens { } } +mod add_pool { + use super::*; + + #[test] + fn success() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |scope, who, role| { + assert_eq!(who, ALICE); + assert!(matches!(scope, PermissionScope::Pool(POOL_ID))); + assert!(matches!(role, Role::PoolRole(PoolRole::PoolAdmin))); + true + }); + Pools::mock_pool_exists(|_| true); + + Gateway::mock_submit(|sender, destination, msg| { + assert_eq!(sender, ALICE); + assert_eq!(destination, EVM_ADDRESS.domain()); + assert_eq!(msg, Message::AddPool { pool_id: POOL_ID }); + Ok(()) + }); + + assert_ok!(LiquidityPools::add_pool( + RuntimeOrigin::signed(ALICE), + POOL_ID, + EVM_ADDRESS.domain(), + )); + }) + } + + mod erroring_out_when { + use super::*; + + #[test] + fn with_wrong_pool() { + System::externalities().execute_with(|| { + Pools::mock_pool_exists(|_| true); + Permissions::mock_has(move |_, _, _| false); + + assert_noop!( + LiquidityPools::add_pool( + RuntimeOrigin::signed(ALICE), + POOL_ID, + EVM_ADDRESS.domain(), + ), + Error::::NotPoolAdmin + ); + }) + } + + #[test] + fn with_wrong_permissions() { + System::externalities().execute_with(|| { + Pools::mock_pool_exists(|_| false); + + assert_noop!( + LiquidityPools::add_pool( + RuntimeOrigin::signed(ALICE), + POOL_ID, + EVM_ADDRESS.domain(), + ), + Error::::PoolNotFound + ); + }) + } + } +} + #[test] fn receiving_output_message() { System::externalities().execute_with(|| { diff --git a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs index a41e73ac9d..f0d94c2a22 100644 --- a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs +++ b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs @@ -705,56 +705,6 @@ mod add_allow_upgrade { use super::*; - #[test_runtimes([development])] - fn add_pool() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::tokens::(vec![( - GLMR_CURRENCY_ID, - DEFAULT_BALANCE_GLMR, - )])) - .storage(), - ); - - setup_test(&mut env); - - env.parachain_state_mut(|| { - let pool_id = POOL_ID; - - // Verify that the pool must exist before we can call - // pallet_liquidity_pools::Pallet::::add_pool - assert_noop!( - pallet_liquidity_pools::Pallet::::add_pool( - RawOrigin::Signed(Keyring::Alice.into()).into(), - pool_id, - Domain::EVM(MOONBEAM_EVM_CHAIN_ID), - ), - pallet_liquidity_pools::Error::::PoolNotFound - ); - - // Now create the pool - create_ausd_pool::(pool_id); - - // Verify ALICE can't call `add_pool` given she is not the `PoolAdmin` - assert_noop!( - pallet_liquidity_pools::Pallet::::add_pool( - RawOrigin::Signed(Keyring::Alice.into()).into(), - pool_id, - Domain::EVM(MOONBEAM_EVM_CHAIN_ID), - ), - pallet_liquidity_pools::Error::::NotPoolAdmin - ); - - // Verify that it works if it's BOB calling it (the pool admin) - assert_ok!(pallet_liquidity_pools::Pallet::::add_pool( - RawOrigin::Signed(POOL_ADMIN.into()).into(), - pool_id, - Domain::EVM(MOONBEAM_EVM_CHAIN_ID), - )); - }); - } - #[test_runtimes([development])] fn add_tranche() { let mut env = FudgeEnv::::from_parachain_storage( From 7d576fcc9b7b67c6b33cfade51dc11a1c6ae52bf Mon Sep 17 00:00:00 2001 From: lemunozm Date: Thu, 20 Jun 2024 12:06:00 +0200 Subject: [PATCH 13/17] add add_tranche tests --- pallets/liquidity-pools/src/lib.rs | 5 - pallets/liquidity-pools/src/tests.rs | 219 ++++++++++++++---- .../src/generic/cases/liquidity_pools.rs | 72 ------ 3 files changed, 176 insertions(+), 120 deletions(-) diff --git a/pallets/liquidity-pools/src/lib.rs b/pallets/liquidity-pools/src/lib.rs index 275666aafd..c03021eb60 100644 --- a/pallets/liquidity-pools/src/lib.rs +++ b/pallets/liquidity-pools/src/lib.rs @@ -370,11 +370,6 @@ pub mod pallet { ) -> DispatchResult { let who = ensure_signed(origin.clone())?; - ensure!( - T::PoolInspect::tranche_exists(pool_id, tranche_id), - Error::::TrancheNotFound - ); - ensure!( T::Permission::has( PermissionScope::Pool(pool_id), diff --git a/pallets/liquidity-pools/src/tests.rs b/pallets/liquidity-pools/src/tests.rs index 4e4a7f2e9e..f4a72e73cf 100644 --- a/pallets/liquidity-pools/src/tests.rs +++ b/pallets/liquidity-pools/src/tests.rs @@ -3,10 +3,9 @@ use cfg_traits::{liquidity_pools::InboundQueue, Millis}; use cfg_types::{ domain_address::DomainAddress, permissions::{PermissionScope, PoolRole, Role}, - tokens::{ - default_metadata, AssetMetadata, CrossChainTransferability, CurrencyId, CustomMetadata, - }, + tokens::{AssetMetadata, CrossChainTransferability, CurrencyId, CustomMetadata}, }; +use cfg_utils::vec_to_fixed_array; use frame_support::{ assert_noop, assert_ok, traits::{fungibles::Mutate as _, PalletInfo as _}, @@ -29,39 +28,55 @@ const CURRENCY_ID: CurrencyId = CurrencyId::ForeignAsset(1); const POOL_ID: PoolId = 1; const TRANCHE_ID: TrancheId = [1; 16]; const NOW: Millis = 0; +const NAME: &[u8] = b"Token name"; +const SYMBOL: &[u8] = b"Token symbol"; +const DECIMALS: u8 = 6; -fn transferable_metadata() -> AssetMetadata { - AssetMetadata { - additional: CustomMetadata { - transferability: CrossChainTransferability::LiquidityPools, - ..Default::default() - }, - ..default_metadata() +mod util { + use super::*; + + pub fn default_metadata() -> AssetMetadata { + AssetMetadata { + decimals: DECIMALS as u32, + name: Vec::from(NAME).try_into().unwrap(), + symbol: Vec::from(SYMBOL).try_into().unwrap(), + ..cfg_types::tokens::default_metadata() + } } -} -fn wrapped_transferable_metadata() -> AssetMetadata { - let pallet_index = PalletInfo::index::(); - AssetMetadata { - location: Some(VersionedLocation::V4(Location::new( - 0, - [ - PalletInstance(pallet_index.unwrap() as u8), - GlobalConsensus(NetworkId::Ethereum { chain_id: CHAIN_ID }), - AccountKey20 { - network: None, - key: CONTRACT_ACCOUNT, - }, - ], - ))), - ..transferable_metadata() + pub fn transferable_metadata() -> AssetMetadata { + AssetMetadata { + additional: CustomMetadata { + transferability: CrossChainTransferability::LiquidityPools, + ..Default::default() + }, + ..default_metadata() + } } -} -fn currency_index(currency_id: CurrencyId) -> u128 { - GeneralCurrencyIndexOf::::try_from(currency_id) - .unwrap() - .index + pub fn wrapped_transferable_metadata() -> AssetMetadata { + let pallet_index = PalletInfo::index::(); + AssetMetadata { + location: Some(VersionedLocation::V4(Location::new( + 0, + [ + PalletInstance(pallet_index.unwrap() as u8), + GlobalConsensus(NetworkId::Ethereum { chain_id: CHAIN_ID }), + AccountKey20 { + network: None, + key: CONTRACT_ACCOUNT, + }, + ], + ))), + ..transferable_metadata() + } + } + + pub fn currency_index(currency_id: CurrencyId) -> u128 { + GeneralCurrencyIndexOf::::try_from(currency_id) + .unwrap() + .index + } } mod transfer { @@ -70,7 +85,7 @@ mod transfer { #[test] fn success() { System::externalities().execute_with(|| { - AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); + AssetRegistry::mock_metadata(|_| Some(util::wrapped_transferable_metadata())); TransferFilter::mock_check(|_| Ok(())); Tokens::mint_into(CURRENCY_ID, &ALICE, AMOUNT).unwrap(); Gateway::mock_submit(|sender, destination, msg| { @@ -79,7 +94,7 @@ mod transfer { assert_eq!( msg, Message::Transfer { - currency: currency_index(CURRENCY_ID), + currency: util::currency_index(CURRENCY_ID), sender: ALICE.into(), receiver: EVM_ADDRESS.address(), amount: AMOUNT @@ -150,7 +165,7 @@ mod transfer { #[test] fn with_unsupported_token() { System::externalities().execute_with(|| { - AssetRegistry::mock_metadata(|_| Some(default_metadata())); + AssetRegistry::mock_metadata(|_| Some(util::default_metadata())); assert_noop!( LiquidityPools::transfer( @@ -167,7 +182,7 @@ mod transfer { #[test] fn with_no_transferible_asset() { System::externalities().execute_with(|| { - AssetRegistry::mock_metadata(|_| Some(default_metadata())); + AssetRegistry::mock_metadata(|_| Some(util::default_metadata())); assert_noop!( LiquidityPools::transfer( @@ -184,7 +199,7 @@ mod transfer { #[test] fn with_wrong_location() { System::externalities().execute_with(|| { - AssetRegistry::mock_metadata(|_| Some(transferable_metadata())); + AssetRegistry::mock_metadata(|_| Some(util::transferable_metadata())); assert_noop!( LiquidityPools::transfer( @@ -201,7 +216,7 @@ mod transfer { #[test] fn with_wrong_domain() { System::externalities().execute_with(|| { - AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); + AssetRegistry::mock_metadata(|_| Some(util::wrapped_transferable_metadata())); assert_noop!( LiquidityPools::transfer( @@ -218,7 +233,7 @@ mod transfer { #[test] fn without_satisfy_filter() { System::externalities().execute_with(|| { - AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); + AssetRegistry::mock_metadata(|_| Some(util::wrapped_transferable_metadata())); TransferFilter::mock_check(|_| Err(DispatchError::Other("Err"))); assert_noop!( @@ -236,7 +251,7 @@ mod transfer { #[test] fn without_sufficient_balance() { System::externalities().execute_with(|| { - AssetRegistry::mock_metadata(|_| Some(wrapped_transferable_metadata())); + AssetRegistry::mock_metadata(|_| Some(util::wrapped_transferable_metadata())); TransferFilter::mock_check(|_| Ok(())); assert_noop!( @@ -274,7 +289,6 @@ mod transfer_tranche_tokens { Pools::mock_tranche_exists(|_, _| true); TransferFilter::mock_check(|_| Ok(())); Tokens::mint_into(CurrencyId::Tranche(POOL_ID, TRANCHE_ID), &ALICE, AMOUNT).unwrap(); - Gateway::mock_submit(|sender, destination, msg| { assert_eq!(sender, ALICE); assert_eq!(destination, EVM_ADDRESS.domain()); @@ -363,7 +377,7 @@ mod transfer_tranche_tokens { } #[test] - fn with_wrong_tranche_id() { + fn with_wrong_tranche() { System::externalities().execute_with(|| { DomainAddressToAccountId::mock_convert(|_| CONTRACT_ACCOUNT_ID); Time::mock_now(|| NOW); @@ -422,7 +436,6 @@ mod add_pool { true }); Pools::mock_pool_exists(|_| true); - Gateway::mock_submit(|sender, destination, msg| { assert_eq!(sender, ALICE); assert_eq!(destination, EVM_ADDRESS.domain()); @@ -443,6 +456,22 @@ mod add_pool { #[test] fn with_wrong_pool() { + System::externalities().execute_with(|| { + Pools::mock_pool_exists(|_| false); + + assert_noop!( + LiquidityPools::add_pool( + RuntimeOrigin::signed(ALICE), + POOL_ID, + EVM_ADDRESS.domain(), + ), + Error::::PoolNotFound + ); + }) + } + + #[test] + fn with_wrong_permissions() { System::externalities().execute_with(|| { Pools::mock_pool_exists(|_| true); Permissions::mock_has(move |_, _, _| false); @@ -457,22 +486,126 @@ mod add_pool { ); }) } + } +} + +mod add_tranche { + use super::*; + + #[test] + fn success() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |scope, who, role| { + assert_eq!(who, ALICE); + assert!(matches!(scope, PermissionScope::Pool(POOL_ID))); + assert!(matches!(role, Role::PoolRole(PoolRole::PoolAdmin))); + true + }); + Pools::mock_pool_exists(|_| true); + Pools::mock_tranche_exists(|_, _| true); + AssetRegistry::mock_metadata(|_| Some(util::default_metadata())); + Gateway::mock_submit(|sender, destination, msg| { + assert_eq!(sender, ALICE); + assert_eq!(destination, EVM_ADDRESS.domain()); + assert_eq!( + msg, + Message::AddTranche { + pool_id: POOL_ID, + tranche_id: TRANCHE_ID, + token_name: vec_to_fixed_array(NAME), + token_symbol: vec_to_fixed_array(SYMBOL), + decimals: DECIMALS, + restriction_set: 1 + } + ); + Ok(()) + }); + + assert_ok!(LiquidityPools::add_tranche( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS.domain(), + )); + }) + } + + mod erroring_out_when { + use super::*; #[test] fn with_wrong_permissions() { System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| false); + + assert_noop!( + LiquidityPools::add_tranche( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS.domain(), + ), + Error::::NotPoolAdmin + ); + }) + } + + #[test] + fn with_wrong_pool() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); Pools::mock_pool_exists(|_| false); assert_noop!( - LiquidityPools::add_pool( + LiquidityPools::add_tranche( RuntimeOrigin::signed(ALICE), POOL_ID, + TRANCHE_ID, EVM_ADDRESS.domain(), ), Error::::PoolNotFound ); }) } + + #[test] + fn with_wrong_tranche() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + Pools::mock_pool_exists(|_| true); + Pools::mock_tranche_exists(|_, _| false); + + assert_noop!( + LiquidityPools::add_tranche( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS.domain(), + ), + Error::::TrancheNotFound, + ); + }) + } + + #[test] + fn with_no_metadata() { + System::externalities().execute_with(|| { + Permissions::mock_has(move |_, _, _| true); + Pools::mock_pool_exists(|_| true); + Pools::mock_tranche_exists(|_, _| true); + AssetRegistry::mock_metadata(|_| None); + + assert_noop!( + LiquidityPools::add_tranche( + RuntimeOrigin::signed(ALICE), + POOL_ID, + TRANCHE_ID, + EVM_ADDRESS.domain(), + ), + Error::::TrancheMetadataNotFound, + ); + }) + } } } diff --git a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs index f0d94c2a22..19c149badd 100644 --- a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs +++ b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs @@ -705,78 +705,6 @@ mod add_allow_upgrade { use super::*; - #[test_runtimes([development])] - fn add_tranche() { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::tokens::(vec![( - GLMR_CURRENCY_ID, - DEFAULT_BALANCE_GLMR, - )])) - .storage(), - ); - - setup_test(&mut env); - - env.parachain_state_mut(|| { - // Now create the pool - let pool_id = POOL_ID; - create_ausd_pool::(pool_id); - - // Verify we can't call pallet_liquidity_pools::Pallet::::add_tranche with a - // non-existing tranche_id - let nonexistent_tranche = [71u8; 16]; - - assert_noop!( - pallet_liquidity_pools::Pallet::::add_tranche( - RawOrigin::Signed(Keyring::Alice.into()).into(), - pool_id, - nonexistent_tranche, - Domain::EVM(MOONBEAM_EVM_CHAIN_ID), - ), - pallet_liquidity_pools::Error::::TrancheNotFound - ); - let tranche_id = default_tranche_id::(pool_id); - - // Verify ALICE can't call `add_tranche` given she is not the `PoolAdmin` - assert_noop!( - pallet_liquidity_pools::Pallet::::add_tranche( - RawOrigin::Signed(Keyring::Alice.into()).into(), - pool_id, - tranche_id, - Domain::EVM(MOONBEAM_EVM_CHAIN_ID), - ), - pallet_liquidity_pools::Error::::NotPoolAdmin - ); - - // Finally, verify we can call pallet_liquidity_pools::Pallet::::add_tranche - // successfully when called by the PoolAdmin with the right pool + tranche id - // pair. - assert_ok!(pallet_liquidity_pools::Pallet::::add_tranche( - RawOrigin::Signed(POOL_ADMIN.into()).into(), - pool_id, - tranche_id, - Domain::EVM(MOONBEAM_EVM_CHAIN_ID), - )); - - // Edge case: Should throw if tranche exists but metadata does not exist - let tranche_currency_id = CurrencyId::Tranche(pool_id, tranche_id); - - orml_asset_registry::Metadata::::remove(tranche_currency_id); - - assert_noop!( - pallet_liquidity_pools::Pallet::::update_tranche_token_metadata( - RawOrigin::Signed(POOL_ADMIN.into()).into(), - pool_id, - tranche_id, - Domain::EVM(MOONBEAM_EVM_CHAIN_ID), - ), - pallet_liquidity_pools::Error::::TrancheMetadataNotFound - ); - }); - } - #[test_runtimes([development])] fn update_member() { let mut env = FudgeEnv::::from_parachain_storage( From ebdebbd5744e0e8b9914cd9e92c5881d85c53999 Mon Sep 17 00:00:00 2001 From: lemunozm Date: Mon, 24 Jun 2024 20:44:56 +0200 Subject: [PATCH 14/17] check balance post transfers --- libs/types/src/domain_address.rs | 14 +++++++------- pallets/liquidity-pools/src/hooks.rs | 6 +++--- pallets/liquidity-pools/src/inbound.rs | 6 +++--- pallets/liquidity-pools/src/lib.rs | 6 +++--- pallets/liquidity-pools/src/tests.rs | 16 +++++++++++++--- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/libs/types/src/domain_address.rs b/libs/types/src/domain_address.rs index a9d738661a..f3a19eb094 100644 --- a/libs/types/src/domain_address.rs +++ b/libs/types/src/domain_address.rs @@ -15,7 +15,7 @@ use cfg_utils::{decode_be_bytes, vec_to_fixed_array}; use frame_support::pallet_prelude::RuntimeDebug; use parity_scale_codec::{Decode, Encode, Input, MaxEncodedLen}; use scale_info::TypeInfo; -use sp_runtime::traits::{AccountIdConversion, Convert}; +use sp_runtime::traits::AccountIdConversion; use sp_std::{vec, vec::Vec}; use crate::EVMChainId; @@ -63,12 +63,12 @@ impl Codec for Domain { } } -impl Convert for Domain -where - AccountId: Encode + Decode, -{ - fn convert(domain: Domain) -> AccountId { - DomainLocator { domain }.into_account_truncating() +impl Domain { + pub fn into_account(&self) -> AccountId { + DomainLocator { + domain: self.clone(), + } + .into_account_truncating() } } diff --git a/pallets/liquidity-pools/src/hooks.rs b/pallets/liquidity-pools/src/hooks.rs index fcf43a495c..50421af6ce 100644 --- a/pallets/liquidity-pools/src/hooks.rs +++ b/pallets/liquidity-pools/src/hooks.rs @@ -15,7 +15,7 @@ use cfg_traits::{ investments::TrancheCurrency, liquidity_pools::OutboundQueue, StatusNotificationHook, }; use cfg_types::{ - domain_address::{Domain, DomainAddress}, + domain_address::DomainAddress, investments::{ExecutedForeignCollect, ExecutedForeignDecreaseInvest}, }; use frame_support::{ @@ -26,7 +26,7 @@ use frame_support::{ transactional, }; use sp_core::Get; -use sp_runtime::{traits::Convert, DispatchError, DispatchResult}; +use sp_runtime::{DispatchError, DispatchResult}; use sp_std::marker::PhantomData; use crate::{pallet::Config, Message, MessageOf, Pallet}; @@ -141,7 +141,7 @@ where T::Tokens::transfer( investment_id.clone().into(), &investor, - &Domain::convert(domain_address.domain()), + &domain_address.domain().into_account(), status.amount_tranche_tokens_payout, Preservation::Expendable, )?; diff --git a/pallets/liquidity-pools/src/inbound.rs b/pallets/liquidity-pools/src/inbound.rs index 3386fddff4..185d04cbd4 100644 --- a/pallets/liquidity-pools/src/inbound.rs +++ b/pallets/liquidity-pools/src/inbound.rs @@ -81,7 +81,7 @@ where T::Tokens::transfer( invest_id.into(), - &Domain::convert(sending_domain), + &sending_domain.into_account(), &local_representation_of_receiver, amount, Preservation::Expendable, @@ -206,7 +206,7 @@ where // origination domain T::Tokens::transfer( invest_id.clone().into(), - &Domain::convert(sending_domain.domain()), + &sending_domain.domain().into_account(), &investor, amount, Preservation::Expendable, @@ -252,7 +252,7 @@ where T::Tokens::transfer( invest_id.clone().into(), &investor, - &Domain::convert(destination.domain()), + &destination.domain().into_account(), tranche_tokens_payout, Preservation::Expendable, )?; diff --git a/pallets/liquidity-pools/src/lib.rs b/pallets/liquidity-pools/src/lib.rs index c03021eb60..76d8c827b6 100644 --- a/pallets/liquidity-pools/src/lib.rs +++ b/pallets/liquidity-pools/src/lib.rs @@ -518,7 +518,7 @@ pub mod pallet { pool_id: T::PoolId, tranche_id: T::TrancheId, domain_address: DomainAddress, - amount: ::Balance, + amount: T::Balance, ) -> DispatchResult { let who = ensure_signed(origin.clone())?; @@ -545,7 +545,7 @@ pub mod pallet { T::Tokens::transfer( invest_id.into(), &who, - &Domain::convert(domain_address.domain()), + &domain_address.domain().into_account(), amount, // NOTE: Here, we allow death Preservation::Expendable, @@ -579,7 +579,7 @@ pub mod pallet { origin: OriginFor, currency_id: T::CurrencyId, receiver: DomainAddress, - amount: ::Balance, + amount: T::Balance, ) -> DispatchResult { let who = ensure_signed(origin.clone())?; diff --git a/pallets/liquidity-pools/src/tests.rs b/pallets/liquidity-pools/src/tests.rs index f4a72e73cf..439fe35362 100644 --- a/pallets/liquidity-pools/src/tests.rs +++ b/pallets/liquidity-pools/src/tests.rs @@ -8,7 +8,10 @@ use cfg_types::{ use cfg_utils::vec_to_fixed_array; use frame_support::{ assert_noop, assert_ok, - traits::{fungibles::Mutate as _, PalletInfo as _}, + traits::{ + fungibles::{Inspect as _, Mutate as _}, + PalletInfo as _, + }, }; use sp_runtime::{DispatchError, TokenError}; use staging_xcm::{ @@ -31,6 +34,7 @@ const NOW: Millis = 0; const NAME: &[u8] = b"Token name"; const SYMBOL: &[u8] = b"Token symbol"; const DECIMALS: u8 = 6; +const TRANCHE_CURRENCY: CurrencyId = CurrencyId::Tranche(POOL_ID, TRANCHE_ID); mod util { use super::*; @@ -109,6 +113,8 @@ mod transfer { EVM_ADDRESS, AMOUNT )); + + assert_eq!(Tokens::total_issuance(CURRENCY_ID), 0); }) } @@ -288,7 +294,7 @@ mod transfer_tranche_tokens { Pools::mock_pool_exists(|_| true); Pools::mock_tranche_exists(|_, _| true); TransferFilter::mock_check(|_| Ok(())); - Tokens::mint_into(CurrencyId::Tranche(POOL_ID, TRANCHE_ID), &ALICE, AMOUNT).unwrap(); + Tokens::mint_into(TRANCHE_CURRENCY, &ALICE, AMOUNT).unwrap(); Gateway::mock_submit(|sender, destination, msg| { assert_eq!(sender, ALICE); assert_eq!(destination, EVM_ADDRESS.domain()); @@ -312,7 +318,11 @@ mod transfer_tranche_tokens { TRANCHE_ID, EVM_ADDRESS, AMOUNT - ),); + )); + + let destination = EVM_ADDRESS.domain().into_account(); + assert_eq!(Tokens::balance(TRANCHE_CURRENCY, &ALICE), 0); + assert_eq!(Tokens::balance(TRANCHE_CURRENCY, &destination), AMOUNT); }) } From d35c3650ef05557b8aae2f2dd5090c95c931e73c Mon Sep 17 00:00:00 2001 From: lemunozm Date: Mon, 24 Jun 2024 21:08:42 +0200 Subject: [PATCH 15/17] fix lp tests --- .../src/generic/cases/liquidity_pools.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs index 19c149badd..08fb15bd73 100644 --- a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs +++ b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs @@ -525,7 +525,7 @@ mod utils { // are transferred from this account instead of minting assert_ok!(orml_tokens::Pallet::::mint_into( default_investment_id::().into(), - &Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()), + &DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(), amount )); @@ -1797,7 +1797,7 @@ mod foreign_investments { let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let sending_domain_locator = - Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()); + DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(); enable_liquidity_pool_transferability::(currency_id); // Create new pool @@ -1944,7 +1944,7 @@ mod foreign_investments { let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let sending_domain_locator = - Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()); + DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(); create_currency_pool::(pool_id, currency_id, currency_decimals.into()); do_initial_increase_investment::( pool_id, @@ -2194,7 +2194,7 @@ mod foreign_investments { // Increasing again should just bump redeeming amount assert_ok!(orml_tokens::Pallet::::mint_into( default_investment_id::().into(), - &Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()), + &DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(), amount )); let msg = LiquidityPoolMessage::IncreaseRedeemOrder { @@ -2231,7 +2231,7 @@ mod foreign_investments { let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let sending_domain_locator = - Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()); + DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(); // Create new pool create_currency_pool::(pool_id, currency_id, currency_decimals.into()); @@ -2349,7 +2349,7 @@ mod foreign_investments { let currency_id = AUSD_CURRENCY_ID; let currency_decimals = currency_decimals::AUSD; let sending_domain_locator = - Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()); + DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(); // Create new pool create_currency_pool::(pool_id, currency_id, currency_decimals.into()); @@ -3000,7 +3000,7 @@ mod foreign_investments { // Mint more into DomainLocator required for subsequent invest attempt assert_ok!(orml_tokens::Pallet::::mint_into( default_investment_id::().into(), - &Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()), + &DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(), 1, )); @@ -3170,7 +3170,7 @@ mod foreign_investments { enable_usdt_trading::(pool_currency, amount, true, true, true); assert_ok!(orml_tokens::Pallet::::mint_into( default_investment_id::().into(), - &Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()), + &DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(), amount, )); @@ -3252,7 +3252,7 @@ mod foreign_investments { enable_usdt_trading::(pool_currency, amount, true, true, true); assert_ok!(orml_tokens::Pallet::::mint_into( default_investment_id::().into(), - &Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()), + &DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(), amount, )); @@ -3315,7 +3315,7 @@ mod foreign_investments { let pool_currency_decimals = currency_decimals::AUSD; let invest_amount_pool_denominated: u128 = 6 * decimals(18); let sending_domain_locator = - Domain::convert(DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain()); + DEFAULT_DOMAIN_ADDRESS_MOONBEAM.domain().into_account(); let trader: AccountId = Keyring::Alice.into(); create_currency_pool::(pool_id, pool_currency, pool_currency_decimals.into()); From f870660a4e6308fc361f9dc1a9ee09111725b98d Mon Sep 17 00:00:00 2001 From: lemunozm Date: Mon, 24 Jun 2024 21:13:38 +0200 Subject: [PATCH 16/17] fix imports after rebasing --- .../src/generic/cases/liquidity_pools.rs | 10 ++-------- runtime/integration-tests/src/generic/utils/xcm.rs | 3 +-- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs index 08fb15bd73..b9da600a28 100644 --- a/runtime/integration-tests/src/generic/cases/liquidity_pools.rs +++ b/runtime/integration-tests/src/generic/cases/liquidity_pools.rs @@ -51,14 +51,8 @@ use crate::{ generic::{ config::Runtime, env::{Blocks, Env}, - envs::fudge_env::{ - handle::{FudgeHandle, SIBLING_ID}, - FudgeEnv, FudgeSupport, - }, - utils::{ - democracy::execute_via_democracy, genesis, genesis::Genesis, - xcm::enable_para_to_sibling_communication, - }, + envs::fudge_env::{handle::SIBLING_ID, FudgeEnv, FudgeSupport}, + utils::{genesis, genesis::Genesis, xcm::enable_para_to_sibling_communication}, }, utils::{accounts::Keyring, orml_asset_registry}, }; diff --git a/runtime/integration-tests/src/generic/utils/xcm.rs b/runtime/integration-tests/src/generic/utils/xcm.rs index 2ecc0b2a06..0380bf0ddf 100644 --- a/runtime/integration-tests/src/generic/utils/xcm.rs +++ b/runtime/integration-tests/src/generic/utils/xcm.rs @@ -14,10 +14,9 @@ use crate::generic::{ config::Runtime, env::{Blocks, Env}, envs::fudge_env::{ - handle::{FudgeHandle, PARA_ID, SIBLING_ID}, + handle::{PARA_ID, SIBLING_ID}, FudgeEnv, FudgeSupport, RelayRuntime, }, - utils::currency::default_metadata, }; pub fn enable_relay_to_para_communication(env: &mut FudgeEnv) { From c3a56ef4499980db91aede8b9df5f7733b343dcb Mon Sep 17 00:00:00 2001 From: lemunozm Date: Tue, 25 Jun 2024 08:28:27 +0200 Subject: [PATCH 17/17] fix taplo --- pallets/liquidity-pools/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/liquidity-pools/Cargo.toml b/pallets/liquidity-pools/Cargo.toml index a0191f014b..a5c8dfbf01 100644 --- a/pallets/liquidity-pools/Cargo.toml +++ b/pallets/liquidity-pools/Cargo.toml @@ -19,9 +19,9 @@ hex = { workspace = true } orml-traits = { workspace = true } parity-scale-codec = { workspace = true } scale-info = { workspace = true } +sp-core = { workspace = true } sp-runtime = { workspace = true } sp-std = { workspace = true } -sp-core = { workspace = true } staging-xcm = { workspace = true } # Our custom pallets @@ -31,9 +31,9 @@ cfg-types = { workspace = true } cfg-utils = { workspace = true } [dev-dependencies] +cfg-mocks = { workspace = true, default-features = true } orml-tokens = { workspace = true, default-features = true } sp-io = { workspace = true } -cfg-mocks = { workspace = true, default-features = true } [features] default = ["std"]