Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: switch deposit currency with deposit pallet #833

Merged
merged 7 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions pallets/pallet-bonded-coins/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub trait BenchmarkHelper<T: Config> {

/// Calculate the asset id for the bonded asset.
fn calculate_bonded_asset_id(seed: u32) -> FungiblesAssetIdOf<T>;

fn set_native_balance(account: &T::AccountId, amount: u128);
}

impl<T> BenchmarkHelper<T> for ()
Expand All @@ -57,6 +59,8 @@ where
fn calculate_bonded_asset_id(seed: u32) -> FungiblesAssetIdOf<T> {
seed.into()
}

fn set_native_balance(_account: &<T>::AccountId, _amount: u128) {}
}

fn get_square_root_curve<Float: FixedSigned>() -> Curve<Float> {
Expand Down Expand Up @@ -87,13 +91,12 @@ fn get_lmsr_curve_input<Float: FixedUnsigned>() -> CurveInput<Float> {
FungiblesBalanceOf<T>: Into<U256> + TryFrom<U256>,
T::Collaterals: Create<T::AccountId> ,
T::Fungibles: InspectRoles<T::AccountId> + AccountTouch<FungiblesAssetIdOf<T>, AccountIdOf<T>>,
T::DepositCurrency: Mutate<T::AccountId>,
T::Collaterals: MutateFungibles<T::AccountId>,
AccountIdLookupOf<T>: From<T::AccountId>,
)]
mod benchmarks {
use frame_support::traits::{
fungible::{Inspect, Mutate, MutateHold},
fungible::{Inspect, MutateHold},
fungibles::{Create, Destroy, Inspect as InspectFungibles, Mutate as MutateFungibles},
AccountTouch, EnsureOrigin, Get, OriginTrait,
};
Expand All @@ -104,8 +107,7 @@ mod benchmarks {
curves::Curve,
mock::*,
types::{Locks, PoolManagingTeam, PoolStatus},
AccountIdLookupOf, AccountIdOf, CollateralAssetIdOf, CurveParameterInputOf, HoldReason, PoolDetailsOf, Pools,
TokenMetaOf,
AccountIdLookupOf, AccountIdOf, CollateralAssetIdOf, CurveParameterInputOf, PoolDetailsOf, Pools, TokenMetaOf,
};

use super::*;
Expand Down Expand Up @@ -178,21 +180,15 @@ mod benchmarks {

// native currency

fn make_free_for_deposit<T: Config>(account: &AccountIdOf<T>)
where
T::DepositCurrency: Mutate<T::AccountId>,
{
fn make_free_for_deposit<T: Config>(account: &AccountIdOf<T>) {
let balance = <T::DepositCurrency as Inspect<AccountIdOf<T>>>::minimum_balance()
+ T::BaseDeposit::get().mul(1000u32.into())
+ T::DepositPerCurrency::get().mul(T::MaxCurrenciesPerPool::get().into());
set_native_balance::<T>(account, balance.saturated_into());
}

fn set_native_balance<T: Config>(account: &AccountIdOf<T>, amount: u128)
where
T::DepositCurrency: Mutate<T::AccountId>,
{
<T::DepositCurrency as Mutate<AccountIdOf<T>>>::set_balance(account, amount.saturated_into());
fn set_native_balance<T: Config>(account: &AccountIdOf<T>, amount: u128) {
T::BenchmarkHelper::set_native_balance(account, amount.saturated_into());
let balance = <T::DepositCurrency as Inspect<AccountIdOf<T>>>::balance(account);
assert_eq!(balance, amount.saturated_into());
}
Expand Down Expand Up @@ -795,8 +791,10 @@ mod benchmarks {

make_free_for_deposit::<T>(&owner);

let hold_reason = Pallet::<T>::calculate_hold_reason(&pool_id).expect("Generating HoldReason should not fail");

T::DepositCurrency::hold(
&T::RuntimeHoldReason::from(HoldReason::Deposit),
&hold_reason,
&owner,
Pallet::<T>::calculate_pool_deposit(bonded_currencies.len()),
)
Expand Down
24 changes: 16 additions & 8 deletions pallets/pallet-bonded-coins/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ pub mod pallet {
/// The type used for pool ids
type PoolId: Parameter + MaxEncodedLen + From<[u8; 32]> + Into<Self::AccountId>;

type RuntimeHoldReason: From<HoldReason>;
type RuntimeHoldReason: From<Self::HoldReason>;
type HoldReason: TryFrom<Self::PoolId>;

/// The type used for the curve parameters. This is the type used in the
/// calculation steps and stored in the pool details.
Expand Down Expand Up @@ -316,11 +317,6 @@ pub mod pallet {
ZeroCollateral,
}

#[pallet::composite_enum]
pub enum HoldReason {
Deposit,
}

#[pallet::call]
impl<T: Config> Pallet<T>
where
Expand Down Expand Up @@ -399,7 +395,8 @@ pub mod pallet {

let deposit_amount = Self::calculate_pool_deposit(currency_length);

T::DepositCurrency::hold(&T::RuntimeHoldReason::from(HoldReason::Deposit), &who, deposit_amount)?;
let hold_reason = Self::calculate_hold_reason(&pool_id)?;
T::DepositCurrency::hold(&hold_reason, &who, deposit_amount)?;

let pool_account = &pool_id.clone().into();

Expand Down Expand Up @@ -1280,8 +1277,9 @@ pub mod pallet {

Pools::<T>::remove(&pool_id);

let hold_reason = Self::calculate_hold_reason(&pool_id)?;
T::DepositCurrency::release(
&T::RuntimeHoldReason::from(HoldReason::Deposit),
&hold_reason,
&pool_details.owner,
pool_details.deposit,
WithdrawalPrecision::Exact,
Expand Down Expand Up @@ -1562,5 +1560,15 @@ pub mod pallet {
T::BaseDeposit::get()
.saturating_add(T::DepositPerCurrency::get().saturating_mul(n_currencies.saturated_into()))
}

/// Calculates the hold reason for a pool.
pub(crate) fn calculate_hold_reason(pool_id: &T::PoolId) -> Result<T::RuntimeHoldReason, Error<T>> {
let hold_reason = T::HoldReason::try_from(pool_id.to_owned()).map_err(|_| {
log::error!(target: LOG_TARGET, "Failed to convert pool ID into a valid hold reason.");
Error::<T>::Internal
})?;

Ok(T::RuntimeHoldReason::from(hold_reason))
}
}
}
50 changes: 44 additions & 6 deletions pallets/pallet-bonded-coins/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,22 @@ pub mod runtime {
use frame_support::{
pallet_prelude::*,
parameter_types, storage_alias,
traits::{fungible::hold::Mutate, ConstU128, ConstU32, PalletInfoAccess},
traits::{fungible::hold::Mutate as MutateHold, ConstU128, ConstU32, PalletInfoAccess, VariantCount},
weights::constants::RocksDbWeight,
};
use frame_system::{EnsureRoot, EnsureSigned};
use sp_core::U256;
use sp_runtime::{
traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Verify},
ArithmeticError, BoundedVec, BuildStorage, DispatchError, MultiSignature, Permill,
AccountId32, ArithmeticError, BoundedVec, BuildStorage, DispatchError, MultiSignature, Permill,
};
use substrate_fixed::types::{I75F53, U75F53};

use crate::{
self as pallet_bonded_coins,
traits::NextAssetIds,
types::{Locks, PoolStatus},
Config, DepositBalanceOf, FungiblesAssetIdOf, HoldReason, PoolDetailsOf,
Config, DepositBalanceOf, FungiblesAssetIdOf, PoolDetailsOf,
};

pub type Hash = sp_core::H256;
Expand Down Expand Up @@ -200,6 +200,15 @@ pub mod runtime {
}
);

#[derive(Default, Clone, Copy, Encode, Decode, MaxEncodedLen, TypeInfo, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum TestRuntimeHoldReason {
#[default]
Deposit,
}
impl VariantCount for TestRuntimeHoldReason {
const VARIANT_COUNT: u32 = 1;
}

parameter_types! {
pub const SS58Prefix: u8 = 38;
pub const BlockHashCount: u64 = 250;
Expand Down Expand Up @@ -250,7 +259,7 @@ pub mod runtime {
type ReserveIdentifier = [u8; 8];
type RuntimeEvent = RuntimeEvent;
type RuntimeFreezeReason = ();
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeHoldReason = TestRuntimeHoldReason;
type WeightInfo = ();
}

Expand Down Expand Up @@ -288,6 +297,32 @@ pub mod runtime {
pub const MaxDenomination: u8 = 15;
}

impl From<AccountId32> for TestRuntimeHoldReason {
fn from(_value: AccountId32) -> Self {
Self::Deposit
}
}

#[cfg(feature = "runtime-benchmarks")]
struct BenchmarkHelper;

#[cfg(feature = "runtime-benchmarks")]
impl crate::BenchmarkHelper<Test> for BenchmarkHelper {
fn calculate_bonded_asset_id(seed: u32) -> FungiblesAssetIdOf<Test> {
seed
}

fn calculate_collateral_asset_id(seed: u32) -> crate::CollateralAssetIdOf<Test> {
seed
}

fn set_native_balance(who: &AccountId, amount: DepositBalanceOf<Test>) {
use frame_support::traits::fungible::Mutate;

Balances::set_balance(who, amount);
}
}

impl pallet_bonded_coins::Config for Test {
type BaseDeposit = ExistentialDeposit;
type Collaterals = Assets;
Expand All @@ -298,14 +333,15 @@ pub mod runtime {
type DepositPerCurrency = CurrencyDeposit;
type ForceOrigin = EnsureRoot<AccountId>;
type Fungibles = Assets;
type HoldReason = Self::PoolId;
type MaxCurrenciesPerPool = MaxCurrenciesPerPool;
type MaxDenomination = MaxDenomination;
type MaxStringInputLength = StringLimit;
type NextAssetIds = NextAssetIdGenerator;
type PoolCreateOrigin = EnsureSigned<AccountId>;
type PoolId = AccountId;
type RuntimeEvent = RuntimeEvent;
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeHoldReason = TestRuntimeHoldReason;
type WeightInfo = ();

#[cfg(feature = "runtime-benchmarks")]
Expand Down Expand Up @@ -400,8 +436,10 @@ pub mod runtime {
System::set_block_number(System::block_number() + 1);

self.pools.into_iter().for_each(|(pool_id, pool)| {
let hold_reason =
BondingPallet::calculate_hold_reason(&pool_id).expect("Creating hold reason should not fail.");
<Test as crate::Config>::DepositCurrency::hold(
&HoldReason::Deposit.into(),
&hold_reason,
&pool.owner,
BondingPallet::calculate_pool_deposit(pool.bonded_currencies.len()),
)
Expand Down
10 changes: 7 additions & 3 deletions pallets/pallet-bonded-coins/src/try_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use frame_support::traits::{
use sp_runtime::{traits::Zero, TryRuntimeError};
use sp_std::vec::Vec;

use crate::{types::PoolDetails, Config, FungiblesAssetIdOf, HoldReason, Pools};
use crate::{types::PoolDetails, Config, FungiblesAssetIdOf, Pools};

pub(crate) fn do_try_state<T: Config>() -> Result<(), TryRuntimeError> {
// checked currency ids. Each Currency should only be associated with one pool.
Expand All @@ -22,10 +22,14 @@ pub(crate) fn do_try_state<T: Config>() -> Result<(), TryRuntimeError> {
..
} = pool_details;

let pool_account = pool_id.into();
let pool_account = pool_id.clone().into();

let hold_reason = T::HoldReason::try_from(pool_id)
.map_err(|_| TryRuntimeError::Other("Failed to convert pool_id to HoldReason"))
.map(T::RuntimeHoldReason::from)?;

// Deposit checks
let balance_on_hold_user = T::DepositCurrency::balance_on_hold(&HoldReason::Deposit.into(), &owner);
let balance_on_hold_user = T::DepositCurrency::balance_on_hold(&hold_reason, &owner);
assert!(balance_on_hold_user >= deposit);

// Collateral checks
Expand Down
6 changes: 6 additions & 0 deletions pallets/pallet-deposit-storage/src/fungible/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ pub struct PalletDepositStorageReason<Namespace, Key> {
pub(crate) key: Key,
}

impl<Namespace, Key> PalletDepositStorageReason<Namespace, Key> {
pub const fn new(namespace: Namespace, key: Key) -> Self {
Self { namespace, key }
}
}

impl<Namespace, Key> From<PalletDepositStorageReason<Namespace, Key>> for HoldReason {
fn from(_value: PalletDepositStorageReason<Namespace, Key>) -> Self {
// All the deposits ever taken like this will count towards the same hold
Expand Down
53 changes: 53 additions & 0 deletions runtimes/common/src/deposits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// KILT Blockchain – https://botlabs.org
// Copyright (C) 2019-2024 BOTLabs GmbH

// The KILT Blockchain 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.

// The KILT Blockchain 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.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

// If you feel like getting in touch with us, you can do so at [email protected]

// The `RuntimeDebug` macro uses these internally.
#![allow(clippy::ref_patterns)]

use pallet_dip_provider::IdentityCommitmentVersion;
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::RuntimeDebug;

use crate::DidIdentifier;

#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Clone, PartialEq, Eq, RuntimeDebug)]
pub enum DepositNamespace {
DipProvider,
BondedTokens,
}

#[cfg(feature = "runtime-benchmarks")]
impl Default for DepositNamespace {
fn default() -> Self {
Self::DipProvider
}
}

/// The various different keys that can be stored in the storage-tracking
/// pallet.
/// Although the namespace is used to distinguish between keys, it is useful to
/// group all keys under the same enum to calculate the maximum length that a
/// key can take.
#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Clone, PartialEq, Eq, RuntimeDebug)]
pub enum DepositKey {
DipProvider {
identifier: DidIdentifier,
version: IdentityCommitmentVersion,
},
}
Loading
Loading