From 60e9add23d13fb680cef7fc8f9522bac59e27765 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Mon, 20 Nov 2023 16:40:23 +0100 Subject: [PATCH] chore: use fungibles + add pool currency id --- Cargo.lock | 1 + libs/types/src/investments.rs | 20 +++- runtime/altair/src/lib.rs | 4 +- runtime/centrifuge/src/lib.rs | 4 +- runtime/common/Cargo.toml | 4 + runtime/common/src/lib.rs | 108 ++++++++++++------ runtime/development/src/lib.rs | 4 +- .../src/generic/cases/investments.rs | 21 ++-- .../integration-tests/src/generic/config.rs | 2 +- 9 files changed, 113 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d42b85eb2..3b99ac1256 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11408,6 +11408,7 @@ dependencies = [ "pallet-liquidity-pools-gateway", "pallet-loans", "pallet-pool-system", + "pallet-restricted-tokens", "pallet-treasury", "parachain-info", "parity-scale-codec 3.6.5", diff --git a/libs/types/src/investments.rs b/libs/types/src/investments.rs index 18604ed2c6..85a3b1b42e 100644 --- a/libs/types/src/investments.rs +++ b/libs/types/src/investments.rs @@ -244,14 +244,16 @@ pub struct ExecutedForeignCollect { /// claimable pool currency as well as tranche tokens. #[derive(Encode, Decode, Default, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct InvestmentPortfolio { +pub struct InvestmentPortfolio { + /// The identifier of the pool currency + pub pool_currency_id: CurrencyId, /// The unprocessed invest order amount in pool currency pub pending_invest_currency: Balance, /// The amount of tranche tokens which can be collected for an invest order pub claimable_tranche_tokens: Balance, /// The amount of tranche tokens which can be transferred pub free_tranche_tokens: Balance, - /// The amount of tranche tokens which can not be used at all and get + /// The amount of tranche tokens which can not be used at all and could get /// slashed pub reserved_tranche_tokens: Balance, /// The unprocessed redeem order amount in tranche tokens @@ -260,9 +262,17 @@ pub struct InvestmentPortfolio { pub claimable_currency: Balance, } -impl InvestmentPortfolio { - pub fn new() -> Self { - Default::default() +impl InvestmentPortfolio { + pub fn new(pool_currency_id: CurrencyId) -> Self { + Self { + pool_currency_id, + pending_invest_currency: Balance::default(), + claimable_tranche_tokens: Balance::default(), + free_tranche_tokens: Balance::default(), + reserved_tranche_tokens: Balance::default(), + pending_redeem_tranche_tokens: Balance::default(), + claimable_currency: Balance::default(), + } } pub fn with_pending_invest_currency(mut self, amount: Balance) -> Self { diff --git a/runtime/altair/src/lib.rs b/runtime/altair/src/lib.rs index db15223cf6..d8e0b62f98 100644 --- a/runtime/altair/src/lib.rs +++ b/runtime/altair/src/lib.rs @@ -2165,8 +2165,8 @@ impl_runtime_apis! { // Investment Runtime APIs - impl runtime_common::apis::InvestmentsApi> for Runtime { - fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio)> { + impl runtime_common::apis::InvestmentsApi> for Runtime { + fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio)> { runtime_common::investment_portfolios::get_account_portfolio::(account_id) } } diff --git a/runtime/centrifuge/src/lib.rs b/runtime/centrifuge/src/lib.rs index dfa10fa83f..37787deb79 100644 --- a/runtime/centrifuge/src/lib.rs +++ b/runtime/centrifuge/src/lib.rs @@ -2202,8 +2202,8 @@ impl_runtime_apis! { } // Investment Runtime APIs - impl runtime_common::apis::InvestmentsApi> for Runtime { - fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio)> { + impl runtime_common::apis::InvestmentsApi> for Runtime { + fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio)> { runtime_common::investment_portfolios::get_account_portfolio::(account_id) } } diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index d1b5893e99..7c2542b97c 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -71,6 +71,7 @@ pallet-liquidity-pools = { path = "../../pallets/liquidity-pools", default-featu pallet-liquidity-pools-gateway = { path = "../../pallets/liquidity-pools-gateway", default-features = false } pallet-loans = { path = "../../pallets/loans", default-features = false } pallet-pool-system = { path = "../../pallets/pool-system", default-features = false } +pallet-restricted-tokens = { path = "../../pallets/restricted-tokens", default-features = false } # Used for migrations log = "0.4" @@ -119,6 +120,7 @@ std = [ "pallet-liquidity-pools/std", "pallet-loans/std", "pallet-pool-system/std", + "pallet-restricted-tokens/std", "pallet-treasury/std", "parachain-info/std", "polkadot-parachain/std", @@ -156,6 +158,7 @@ runtime-benchmarks = [ "pallet-liquidity-pools/runtime-benchmarks", "pallet-loans/runtime-benchmarks", "pallet-pool-system/runtime-benchmarks", + "pallet-restricted-tokens/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "polkadot-parachain/runtime-benchmarks", "sp-runtime/runtime-benchmarks", @@ -193,6 +196,7 @@ try-runtime = [ "pallet-liquidity-pools/try-runtime", "pallet-loans/try-runtime", "pallet-pool-system/try-runtime", + "pallet-restricted-tokens/try-runtime", "pallet-treasury/try-runtime", "parachain-info/try-runtime", "sp-runtime/try-runtime", diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index dd1a3825be..097fff8002 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -378,6 +378,10 @@ pub mod investment_portfolios { PoolInspect, Seconds, }; use cfg_types::{investments::InvestmentPortfolio, tokens::CurrencyId}; + use frame_support::traits::{ + fungibles, + tokens::{Fortitude, Preservation}, + }; use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; /// Get the PoolId, CurrencyId, InvestmentId, and Balance for all @@ -390,18 +394,26 @@ pub mod investment_portfolios { investor: ::AccountId, ) -> Vec<( ::InvestmentId, - InvestmentPortfolio, + InvestmentPortfolio, )> where - T: frame_system::Config + pallet_investments::Config + orml_tokens::Config, - ::InvestmentId: - TrancheCurrency + Into<::CurrencyId> + Ord, - CurrencyId: From<::CurrencyId>, + T: frame_system::Config + + pallet_investments::Config + + orml_tokens::Config + + pallet_restricted_tokens::Config, + ::InvestmentId: TrancheCurrency + + Into<::CurrencyId> + + Ord + + Into<::CurrencyId>, + CurrencyId: From<::CurrencyId> + + From<::CurrencyId>, + ::CurrencyId: + From<::CurrencyId>, Balance: From<::Amount> - + From<::Balance>, + + From<::Balance>, PoolInspector: PoolInspect< ::AccountId, - ::CurrencyId, + ::CurrencyId, PoolId = PoolId, TrancheId = TrancheId, Moment = Seconds, @@ -409,29 +421,46 @@ pub mod investment_portfolios { { let mut portfolio = BTreeMap::< ::InvestmentId, - InvestmentPortfolio, + InvestmentPortfolio, >::new(); // Denote current tranche token balances before dry running collecting orml_tokens::Accounts::::iter_key_prefix(&investor).for_each(|currency| { if let CurrencyId::Tranche(pool_id, tranche_id) = CurrencyId::from(currency) { - let balance = orml_tokens::Accounts::::get(&investor, currency); + let pool_currency = PoolInspector::currency_for(pool_id) + .expect("Pool must exist; qed") + .into(); + let free_balance = as fungibles::Inspect< + T::AccountId, + >>::reducible_balance( + currency.into(), + &investor, + Preservation::Preserve, + Fortitude::Polite, + ); + let reserved_balance = as fungibles::InspectHold< + T::AccountId, + >>::balance_on_hold(currency.into(), &(), &investor); + portfolio .entry(TrancheCurrency::generate(pool_id, tranche_id)) .and_modify(|p| { - p.free_tranche_tokens = balance.free.into(); - p.reserved_tranche_tokens = balance.reserved.into(); + p.free_tranche_tokens = free_balance.into(); + p.reserved_tranche_tokens = reserved_balance.into(); }) .or_insert( - InvestmentPortfolio::::new() - .with_free_tranche_tokens(balance.free.into()) - .with_reserved_tranche_tokens(balance.reserved.into()), + InvestmentPortfolio::::new(pool_currency) + .with_free_tranche_tokens(free_balance.into()) + .with_reserved_tranche_tokens(reserved_balance.into()), ); } }); // Set pending invest currency and claimable tranche tokens pallet_investments::InvestOrders::::iter_key_prefix(&investor).for_each(|invest_id| { + let pool_currency = + PoolInspector::currency_for(invest_id.of_pool()).expect("Pool must exist; qed"); + // Collect such that we can determine claimable tranche tokens // NOTE: Does not modify storage since RtAPI is readonly let _ = @@ -439,10 +468,14 @@ pub mod investment_portfolios { let amount = pallet_investments::InvestOrders::::get(&investor, invest_id) .map(|order| order.amount()) .unwrap_or_default(); - let free_tranche_tokens_new = - orml_tokens::Accounts::::get(&investor, invest_id.into()) - .free - .into(); + let free_tranche_tokens_new: Balance = as fungibles::Inspect< + T::AccountId, + >>::reducible_balance( + invest_id.into(), + &investor, + Preservation::Preserve, + Fortitude::Polite, + ).into(); portfolio .entry(invest_id) @@ -454,7 +487,7 @@ pub mod investment_portfolios { } }) .or_insert( - InvestmentPortfolio::::new() + InvestmentPortfolio::::new(pool_currency.into()) .with_pending_invest_currency(amount.into()) .with_claimable_tranche_tokens(free_tranche_tokens_new), ); @@ -462,14 +495,17 @@ pub mod investment_portfolios { // Set pending tranche tokens and claimable invest currency pallet_investments::RedeemOrders::::iter_key_prefix(&investor).for_each(|invest_id| { - let pool_currency = PoolInspector::currency_for(invest_id.of_pool()); - let balance_before: Balance = pool_currency - .map(|p_currency| { - orml_tokens::Accounts::::get(&investor, p_currency) - .free - .into() - }) - .unwrap_or_default(); + let pool_currency = + PoolInspector::currency_for(invest_id.of_pool()).expect("Pool must exist; qed"); + let balance_before: Balance = + as fungibles::Inspect< + T::AccountId, + >>::reducible_balance( + pool_currency, + &investor, + Preservation::Preserve, + Fortitude::Polite, + ).into(); // Collect such that we can determine claimable invest currency // NOTE: Does not modify storage since RtAPI is readonly @@ -478,13 +514,15 @@ pub mod investment_portfolios { let amount = pallet_investments::RedeemOrders::::get(&investor, invest_id) .map(|order| order.amount()) .unwrap_or_default(); - let balance_after: Balance = pool_currency - .map(|p_currency| { - orml_tokens::Accounts::::get(&investor, p_currency) - .free - .into() - }) - .unwrap_or_default(); + let balance_after: Balance = + as fungibles::Inspect< + T::AccountId, + >>::reducible_balance( + pool_currency, + &investor, + Preservation::Preserve, + Fortitude::Polite, + ).into(); portfolio .entry(invest_id) @@ -495,7 +533,7 @@ pub mod investment_portfolios { } }) .or_insert( - InvestmentPortfolio::::new() + InvestmentPortfolio::::new(pool_currency.into()) .with_pending_redeem_tranche_tokens(amount.into()) .with_claimable_currency(balance_after), ); diff --git a/runtime/development/src/lib.rs b/runtime/development/src/lib.rs index 7269b6f376..19e314dd37 100644 --- a/runtime/development/src/lib.rs +++ b/runtime/development/src/lib.rs @@ -2295,8 +2295,8 @@ impl_runtime_apis! { } // Investment Runtime APIs - impl runtime_common::apis::InvestmentsApi> for Runtime { - fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio)> { + impl runtime_common::apis::InvestmentsApi> for Runtime { + fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio)> { runtime_common::investment_portfolios::get_account_portfolio::(account_id) } } diff --git a/runtime/integration-tests/src/generic/cases/investments.rs b/runtime/integration-tests/src/generic/cases/investments.rs index be4546c604..dd559a9517 100644 --- a/runtime/integration-tests/src/generic/cases/investments.rs +++ b/runtime/integration-tests/src/generic/cases/investments.rs @@ -1,6 +1,10 @@ use cfg_primitives::{AccountId, Balance, PoolId}; use cfg_traits::{investments::TrancheCurrency as _, Seconds}; -use cfg_types::{investments::InvestmentPortfolio, permissions::PoolRole, tokens::TrancheCurrency}; +use cfg_types::{ + investments::InvestmentPortfolio, + permissions::PoolRole, + tokens::{CurrencyId, TrancheCurrency}, +}; use frame_support::traits::fungibles::MutateHold; use runtime_common::apis::{ runtime_decl_for_investments_api::InvestmentsApiV1, runtime_decl_for_pools_api::PoolsApiV1, @@ -84,7 +88,7 @@ fn investment_portfolio_single_tranche() { investment_portfolio, vec![( invest_id, - InvestmentPortfolio::::new() + InvestmentPortfolio::::new(Usd6::ID) .with_pending_invest_currency(EXPECTED_POOL_BALANCE) )] ); @@ -99,7 +103,7 @@ fn investment_portfolio_single_tranche() { investment_portfolio, vec![( invest_id, - InvestmentPortfolio::::new() + InvestmentPortfolio::::new(Usd6::ID) .with_claimable_tranche_tokens(EXPECTED_POOL_BALANCE) )] ); @@ -113,7 +117,8 @@ fn investment_portfolio_single_tranche() { investment_portfolio, vec![( invest_id, - InvestmentPortfolio::::new().with_free_tranche_tokens(EXPECTED_POOL_BALANCE) + InvestmentPortfolio::::new(Usd6::ID) + .with_free_tranche_tokens(EXPECTED_POOL_BALANCE) )] ); @@ -126,7 +131,7 @@ fn investment_portfolio_single_tranche() { investment_portfolio, vec![( invest_id, - InvestmentPortfolio::::new() + InvestmentPortfolio::::new(Usd6::ID) .with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT) .with_pending_redeem_tranche_tokens(REDEEM_AMOUNT) )] @@ -142,7 +147,7 @@ fn investment_portfolio_single_tranche() { investment_portfolio, vec![( invest_id, - InvestmentPortfolio::::new() + InvestmentPortfolio::::new(Usd6::ID) .with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT) .with_claimable_currency(REDEEM_AMOUNT) )] @@ -157,7 +162,7 @@ fn investment_portfolio_single_tranche() { investment_portfolio, vec![( invest_id, - InvestmentPortfolio::::new() + InvestmentPortfolio::::new(Usd6::ID) .with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT) )] ); @@ -177,7 +182,7 @@ fn investment_portfolio_single_tranche() { investment_portfolio, vec![( invest_id, - InvestmentPortfolio::::new() + InvestmentPortfolio::::new(Usd6::ID) .with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT - HOLD_AMOUNT) .with_reserved_tranche_tokens(HOLD_AMOUNT) )] diff --git a/runtime/integration-tests/src/generic/config.rs b/runtime/integration-tests/src/generic/config.rs index 7a68e129b8..635b477931 100644 --- a/runtime/integration-tests/src/generic/config.rs +++ b/runtime/integration-tests/src/generic/config.rs @@ -177,7 +177,7 @@ pub trait Runtime: Self::Block, AccountId, TrancheCurrency, - InvestmentPortfolio, + InvestmentPortfolio, >; type MaxTranchesExt: Codec + Get + Member + PartialOrd + TypeInfo;