Skip to content

Commit

Permalink
chore: use fungibles + add pool currency id
Browse files Browse the repository at this point in the history
  • Loading branch information
wischli committed Nov 20, 2023
1 parent 1f109ee commit 60e9add
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 55 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

20 changes: 15 additions & 5 deletions libs/types/src/investments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,14 +244,16 @@ pub struct ExecutedForeignCollect<Balance, Currency> {
/// claimable pool currency as well as tranche tokens.
#[derive(Encode, Decode, Default, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)]

pub struct InvestmentPortfolio<Balance> {
pub struct InvestmentPortfolio<Balance, CurrencyId> {
/// 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
Expand All @@ -260,9 +262,17 @@ pub struct InvestmentPortfolio<Balance> {
pub claimable_currency: Balance,
}

impl<Balance: Default> InvestmentPortfolio<Balance> {
pub fn new() -> Self {
Default::default()
impl<Balance: Default, CurrencyId> InvestmentPortfolio<Balance, CurrencyId> {
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 {
Expand Down
4 changes: 2 additions & 2 deletions runtime/altair/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2165,8 +2165,8 @@ impl_runtime_apis! {


// Investment Runtime APIs
impl runtime_common::apis::InvestmentsApi<Block, AccountId, TrancheCurrency, InvestmentPortfolio<Balance>> for Runtime {
fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio<Balance>)> {
impl runtime_common::apis::InvestmentsApi<Block, AccountId, TrancheCurrency, InvestmentPortfolio<Balance, CurrencyId>> for Runtime {
fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio<Balance, CurrencyId>)> {
runtime_common::investment_portfolios::get_account_portfolio::<Runtime, PoolSystem>(account_id)
}
}
Expand Down
4 changes: 2 additions & 2 deletions runtime/centrifuge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2202,8 +2202,8 @@ impl_runtime_apis! {
}

// Investment Runtime APIs
impl runtime_common::apis::InvestmentsApi<Block, AccountId, TrancheCurrency, InvestmentPortfolio<Balance>> for Runtime {
fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio<Balance>)> {
impl runtime_common::apis::InvestmentsApi<Block, AccountId, TrancheCurrency, InvestmentPortfolio<Balance, CurrencyId>> for Runtime {
fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio<Balance, CurrencyId>)> {
runtime_common::investment_portfolios::get_account_portfolio::<Runtime, PoolSystem>(account_id)
}
}
Expand Down
4 changes: 4 additions & 0 deletions runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
108 changes: 73 additions & 35 deletions runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -390,59 +394,88 @@ pub mod investment_portfolios {
investor: <T as frame_system::Config>::AccountId,
) -> Vec<(
<T as pallet_investments::Config>::InvestmentId,
InvestmentPortfolio<Balance>,
InvestmentPortfolio<Balance, CurrencyId>,
)>
where
T: frame_system::Config + pallet_investments::Config + orml_tokens::Config,
<T as pallet_investments::Config>::InvestmentId:
TrancheCurrency<PoolId, TrancheId> + Into<<T as orml_tokens::Config>::CurrencyId> + Ord,
CurrencyId: From<<T as orml_tokens::Config>::CurrencyId>,
T: frame_system::Config
+ pallet_investments::Config
+ orml_tokens::Config
+ pallet_restricted_tokens::Config,
<T as pallet_investments::Config>::InvestmentId: TrancheCurrency<PoolId, TrancheId>
+ Into<<T as orml_tokens::Config>::CurrencyId>
+ Ord
+ Into<<T as pallet_restricted_tokens::Config>::CurrencyId>,
CurrencyId: From<<T as orml_tokens::Config>::CurrencyId>
+ From<<T as pallet_restricted_tokens::Config>::CurrencyId>,
<T as pallet_restricted_tokens::Config>::CurrencyId:
From<<T as orml_tokens::Config>::CurrencyId>,
Balance: From<<T as pallet_investments::Config>::Amount>
+ From<<T as orml_tokens::Config>::Balance>,
+ From<<T as pallet_restricted_tokens::Config>::Balance>,
PoolInspector: PoolInspect<
<T as frame_system::Config>::AccountId,
<T as orml_tokens::Config>::CurrencyId,
<T as pallet_restricted_tokens::Config>::CurrencyId,
PoolId = PoolId,
TrancheId = TrancheId,
Moment = Seconds,
>,
{
let mut portfolio = BTreeMap::<
<T as pallet_investments::Config>::InvestmentId,
InvestmentPortfolio<Balance>,
InvestmentPortfolio<Balance, CurrencyId>,
>::new();

// Denote current tranche token balances before dry running collecting
orml_tokens::Accounts::<T>::iter_key_prefix(&investor).for_each(|currency| {
if let CurrencyId::Tranche(pool_id, tranche_id) = CurrencyId::from(currency) {
let balance = orml_tokens::Accounts::<T>::get(&investor, currency);
let pool_currency = PoolInspector::currency_for(pool_id)
.expect("Pool must exist; qed")
.into();
let free_balance = <pallet_restricted_tokens::Pallet<T> as fungibles::Inspect<
T::AccountId,
>>::reducible_balance(
currency.into(),
&investor,
Preservation::Preserve,
Fortitude::Polite,
);
let reserved_balance = <pallet_restricted_tokens::Pallet<T> 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::<Balance>::new()
.with_free_tranche_tokens(balance.free.into())
.with_reserved_tranche_tokens(balance.reserved.into()),
InvestmentPortfolio::<Balance, CurrencyId>::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::<T>::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 _ =
pallet_investments::Pallet::<T>::collect_investment(investor.clone(), invest_id);
let amount = pallet_investments::InvestOrders::<T>::get(&investor, invest_id)
.map(|order| order.amount())
.unwrap_or_default();
let free_tranche_tokens_new =
orml_tokens::Accounts::<T>::get(&investor, invest_id.into())
.free
.into();
let free_tranche_tokens_new: Balance = <pallet_restricted_tokens::Pallet<T> as fungibles::Inspect<
T::AccountId,
>>::reducible_balance(
invest_id.into(),
&investor,
Preservation::Preserve,
Fortitude::Polite,
).into();

portfolio
.entry(invest_id)
Expand All @@ -454,22 +487,25 @@ pub mod investment_portfolios {
}
})
.or_insert(
InvestmentPortfolio::<Balance>::new()
InvestmentPortfolio::<Balance, CurrencyId>::new(pool_currency.into())
.with_pending_invest_currency(amount.into())
.with_claimable_tranche_tokens(free_tranche_tokens_new),
);
});

// Set pending tranche tokens and claimable invest currency
pallet_investments::RedeemOrders::<T>::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::<T>::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 =
<pallet_restricted_tokens::Pallet<T> 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
Expand All @@ -478,13 +514,15 @@ pub mod investment_portfolios {
let amount = pallet_investments::RedeemOrders::<T>::get(&investor, invest_id)
.map(|order| order.amount())
.unwrap_or_default();
let balance_after: Balance = pool_currency
.map(|p_currency| {
orml_tokens::Accounts::<T>::get(&investor, p_currency)
.free
.into()
})
.unwrap_or_default();
let balance_after: Balance =
<pallet_restricted_tokens::Pallet<T> as fungibles::Inspect<
T::AccountId,
>>::reducible_balance(
pool_currency,
&investor,
Preservation::Preserve,
Fortitude::Polite,
).into();

portfolio
.entry(invest_id)
Expand All @@ -495,7 +533,7 @@ pub mod investment_portfolios {
}
})
.or_insert(
InvestmentPortfolio::<Balance>::new()
InvestmentPortfolio::<Balance, CurrencyId>::new(pool_currency.into())
.with_pending_redeem_tranche_tokens(amount.into())
.with_claimable_currency(balance_after),
);
Expand Down
4 changes: 2 additions & 2 deletions runtime/development/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2295,8 +2295,8 @@ impl_runtime_apis! {
}

// Investment Runtime APIs
impl runtime_common::apis::InvestmentsApi<Block, AccountId, TrancheCurrency, InvestmentPortfolio<Balance>> for Runtime {
fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio<Balance>)> {
impl runtime_common::apis::InvestmentsApi<Block, AccountId, TrancheCurrency, InvestmentPortfolio<Balance, CurrencyId>> for Runtime {
fn investment_portfolio(account_id: AccountId) -> Vec<(TrancheCurrency, InvestmentPortfolio<Balance, CurrencyId>)> {
runtime_common::investment_portfolios::get_account_portfolio::<Runtime, PoolSystem>(account_id)
}
}
Expand Down
21 changes: 13 additions & 8 deletions runtime/integration-tests/src/generic/cases/investments.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -84,7 +88,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance>::new()
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
.with_pending_invest_currency(EXPECTED_POOL_BALANCE)
)]
);
Expand All @@ -99,7 +103,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance>::new()
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
.with_claimable_tranche_tokens(EXPECTED_POOL_BALANCE)
)]
);
Expand All @@ -113,7 +117,8 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance>::new().with_free_tranche_tokens(EXPECTED_POOL_BALANCE)
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE)
)]
);

Expand All @@ -126,7 +131,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance>::new()
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT)
.with_pending_redeem_tranche_tokens(REDEEM_AMOUNT)
)]
Expand All @@ -142,7 +147,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance>::new()
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT)
.with_claimable_currency(REDEEM_AMOUNT)
)]
Expand All @@ -157,7 +162,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance>::new()
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT)
)]
);
Expand All @@ -177,7 +182,7 @@ fn investment_portfolio_single_tranche<T: Runtime>() {
investment_portfolio,
vec![(
invest_id,
InvestmentPortfolio::<Balance>::new()
InvestmentPortfolio::<Balance, CurrencyId>::new(Usd6::ID)
.with_free_tranche_tokens(EXPECTED_POOL_BALANCE - REDEEM_AMOUNT - HOLD_AMOUNT)
.with_reserved_tranche_tokens(HOLD_AMOUNT)
)]
Expand Down
2 changes: 1 addition & 1 deletion runtime/integration-tests/src/generic/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ pub trait Runtime:
Self::Block,
AccountId,
TrancheCurrency,
InvestmentPortfolio<Balance>,
InvestmentPortfolio<Balance, CurrencyId>,
>;

type MaxTranchesExt: Codec + Get<u32> + Member + PartialOrd + TypeInfo;
Expand Down

0 comments on commit 60e9add

Please sign in to comment.