From 59622fb1aacd3fbfb4563c21b34ae08047d117a7 Mon Sep 17 00:00:00 2001 From: Juan Ignacio Rios Date: Wed, 18 Sep 2024 12:25:17 +0200 Subject: [PATCH] pallet funding OTM integration --- Cargo.lock | 38 ++++---- Cargo.toml | 1 + pallets/funding/Cargo.toml | 4 + pallets/funding/src/benchmarking.rs | 12 +-- pallets/funding/src/functions/2_evaluation.rs | 5 +- .../funding/src/functions/4_contribution.rs | 13 +-- pallets/funding/src/functions/6_settlement.rs | 73 ++++++++++----- pallets/funding/src/functions/misc.rs | 26 +++++- .../funding/src/instantiator/calculations.rs | 36 ++++--- .../src/instantiator/chain_interactions.rs | 2 +- pallets/funding/src/instantiator/types.rs | 23 ++--- pallets/funding/src/lib.rs | 31 ++++--- pallets/funding/src/mock.rs | 26 +++++- pallets/funding/src/runtime_api.rs | 2 +- pallets/funding/src/tests/3_auction.rs | 2 +- pallets/funding/src/tests/4_contribution.rs | 93 +++++++++---------- pallets/funding/src/tests/6_settlement.rs | 11 ++- pallets/funding/src/tests/misc.rs | 10 +- pallets/funding/src/tests/mod.rs | 30 +++--- pallets/funding/src/tests/runtime_api.rs | 24 ++--- pallets/funding/src/types.rs | 32 +++++-- pallets/proxy-bonding/Cargo.toml | 17 +++- pallets/proxy-bonding/src/functions.rs | 6 +- pallets/proxy-bonding/src/lib.rs | 1 + polimec-common/common/src/lib.rs | 3 +- runtimes/polimec/Cargo.toml | 4 + runtimes/polimec/src/benchmark_helpers.rs | 3 +- runtimes/polimec/src/lib.rs | 27 +++++- runtimes/shared-configuration/src/currency.rs | 3 +- runtimes/shared-configuration/src/funding.rs | 4 +- 30 files changed, 355 insertions(+), 207 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18fde7cec..aa0bafbe8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7296,6 +7296,7 @@ dependencies = [ "pallet-balances", "pallet-insecure-randomness-collective-flip", "pallet-linear-release", + "pallet-proxy-bonding", "pallet-timestamp", "pallet-xcm", "parachains-common", @@ -7757,6 +7758,24 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-proxy-bonding" +version = "0.8.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-assets", + "pallet-balances", + "pallet-linear-release", + "parity-scale-codec", + "polimec-common", + "scale-info", + "serde", + "sp-io", + "sp-runtime", +] + [[package]] name = "pallet-ranked-collective" version = "35.0.0" @@ -8828,6 +8847,7 @@ dependencies = [ "pallet-parachain-staking", "pallet-preimage", "pallet-proxy", + "pallet-proxy-bonding", "pallet-scheduler", "pallet-session", "pallet-timestamp", @@ -10563,24 +10583,6 @@ dependencies = [ "prost 0.12.6", ] -[[package]] -name = "proxy-bonding" -version = "0.8.0" -dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", - "pallet-assets", - "pallet-balances", - "pallet-linear-release", - "parity-scale-codec", - "polimec-common", - "scale-info", - "serde", - "sp-io", - "sp-runtime", -] - [[package]] name = "psm" version = "0.1.21" diff --git a/Cargo.toml b/Cargo.toml index 951f2d8d3..84c3a5fbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,6 +67,7 @@ pallet-parachain-staking = { path = "pallets/parachain-staking", default-feature pallet-linear-release = { path = "pallets/linear-release", default-features = false } polimec-receiver = { path = "pallets/polimec-receiver", default-features = false } on-slash-vesting = { path = "pallets/on-slash-vesting", default-features = false } +pallet-proxy-bonding = { path = "pallets/proxy-bonding", default-features = false } # Internal macros macros = { path = "macros" } diff --git a/pallets/funding/Cargo.toml b/pallets/funding/Cargo.toml index 247e98e2b..35e7c95e3 100644 --- a/pallets/funding/Cargo.toml +++ b/pallets/funding/Cargo.toml @@ -29,6 +29,7 @@ variant_count = "1.1.0" pallet-linear-release.workspace = true on-slash-vesting.workspace = true +pallet-proxy-bonding.workspace = true # Substrate dependencies frame-support.workspace = true @@ -95,6 +96,7 @@ std = [ "xcm-builder/std", "xcm-executor/std", "xcm/std", + "pallet-proxy-bonding/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", @@ -115,6 +117,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "pallet-proxy-bonding/runtime-benchmarks" ] try-runtime = [ "frame-support/try-runtime", @@ -128,5 +131,6 @@ try-runtime = [ "polimec-common-test-utils?/try-runtime", "polimec-common/try-runtime", "sp-runtime/try-runtime", + "pallet-proxy-bonding/try-runtime" ] on-chain-release-build = [] diff --git a/pallets/funding/src/benchmarking.rs b/pallets/funding/src/benchmarking.rs index 6a1e8a8bb..5883315dc 100644 --- a/pallets/funding/src/benchmarking.rs +++ b/pallets/funding/src/benchmarking.rs @@ -1042,7 +1042,7 @@ mod benchmarks { let contributions = vec![ - ContributionParams::new(contributor.clone(), (50 * CT_UNIT).into(), 1u8, AcceptedFundingAsset::USDT); + ContributionParams::new(contributor.clone(), (50 * CT_UNIT).into(), ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT); x as usize + 1 ]; @@ -1078,7 +1078,7 @@ mod benchmarks { jwt, project_id, contributions[0].amount, - contributions[0].multiplier, + contributions[0].mode, contributions[0].asset, ); @@ -1112,7 +1112,7 @@ mod benchmarks { funding_asset: AcceptedFundingAsset::USDT, funding_amount: usdt[0].asset_amount, plmc_bond: plmc[0].plmc_amount, - multiplier: contributions[0].multiplier, + mode: contributions[0].mode, } .into(), ); @@ -1504,7 +1504,7 @@ mod benchmarks { ContributionParams::::new( participant.clone(), (10 * CT_UNIT).into(), - 1u8, + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ) }) @@ -1846,7 +1846,7 @@ mod benchmarks { ContributionParams::::new( participant.clone(), (10 * CT_UNIT).into(), - 1u8, + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ) }) @@ -1937,7 +1937,7 @@ mod benchmarks { ContributionParams::::new( participant.clone(), (10 * CT_UNIT).into(), - 1u8, + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ) }) diff --git a/pallets/funding/src/functions/2_evaluation.rs b/pallets/funding/src/functions/2_evaluation.rs index b7a837a10..8fa933f52 100644 --- a/pallets/funding/src/functions/2_evaluation.rs +++ b/pallets/funding/src/functions/2_evaluation.rs @@ -124,8 +124,9 @@ impl Pallet { let mut project_details = ProjectsDetails::::get(project_id).ok_or(Error::::ProjectDetailsNotFound)?; let now = >::block_number(); let evaluation_id = NextEvaluationId::::get(); - let plmc_usd_price = T::PriceProvider::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS) - .ok_or(Error::::PriceNotFound)?; + let plmc_usd_price = + >::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS) + .ok_or(Error::::PriceNotFound)?; let early_evaluation_reward_threshold_usd = T::EvaluationSuccessThreshold::get() * project_details.fundraising_target_usd; let evaluation_round_info = &mut project_details.evaluation_round_info; diff --git a/pallets/funding/src/functions/4_contribution.rs b/pallets/funding/src/functions/4_contribution.rs index 99a1c9912..8035377ee 100644 --- a/pallets/funding/src/functions/4_contribution.rs +++ b/pallets/funding/src/functions/4_contribution.rs @@ -17,7 +17,7 @@ impl Pallet { contributor, project_id, ct_amount: token_amount, - multiplier, + mode, funding_asset, investor_type, did, @@ -48,7 +48,7 @@ impl Pallet { project_id, project_details: &mut project_details, buyable_tokens, - multiplier, + mode, funding_asset, investor_type, did, @@ -65,7 +65,7 @@ impl Pallet { project_id, project_details, buyable_tokens, - multiplier, + mode, funding_asset, investor_type, did, @@ -91,6 +91,7 @@ impl Pallet { InvestorType::Professional => PROFESSIONAL_MAX_MULTIPLIER, InvestorType::Institutional => INSTITUTIONAL_MAX_MULTIPLIER, }; + let multiplier: MultiplierOf = mode.multiplier().try_into().map_err(|_| Error::::ForbiddenMultiplier)?; // * Validity checks * ensure!(project_policy == whitelisted_policy, Error::::PolicyMismatch); @@ -125,7 +126,7 @@ impl Pallet { contributor: contributor.clone(), ct_amount: buyable_tokens, usd_contribution_amount: ticket_size, - multiplier, + mode: mode.clone(), funding_asset, funding_asset_amount, plmc_bond, @@ -133,7 +134,7 @@ impl Pallet { }; // Try adding the new contribution to the system - Self::try_plmc_participation_lock(&contributor, project_id, plmc_bond)?; + Self::bond_plmc_with_mode(&contributor, project_id, plmc_bond, mode, funding_asset)?; Self::try_funding_asset_hold(&contributor, project_id, funding_asset_amount, funding_asset.id())?; Contributions::::insert((project_id, contributor.clone(), contribution_id), &new_contribution); @@ -152,7 +153,7 @@ impl Pallet { funding_asset, funding_amount: funding_asset_amount, plmc_bond, - multiplier, + mode, }); // return correct weight function diff --git a/pallets/funding/src/functions/6_settlement.rs b/pallets/funding/src/functions/6_settlement.rs index f558ffd8d..8fac88e6f 100644 --- a/pallets/funding/src/functions/6_settlement.rs +++ b/pallets/funding/src/functions/6_settlement.rs @@ -151,7 +151,7 @@ impl Pallet { let BidRefund { final_ct_usd_price, final_ct_amount, refunded_plmc, refunded_funding_asset_amount } = Self::calculate_refund(&bid, funding_success, wap)?; - Self::release_participation_bond(&bid.bidder, refunded_plmc)?; + Self::release_participation_bond_for(&bid.bidder, refunded_plmc)?; Self::release_funding_asset(project_id, &bid.bidder, refunded_funding_asset_amount, bid.funding_asset)?; if funding_success && bid.status != BidStatus::Rejected { @@ -162,7 +162,7 @@ impl Pallet { .map_err(|_| Error::::BadMath)?; if vesting_info.duration == 1u32.into() { - Self::release_participation_bond(&bid.bidder, vesting_info.total_amount)?; + Self::release_participation_bond_for(&bid.bidder, vesting_info.total_amount)?; } else { VestingOf::::add_release_schedule( &bid.bidder, @@ -245,7 +245,7 @@ impl Pallet { if outcome == FundingOutcome::Failure { // Release the held PLMC bond - Self::release_participation_bond(&contribution.contributor, contribution.plmc_bond)?; + Self::unbond_participation_with_mode(contribution.contributor.clone(), contribution.plmc_bond, contribution.mode)?; Self::release_funding_asset( project_id, @@ -254,25 +254,13 @@ impl Pallet { contribution.funding_asset, )?; } else { - // Calculate the vesting info and add the release schedule - let vesting_info = Self::calculate_vesting_info( - &contribution.contributor, - contribution.multiplier, - contribution.plmc_bond, - ) - .map_err(|_| Error::::BadMath)?; - if vesting_info.duration == 1u32.into() { - Self::release_participation_bond(&contribution.contributor, vesting_info.total_amount)?; - } else { - VestingOf::::add_release_schedule( - &contribution.contributor, - vesting_info.total_amount, - vesting_info.amount_per_block, - funding_end_block, - HoldReason::Participation.into(), - )?; - } + let ct_vesting_duration = Self::set_bond_release_with_mode( + contribution.contributor.clone(), + contribution.plmc_bond, + contribution.mode, + funding_end_block, + )?; // Mint the contribution tokens Self::mint_contribution_tokens(project_id, &contribution.contributor, contribution.ct_amount)?; @@ -292,7 +280,7 @@ impl Pallet { contribution.id, ParticipationType::Contribution, contribution.ct_amount, - vesting_info.duration, + ct_vesting_duration )?; final_ct_amount = contribution.ct_amount; @@ -367,7 +355,14 @@ impl Pallet { Ok(()) } - fn release_participation_bond(participant: &AccountIdOf, amount: Balance) -> DispatchResult { + fn unbond_participation_with_mode(participant: AccountIdOf, plmc_amount: Balance, mode: ParticipationMode) -> DispatchResult { + match mode { + ParticipationMode::OTM => todo!(), + ParticipationMode::Normal(_) => Self::release_participation_bond_for(&participant, plmc_amount), + } + } + + fn release_participation_bond_for(participant: &AccountIdOf, amount: Balance) -> DispatchResult { if amount.is_zero() { return Ok(()); } @@ -376,6 +371,38 @@ impl Pallet { Ok(()) } + fn set_bond_release_with_mode(participant: AccountIdOf, plmc_amount: Balance, mode: ParticipationMode, funding_end_block: BlockNumberFor) -> Result, DispatchError> { + let multiplier = mode.multiplier().try_into().map_err(|_| Error::::ImpossibleState)?; + match mode { + ParticipationMode::OTM => todo!(), + ParticipationMode::Normal(_) => Self::set_release_schedule_for(&participant, plmc_amount, multiplier, funding_end_block), + } + } + + fn set_release_schedule_for(participant: &AccountIdOf, plmc_amount: Balance, multiplier: MultiplierOf, funding_end_block: BlockNumberFor) -> Result, DispatchError> { + // Calculate the vesting info and add the release schedule + let vesting_info = Self::calculate_vesting_info( + participant, + multiplier, + plmc_amount, + ) + .map_err(|_| Error::::BadMath)?; + + if vesting_info.duration == 1u32.into() { + Self::release_participation_bond_for(participant, vesting_info.total_amount)?; + } else { + VestingOf::::add_release_schedule( + participant, + vesting_info.total_amount, + vesting_info.amount_per_block, + funding_end_block, + HoldReason::Participation.into(), + )?; + } + + Ok(vesting_info.duration) + } + fn slash_evaluator(evaluation: &EvaluationInfoOf) -> Result { let slash_percentage = T::EvaluatorSlash::get(); let treasury_account = T::BlockchainOperationTreasury::get(); diff --git a/pallets/funding/src/functions/misc.rs b/pallets/funding/src/functions/misc.rs index 4c6a68fc0..8a0118eea 100644 --- a/pallets/funding/src/functions/misc.rs +++ b/pallets/funding/src/functions/misc.rs @@ -29,8 +29,9 @@ impl Pallet { } pub fn calculate_plmc_bond(ticket_size: Balance, multiplier: MultiplierOf) -> Result { - let plmc_usd_price = T::PriceProvider::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS) - .ok_or(Error::::PriceNotFound)?; + let plmc_usd_price = + >::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS) + .ok_or(Error::::PriceNotFound)?; let usd_bond = multiplier.calculate_bonding_requirement::(ticket_size).ok_or(Error::::BadMath)?; plmc_usd_price .reciprocal() @@ -45,7 +46,7 @@ impl Pallet { ) -> Result { let asset_id = asset_id.id(); let asset_decimals = T::FundingCurrency::decimals(asset_id); - let asset_usd_price = T::PriceProvider::get_decimals_aware_price(asset_id, USD_DECIMALS, asset_decimals) + let asset_usd_price = >::get_decimals_aware_price(asset_id, USD_DECIMALS, asset_decimals) .ok_or(Error::::PriceNotFound)?; asset_usd_price .reciprocal() @@ -130,6 +131,25 @@ impl Pallet { Ok((accepted_bid_len, rejected_bids.len() as u32)) } + pub fn bond_plmc_with_mode( + who: &T::AccountId, + project_id: ProjectId, + amount: Balance, + mode: ParticipationMode, + asset: AcceptedFundingAsset, + ) -> DispatchResult { + match mode { + ParticipationMode::Normal(_) => Self::try_plmc_participation_lock(who, project_id, amount), + ParticipationMode::OTM => pallet_proxy_bonding::Pallet::::bond_on_behalf_of( + project_id, + who.clone(), + amount, + asset.id(), + HoldReason::Participation.into(), + ), + } + } + pub fn try_plmc_participation_lock(who: &T::AccountId, project_id: ProjectId, amount: Balance) -> DispatchResult { // Check if the user has already locked tokens in the evaluation period let user_evaluations = Evaluations::::iter_prefix_values((project_id, who)); diff --git a/pallets/funding/src/instantiator/calculations.rs b/pallets/funding/src/instantiator/calculations.rs index 9830cf3e1..f08a88936 100644 --- a/pallets/funding/src/instantiator/calculations.rs +++ b/pallets/funding/src/instantiator/calculations.rs @@ -3,6 +3,8 @@ use super::*; use core::cmp::Ordering; use itertools::GroupBy; use polimec_common::{ProvideAssetPrice, USD_DECIMALS}; +use crate::{Multiplier, MultiplierOf, ParticipationMode}; + impl< T: Config, AllPalletsWithoutSystem: OnFinalize> + OnIdle> + OnInitialize>, @@ -23,7 +25,7 @@ impl< with_ed: bool, ) -> Vec> { let plmc_usd_price = self.execute(|| { - T::PriceProvider::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() + >::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() }); let mut output = Vec::new(); @@ -78,7 +80,7 @@ impl< with_ed: bool, ) -> Vec> { let plmc_usd_price = self.execute(|| { - T::PriceProvider::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() + >::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() }); let mut output = Vec::new(); @@ -104,7 +106,7 @@ impl< ) -> Vec> { let mut output = Vec::new(); let plmc_usd_price = self.execute(|| { - T::PriceProvider::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() + >::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() }); for (bid, price) in self.get_actual_price_charged_for_bucketed_bids(bids, project_metadata, maybe_bucket) { @@ -137,7 +139,7 @@ impl< grouped_by_price_bids.reverse(); let plmc_usd_price = self.execute(|| { - T::PriceProvider::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() + >::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() }); let mut remaining_cts = project_metadata.auction_round_allocation_percentage * project_metadata.total_allocation_size; @@ -205,7 +207,7 @@ impl< let funding_asset_id = bid.asset.id(); let funding_asset_decimals = self.execute(|| T::FundingCurrency::decimals(funding_asset_id)); let funding_asset_usd_price = self.execute(|| { - T::PriceProvider::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals) + >::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals) .unwrap() }); let usd_ticket_size = ct_price.saturating_mul_int(bid.amount); @@ -228,7 +230,7 @@ impl< let funding_asset_id = bid.asset.id(); let funding_asset_decimals = self.execute(|| T::FundingCurrency::decimals(funding_asset_id)); let funding_asset_usd_price = self.execute(|| { - T::PriceProvider::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals) + >::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals) .ok_or(Error::::PriceNotFound) .unwrap() }); @@ -264,9 +266,13 @@ impl< let funding_asset_id = bid.asset.id(); let funding_asset_decimals = self.execute(|| T::FundingCurrency::decimals(funding_asset_id)); let funding_asset_usd_price = self.execute(|| { - T::PriceProvider::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals) - .ok_or(Error::::PriceNotFound) - .unwrap() + >::get_decimals_aware_price( + funding_asset_id, + USD_DECIMALS, + funding_asset_decimals, + ) + .ok_or(Error::::PriceNotFound) + .unwrap() }); let charged_usd_ticket_size = price_charged.saturating_mul_int(bid.amount); @@ -346,13 +352,15 @@ impl< with_ed: bool, ) -> Vec> { let plmc_usd_price = self.execute(|| { - T::PriceProvider::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() + >::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS).unwrap() }); let mut output = Vec::new(); for cont in contributions { let usd_ticket_size = token_usd_price.saturating_mul_int(cont.amount); - let usd_bond = cont.multiplier.calculate_bonding_requirement::(usd_ticket_size).unwrap(); + // Needs to be forced to allow for failure tests + let multiplier = Multiplier::force_new(cont.mode.multiplier()); + let usd_bond = multiplier.calculate_bonding_requirement::(usd_ticket_size).unwrap(); let mut plmc_bond = plmc_usd_price.reciprocal().unwrap().saturating_mul_int(usd_bond); if with_ed { plmc_bond = plmc_bond.saturating_add(self.get_ed()); @@ -420,7 +428,7 @@ impl< let funding_asset_id = cont.asset.id(); let funding_asset_decimals = self.execute(|| T::FundingCurrency::decimals(funding_asset_id)); let funding_asset_usd_price = self.execute(|| { - T::PriceProvider::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals) + >::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals) .ok_or(Error::::PriceNotFound) .unwrap() }); @@ -587,7 +595,7 @@ impl< let ticket_size = Percent::from_percent(weight) * usd_amount; let token_amount = final_price.reciprocal().unwrap().saturating_mul_int(ticket_size); - ContributionParams::new(bidder, token_amount, multiplier, AcceptedFundingAsset::USDT) + ContributionParams::new(bidder, token_amount, ParticipationMode::Normal(multiplier), AcceptedFundingAsset::USDT) }) .collect() } @@ -608,7 +616,7 @@ impl< zip(zip(weights, contributors), multipliers) .map(|((weight, contributor), multiplier)| { let token_amount = Percent::from_percent(weight) * total_ct_bought; - ContributionParams::new(contributor, token_amount, multiplier, AcceptedFundingAsset::USDT) + ContributionParams::new(contributor, token_amount, ParticipationMode::Normal(multiplier), AcceptedFundingAsset::USDT) }) .collect() } diff --git a/pallets/funding/src/instantiator/chain_interactions.rs b/pallets/funding/src/instantiator/chain_interactions.rs index a51f29871..df718297e 100644 --- a/pallets/funding/src/instantiator/chain_interactions.rs +++ b/pallets/funding/src/instantiator/chain_interactions.rs @@ -628,7 +628,7 @@ impl< contributor: cont.contributor, project_id, ct_amount: cont.amount, - multiplier: cont.multiplier, + mode: cont.mode, funding_asset: cont.asset, did, investor_type, diff --git a/pallets/funding/src/instantiator/types.rs b/pallets/funding/src/instantiator/types.rs index d303929e5..0556b373e 100644 --- a/pallets/funding/src/instantiator/types.rs +++ b/pallets/funding/src/instantiator/types.rs @@ -1,6 +1,7 @@ #[allow(clippy::wildcard_imports)] use super::*; use frame_support::{Deserialize, Serialize}; +use crate::ParticipationMode; pub type RuntimeOriginOf = ::RuntimeOrigin; pub struct BoxToFunction(pub Box); @@ -316,19 +317,19 @@ impl Accounts for Vec> { pub struct ContributionParams { pub contributor: AccountIdOf, pub amount: Balance, - pub multiplier: MultiplierOf, + pub mode: ParticipationMode, pub asset: AcceptedFundingAsset, } impl ContributionParams { - pub fn new(contributor: AccountIdOf, amount: Balance, multiplier: u8, asset: AcceptedFundingAsset) -> Self { - Self { contributor, amount, multiplier: multiplier.try_into().map_err(|_| ()).unwrap(), asset } + pub fn new(contributor: AccountIdOf, amount: Balance, mode: ParticipationMode, asset: AcceptedFundingAsset) -> Self { + Self { contributor, amount, mode, asset } } pub fn new_with_defaults(contributor: AccountIdOf, amount: Balance) -> Self { Self { contributor, amount, - multiplier: 1u8.try_into().unwrap_or_else(|_| panic!("multiplier could not be created from 1u8")), + mode: ParticipationMode::Normal(1u8), asset: AcceptedFundingAsset::USDT, } } @@ -338,21 +339,21 @@ impl From<(AccountIdOf, Balance)> for ContributionParams { Self { contributor, amount, - multiplier: 1u8.try_into().unwrap_or_else(|_| panic!("multiplier could not be created from 1u8")), + mode: ParticipationMode::Normal(1u8), asset: AcceptedFundingAsset::USDT, } } } -impl From<(AccountIdOf, Balance, MultiplierOf)> for ContributionParams { - fn from((contributor, amount, multiplier): (AccountIdOf, Balance, MultiplierOf)) -> Self { - Self { contributor, amount, multiplier, asset: AcceptedFundingAsset::USDT } +impl From<(AccountIdOf, Balance, ParticipationMode)> for ContributionParams { + fn from((contributor, amount, mode): (AccountIdOf, Balance, ParticipationMode)) -> Self { + Self { contributor, amount, mode, asset: AcceptedFundingAsset::USDT } } } -impl From<(AccountIdOf, Balance, MultiplierOf, AcceptedFundingAsset)> for ContributionParams { +impl From<(AccountIdOf, Balance, ParticipationMode, AcceptedFundingAsset)> for ContributionParams { fn from( - (contributor, amount, multiplier, asset): (AccountIdOf, Balance, MultiplierOf, AcceptedFundingAsset), + (contributor, amount, mode, asset): (AccountIdOf, Balance, ParticipationMode, AcceptedFundingAsset), ) -> Self { - Self { contributor, amount, multiplier, asset } + Self { contributor, amount, mode, asset } } } impl Accounts for Vec> { diff --git a/pallets/funding/src/lib.rs b/pallets/funding/src/lib.rs index b47dad639..a263b01d6 100644 --- a/pallets/funding/src/lib.rs +++ b/pallets/funding/src/lib.rs @@ -89,6 +89,7 @@ use pallet_xcm::ensure_response; use polimec_common::{ credentials::{Cid, Did, EnsureOriginWithCredentials, InvestorType, UntrustedToken}, migration_types::{Migration, MigrationStatus}, + PLMC_DECIMALS, PLMC_FOREIGN_ID, USD_DECIMALS, }; use polkadot_parachain_primitives::primitives::Id as ParaId; use sp_arithmetic::traits::{One, Saturating}; @@ -96,7 +97,6 @@ use sp_runtime::{traits::AccountIdConversion, FixedPointNumber, FixedU128}; use sp_std::{marker::PhantomData, prelude::*}; pub use types::*; use xcm::v4::{prelude::*, SendXcm}; - mod functions; pub mod storage_migrations; pub mod traits; @@ -125,7 +125,6 @@ pub type Balance = u128; pub type MultiplierOf = ::Multiplier; pub type PriceOf = ::Price; -pub type PriceProviderOf = ::PriceProvider; pub type StringLimitOf = ::StringLimit; pub type AssetIdOf = <::FundingCurrency as fungibles::Inspect<::AccountId>>::AssetId; @@ -137,15 +136,14 @@ pub type EvaluationInfoOf = EvaluationInfo = BidInfo, AccountIdOf, BlockNumberFor, MultiplierOf>; pub type ContributionInfoOf = - ContributionInfo, BlockNumberFor, MultiplierOf>; + ContributionInfo, BlockNumberFor>; pub type BucketOf = Bucket>; pub type WeightInfoOf = ::WeightInfo; pub type VestingOf = pallet_linear_release::Pallet; pub type BlockNumberToBalanceOf = ::BlockNumberToBalance; - -pub const PLMC_FOREIGN_ID: u32 = 3344; -pub const PLMC_DECIMALS: u8 = 10; +pub type RuntimeHoldReasonOf = ::RuntimeHoldReason; +pub type PriceProviderOf = ::PriceProvider; #[frame_support::pallet] pub mod pallet { @@ -163,7 +161,7 @@ pub mod pallet { use polimec_common::ProvideAssetPrice; use sp_arithmetic::Percent; use sp_runtime::{ - traits::{Convert, ConvertBack, Get}, + traits::{ConstU8, Convert, ConvertBack, Get}, Perquintill, }; @@ -182,7 +180,16 @@ pub mod pallet { frame_system::Config + pallet_balances::Config + pallet_xcm::Config - + pallet_linear_release::Config::RuntimeHoldReason> + + pallet_linear_release::Config> + + pallet_proxy_bonding::Config< + RuntimeHoldReason = RuntimeHoldReasonOf, + BondingToken = Self::NativeCurrency, + BondingTokenDecimals = ConstU8, + BondingTokenId = ConstU32, + UsdDecimals = ConstU8, + FeeToken = Self::FundingCurrency, + PriceProvider = PriceProviderOf, + > { /// A way to convert from and to the account type used in CT migrations type AccountId32Conversion: ConvertBack; @@ -297,7 +304,7 @@ pub mod pallet { /// The chains native currency type NativeCurrency: fungible::InspectHold, Balance = Balance> - + fungible::MutateHold, Balance = Balance, Reason = ::RuntimeHoldReason> + + fungible::MutateHold, Balance = Balance, Reason = RuntimeHoldReasonOf> + fungible::BalancedHold, Balance = Balance> + fungible::Mutate, Balance = Balance> + fungible::Inspect, Balance = Balance>; @@ -529,7 +536,7 @@ pub mod pallet { funding_asset: AcceptedFundingAsset, funding_amount: Balance, plmc_bond: Balance, - multiplier: MultiplierOf, + mode: ParticipationMode, }, BidRefunded { project_id: ProjectId, @@ -865,7 +872,7 @@ pub mod pallet { jwt: UntrustedToken, project_id: ProjectId, #[pallet::compact] ct_amount: Balance, - multiplier: MultiplierOf, + mode: ParticipationMode, funding_asset: AcceptedFundingAsset, ) -> DispatchResultWithPostInfo { let (contributor, did, investor_type, whitelisted_policy) = @@ -874,7 +881,7 @@ pub mod pallet { contributor, project_id, ct_amount, - multiplier, + mode, funding_asset, did, investor_type, diff --git a/pallets/funding/src/mock.rs b/pallets/funding/src/mock.rs index ae1d4db9f..646e09728 100644 --- a/pallets/funding/src/mock.rs +++ b/pallets/funding/src/mock.rs @@ -35,8 +35,8 @@ use frame_system as system; use frame_system::{EnsureRoot, RawOrigin as SystemRawOrigin}; use polimec_common::{credentials::EnsureInvestor, DummyXcmSender, ProvideAssetPrice, USD_UNIT}; use polkadot_parachain_primitives::primitives::Sibling; -use sp_arithmetic::Percent; -use sp_core::H256; +use sp_arithmetic::{Perbill, Percent}; +use sp_core::{ConstU8, H256}; use sp_runtime::{ traits::{BlakeTwo256, ConvertBack, ConvertInto, Get, IdentityLookup, TryConvert}, BuildStorage, Perquintill, @@ -435,6 +435,27 @@ impl Config for TestRuntime { type WeightInfo = weights::SubstrateWeight; } +parameter_types! { + pub const FeePercentage: Perbill = Perbill::from_percent(5); + pub const FeeRecipient: AccountId = 80085u32; + pub const RootId: PalletId = PalletId(*b"treasury"); +} +impl pallet_proxy_bonding::Config for TestRuntime { + type BondingToken = Balances; + type BondingTokenDecimals = ConstU8; + type BondingTokenId = ConstU32; + type FeePercentage = FeePercentage; + type FeeRecipient = FeeRecipient; + type FeeToken = ForeignAssets; + type Id = PalletId; + type PriceProvider = ConstPriceProvider; + type RootId = RootId; + type RuntimeEvent = RuntimeEvent; + type RuntimeHoldReason = RuntimeHoldReason; + type Treasury = BlockchainOperationTreasuryAccount; + type UsdDecimals = ConstU8; +} + // Configure a mock runtime to test the pallet. construct_runtime!( pub enum TestRuntime @@ -448,6 +469,7 @@ construct_runtime!( ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event, Config}, PolkadotXcm: pallet_xcm, PolimecFunding: pallet_funding::{Pallet, Call, Storage, Event, HoldReason} = 52, + ProxyBonding: pallet_proxy_bonding, } ); diff --git a/pallets/funding/src/runtime_api.rs b/pallets/funding/src/runtime_api.rs index dd2520862..aeeefa5ab 100644 --- a/pallets/funding/src/runtime_api.rs +++ b/pallets/funding/src/runtime_api.rs @@ -140,7 +140,7 @@ impl Pallet { let funding_asset_id = asset.id(); let funding_asset_decimals = T::FundingCurrency::decimals(funding_asset_id); let funding_asset_usd_price = - T::PriceProvider::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals) + >::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals) .expect("Price not found"); let usd_ticket_size = funding_asset_usd_price.saturating_mul_int(asset_amount); diff --git a/pallets/funding/src/tests/3_auction.rs b/pallets/funding/src/tests/3_auction.rs index 369de7c0a..8251e91ed 100644 --- a/pallets/funding/src/tests/3_auction.rs +++ b/pallets/funding/src/tests/3_auction.rs @@ -332,7 +332,7 @@ mod round_flow { contributor: BIDDER_1, project_id, ct_amount: 100, - multiplier: 1u8.try_into().unwrap(), + mode: ParticipationMode::Normal(1u8), funding_asset: AcceptedFundingAsset::USDT, did, investor_type, diff --git a/pallets/funding/src/tests/4_contribution.rs b/pallets/funding/src/tests/4_contribution.rs index ca9cf9b89..71adc21a5 100644 --- a/pallets/funding/src/tests/4_contribution.rs +++ b/pallets/funding/src/tests/4_contribution.rs @@ -82,7 +82,7 @@ mod round_flow { let remaining_ct = inst.get_project_details(project_id).remaining_contribution_tokens; let ct_price = inst.get_project_details(project_id).weighted_average_price.expect("CT Price should exist"); - let contributions = vec![ContributionParams::new(BOB, remaining_ct, 1u8, AcceptedFundingAsset::USDT)]; + let contributions = vec![ContributionParams::new(BOB, remaining_ct,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT)]; let plmc_fundings = inst.calculate_contributed_plmc_spent(contributions.clone(), ct_price, false); let plmc_existential_deposits = plmc_fundings.accounts().existential_deposits(); let foreign_asset_fundings = @@ -290,7 +290,7 @@ mod round_flow { ), project_id, total_funding_ct, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), funding_asset, ))); @@ -380,7 +380,7 @@ mod contribute_extrinsic { ), project_id, usable_ct + slashable_ct, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::ParticipantNotEnoughFunds @@ -402,7 +402,7 @@ mod contribute_extrinsic { ), project_id, usable_ct / 2, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -422,7 +422,7 @@ mod contribute_extrinsic { ), project_id, usable_ct, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -515,7 +515,7 @@ mod contribute_extrinsic { ), project_id, usable_bob_ct, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -544,9 +544,9 @@ mod contribute_extrinsic { default_evaluations(), default_bids(), ); - let usdt_contribution = ContributionParams::new(BUYER_1, 10_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT); - let usdc_contribution = ContributionParams::new(BUYER_2, 10_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDC); - let dot_contribution = ContributionParams::new(BUYER_3, 10_000 * CT_UNIT, 1u8, AcceptedFundingAsset::DOT); + let usdt_contribution = ContributionParams::new(BUYER_1, 10_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT); + let usdc_contribution = ContributionParams::new(BUYER_2, 10_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDC); + let dot_contribution = ContributionParams::new(BUYER_3, 10_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::DOT); let wap = inst.get_project_details(project_id).weighted_average_price.unwrap(); @@ -588,14 +588,13 @@ mod contribute_extrinsic { project_policy, ); let amount = 1000 * CT_UNIT; - let multiplier = Multiplier::force_new(u8_multiplier); let wap = inst.get_project_details(project_id).weighted_average_price.unwrap(); if u8_multiplier > 0 { let contribution = ContributionParams:: { contributor: contributor.clone(), amount, - multiplier, + mode: ParticipationMode::Normal(u8_multiplier), asset: AcceptedFundingAsset::USDT, }; @@ -613,7 +612,7 @@ mod contribute_extrinsic { jwt, project_id, amount, - multiplier, + ParticipationMode::Normal(u8_multiplier), AcceptedFundingAsset::USDT, ) }) @@ -787,7 +786,7 @@ mod contribute_extrinsic { ), project_id, 10 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -817,7 +816,7 @@ mod contribute_extrinsic { ); let wap = inst.get_project_details(project_id).weighted_average_price.unwrap(); - let contribution = ContributionParams::new(BUYER_4, 500 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT); + let contribution = ContributionParams::new(BUYER_4, 500 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT); let plmc_required = inst.calculate_contributed_plmc_spent(vec![contribution.clone()], wap, false); let frozen_amount = plmc_required[0].plmc_amount; let plmc_existential_deposits = plmc_required.accounts().existential_deposits(); @@ -850,7 +849,7 @@ mod contribute_extrinsic { ), project_id, contribution.amount, - contribution.multiplier, + contribution.mode, contribution.asset )); }); @@ -894,7 +893,7 @@ mod contribute_extrinsic { ); let wap = inst.get_project_details(project_id).weighted_average_price.unwrap(); - let contribution = ContributionParams::new(BUYER_4, 500 * CT_UNIT, 5u8, AcceptedFundingAsset::USDT); + let contribution = ContributionParams::new(BUYER_4, 500 * CT_UNIT,ParticipationMode::Normal(5u8), AcceptedFundingAsset::USDT); let plmc_required = inst.calculate_contributed_plmc_spent(vec![contribution.clone()], wap, false); let frozen_amount = plmc_required[0].plmc_amount; let plmc_existential_deposits = plmc_required.accounts().existential_deposits(); @@ -927,7 +926,7 @@ mod contribute_extrinsic { ), project_id, contribution.amount, - contribution.multiplier, + contribution.mode, contribution.asset )); }); @@ -987,7 +986,7 @@ mod contribute_extrinsic { remainder_contributions.push(ContributionParams::new( participant, 10 * CT_UNIT, - 1u8, + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); @@ -1032,7 +1031,7 @@ mod contribute_extrinsic { let token_amount: Balance = CT_UNIT; let range = 0..::MaxContributionsPerUser::get(); let contributions: Vec> = range - .map(|_| ContributionParams::new(CONTRIBUTOR, token_amount, 1u8, AcceptedFundingAsset::USDT)) + .map(|_| ContributionParams::new(CONTRIBUTOR, token_amount,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT)) .collect(); let plmc_funding = inst.calculate_contributed_plmc_spent(contributions.clone(), token_price, false); @@ -1050,7 +1049,7 @@ mod contribute_extrinsic { // Try to contribute again, but it should fail because the limit of contributions for a user-project was reached. let over_limit_contribution = - ContributionParams::new(CONTRIBUTOR, token_amount, 1u8, AcceptedFundingAsset::USDT); + ContributionParams::new(CONTRIBUTOR, token_amount,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT); assert!(inst.contribute_for_users(project_id, vec![over_limit_contribution]).is_err()); // Check that the right amount of PLMC is bonded, and funding currency is transferred @@ -1098,7 +1097,7 @@ mod contribute_extrinsic { contributor: ISSUER_1, project_id, ct_amount: 500 * CT_UNIT, - multiplier: 1u8.try_into().unwrap(), + mode: ParticipationMode::Normal(1), funding_asset: AcceptedFundingAsset::USDT, did: generate_did_from_account(ISSUER_1), investor_type: InvestorType::Institutional, @@ -1142,7 +1141,7 @@ mod contribute_extrinsic { ), project_id, 10 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::UserHasWinningBid @@ -1221,7 +1220,7 @@ mod contribute_extrinsic { jwt, project_id, CT_UNIT / 2, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::TooLow @@ -1241,7 +1240,7 @@ mod contribute_extrinsic { jwt, project_id, 9_999, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::TooLow @@ -1262,7 +1261,7 @@ mod contribute_extrinsic { jwt, project_id, 19_999, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::TooLow @@ -1326,7 +1325,7 @@ mod contribute_extrinsic { buyer_1_jwt, project_id, 9000 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -1337,7 +1336,7 @@ mod contribute_extrinsic { buyer_2_jwt_same_did.clone(), project_id, 1001 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::TooHigh @@ -1350,7 +1349,7 @@ mod contribute_extrinsic { buyer_2_jwt_same_did, project_id, 1000 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -1374,7 +1373,7 @@ mod contribute_extrinsic { buyer_3_jwt, project_id, 1800 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -1385,7 +1384,7 @@ mod contribute_extrinsic { buyer_4_jwt_same_did.clone(), project_id, 201 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::TooHigh @@ -1398,7 +1397,7 @@ mod contribute_extrinsic { buyer_4_jwt_same_did, project_id, 200 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -1422,7 +1421,7 @@ mod contribute_extrinsic { buyer_5_jwt, project_id, 4690 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -1433,7 +1432,7 @@ mod contribute_extrinsic { buyer_6_jwt_same_did.clone(), project_id, 311 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::TooHigh @@ -1446,7 +1445,7 @@ mod contribute_extrinsic { buyer_6_jwt_same_did, project_id, 310 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, )); }); @@ -1470,7 +1469,7 @@ mod contribute_extrinsic { generate_did_from_account(BUYER_1), project_metadata.clone().policy_ipfs_cid.unwrap(), ); - let contribution = ContributionParams::new(BUYER_1, 1_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT); + let contribution = ContributionParams::new(BUYER_1, 1_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT); let wap = inst.get_project_details(project_id).weighted_average_price.unwrap(); // 1 unit less native asset than needed @@ -1492,7 +1491,7 @@ mod contribute_extrinsic { jwt.clone(), project_id, 1_000 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::ParticipantNotEnoughFunds @@ -1528,7 +1527,7 @@ mod contribute_extrinsic { jwt, project_id, 1_000 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT, ), Error::::ParticipantNotEnoughFunds @@ -1572,7 +1571,7 @@ mod contribute_extrinsic { ), project, 1000 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT ), Error::::IncorrectRound @@ -1609,9 +1608,9 @@ mod contribute_extrinsic { }) .collect::>(); - let usdt_contribution = ContributionParams::new(BUYER_1, 10_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT); - let usdc_contribution = ContributionParams::new(BUYER_2, 10_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDC); - let dot_contribution = ContributionParams::new(BUYER_3, 10_000 * CT_UNIT, 1u8, AcceptedFundingAsset::DOT); + let usdt_contribution = ContributionParams::new(BUYER_1, 10_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT); + let usdc_contribution = ContributionParams::new(BUYER_2, 10_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDC); + let dot_contribution = ContributionParams::new(BUYER_3, 10_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::DOT); let project_id_usdc = inst.create_community_contributing_project( project_metadata_usdc, @@ -1654,7 +1653,7 @@ mod contribute_extrinsic { let evaluator_contributor = 69; let evaluation_amount = 420 * USD_UNIT; let evaluator_contribution = - ContributionParams::new(evaluator_contributor, 600 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT); + ContributionParams::new(evaluator_contributor, 600 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT); evaluations_1.push((evaluator_contributor, evaluation_amount).into()); let _project_id_1 = inst.create_community_contributing_project( @@ -1702,7 +1701,7 @@ mod contribute_extrinsic { ), project_id_2, evaluator_contribution.amount, - evaluator_contribution.multiplier, + evaluator_contribution.mode, evaluator_contribution.asset ), Error::::ParticipantNotEnoughFunds @@ -1734,7 +1733,7 @@ mod contribute_extrinsic { ), project_id, 5000 * CT_UNIT, - 1u8.try_into().unwrap(), + ParticipationMode::Normal(1), AcceptedFundingAsset::USDT ), Error::::PolicyMismatch @@ -1755,7 +1754,7 @@ mod contribute_extrinsic { ); let project_details = inst.get_project_details(project_id); let remaining_cts = project_details.remaining_contribution_tokens; - let glutton_contribution = ContributionParams::new(BUYER_1, remaining_cts, 4u8, AcceptedFundingAsset::USDT); + let glutton_contribution = ContributionParams::new(BUYER_1, remaining_cts,ParticipationMode::Normal(4u8), AcceptedFundingAsset::USDT); let wap = project_details.weighted_average_price.unwrap(); let plmc_mint = inst.calculate_contributed_plmc_spent(vec![glutton_contribution.clone()], wap, true); let funding_asset_mint = @@ -1765,7 +1764,7 @@ mod contribute_extrinsic { inst.contribute_for_users(project_id, vec![glutton_contribution.clone()]).unwrap(); let failing_contribution = - ContributionParams::::new(BUYER_2, 1000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT); + ContributionParams::::new(BUYER_2, 1000 * CT_UNIT, ParticipationMode::Normal(1), AcceptedFundingAsset::USDT); let plmc_mint = inst.calculate_contributed_plmc_spent(vec![glutton_contribution.clone()], wap, true); let funding_asset_mint = inst.calculate_contributed_funding_asset_spent(vec![glutton_contribution.clone()], wap); @@ -1783,7 +1782,7 @@ mod contribute_extrinsic { ), project_id, failing_contribution.amount, - failing_contribution.multiplier, + failing_contribution.mode, failing_contribution.asset ), Error::::ProjectSoldOut diff --git a/pallets/funding/src/tests/6_settlement.rs b/pallets/funding/src/tests/6_settlement.rs index c023bdbac..a20d05ec9 100644 --- a/pallets/funding/src/tests/6_settlement.rs +++ b/pallets/funding/src/tests/6_settlement.rs @@ -990,7 +990,7 @@ mod settle_contribution_extrinsic { let project_metadata = default_project_metadata(ISSUER_1); let contribution = - ContributionParams::::new(BUYER_1, 1000 * CT_UNIT, 2, AcceptedFundingAsset::USDT); + ContributionParams::::new(BUYER_1, 1000 * CT_UNIT, ParticipationMode::Normal(2), AcceptedFundingAsset::USDT); let project_id = inst.create_finished_project( project_metadata.clone(), @@ -1041,7 +1041,8 @@ mod settle_contribution_extrinsic { true, ); - let vesting_time = contribution.multiplier.calculate_vesting_duration::(); + let multiplier: MultiplierOf = contribution.mode.multiplier().try_into().ok().unwrap(); + let vesting_time = multiplier.calculate_vesting_duration::(); let current_block = inst.current_block(); inst.jump_to_block(current_block + vesting_time + 1); inst.execute(|| LinearRelease::vest(RuntimeOrigin::signed(BUYER_1), hold_reason).expect("Vesting failed")); @@ -1072,9 +1073,9 @@ mod settle_contribution_extrinsic { ); let contribution_mul_1 = - ContributionParams::::new(BUYER_6, 1000 * CT_UNIT, 1, AcceptedFundingAsset::USDT); + ContributionParams::::new(BUYER_6, 1000 * CT_UNIT, ParticipationMode::Normal(1), AcceptedFundingAsset::USDT); let contribution_mul_2 = - ContributionParams::::new(BUYER_7, 1000 * CT_UNIT, 2, AcceptedFundingAsset::USDT); + ContributionParams::::new(BUYER_7, 1000 * CT_UNIT, ParticipationMode::Normal(2), AcceptedFundingAsset::USDT); community_contributions.push(contribution_mul_1); @@ -1107,7 +1108,7 @@ mod settle_contribution_extrinsic { ), project_id, contribution_mul_2.amount, - contribution_mul_2.multiplier, + contribution_mul_2.mode, contribution_mul_2.asset )); }); diff --git a/pallets/funding/src/tests/misc.rs b/pallets/funding/src/tests/misc.rs index 76108ff14..6288a0e25 100644 --- a/pallets/funding/src/tests/misc.rs +++ b/pallets/funding/src/tests/misc.rs @@ -283,11 +283,11 @@ mod helper_functions { ); let contributions = vec![ - ContributionParams::new(CONTRIBUTOR_1, TOKEN_AMOUNT_1, MULTIPLIER_1, AcceptedFundingAsset::USDT), - ContributionParams::new(CONTRIBUTOR_2, TOKEN_AMOUNT_2, MULTIPLIER_2, AcceptedFundingAsset::USDT), - ContributionParams::new(CONTRIBUTOR_3, TOKEN_AMOUNT_3, MULTIPLIER_3, AcceptedFundingAsset::USDT), - ContributionParams::new(CONTRIBUTOR_4, TOKEN_AMOUNT_4, MULTIPLIER_4, AcceptedFundingAsset::USDT), - ContributionParams::new(CONTRIBUTOR_5, TOKEN_AMOUNT_5, MULTIPLIER_5, AcceptedFundingAsset::USDT), + ContributionParams::new(CONTRIBUTOR_1, TOKEN_AMOUNT_1, ParticipationMode::Normal(MULTIPLIER_1), AcceptedFundingAsset::USDT), + ContributionParams::new(CONTRIBUTOR_2, TOKEN_AMOUNT_2, ParticipationMode::Normal(MULTIPLIER_2), AcceptedFundingAsset::USDT), + ContributionParams::new(CONTRIBUTOR_3, TOKEN_AMOUNT_3, ParticipationMode::Normal(MULTIPLIER_3), AcceptedFundingAsset::USDT), + ContributionParams::new(CONTRIBUTOR_4, TOKEN_AMOUNT_4, ParticipationMode::Normal(MULTIPLIER_4), AcceptedFundingAsset::USDT), + ContributionParams::new(CONTRIBUTOR_5, TOKEN_AMOUNT_5, ParticipationMode::Normal(MULTIPLIER_5), AcceptedFundingAsset::USDT), ]; let expected_plmc_spent = vec![ diff --git a/pallets/funding/src/tests/mod.rs b/pallets/funding/src/tests/mod.rs index f45a5c1a6..8d2b77e6c 100644 --- a/pallets/funding/src/tests/mod.rs +++ b/pallets/funding/src/tests/mod.rs @@ -217,31 +217,31 @@ pub mod defaults { pub fn default_community_contributions() -> Vec> { vec![ - ContributionParams::new(BUYER_1, 50_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_2, 130_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_3, 30_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_4, 210_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_5, 10_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_1, 50_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_2, 130_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_3, 30_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_4, 210_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_5, 10_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), ] } pub fn default_remainder_contributions() -> Vec> { vec![ - ContributionParams::new(EVALUATOR_2, 20_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_2, 5_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BIDDER_1, 30_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(EVALUATOR_2, 20_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_2, 5_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BIDDER_1, 30_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), ] } pub fn knowledge_hub_buys() -> Vec> { vec![ - ContributionParams::new(BUYER_1, 4_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_2, 2_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_3, 2_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_4, 5_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_5, 30_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_6, 5_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_7, 2_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_1, 4_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_2, 2_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_3, 2_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_4, 5_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_5, 30_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_6, 5_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_7, 2_000 * CT_UNIT, ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), ] } diff --git a/pallets/funding/src/tests/runtime_api.rs b/pallets/funding/src/tests/runtime_api.rs index bff7d66e7..d28b82d2f 100644 --- a/pallets/funding/src/tests/runtime_api.rs +++ b/pallets/funding/src/tests/runtime_api.rs @@ -483,9 +483,9 @@ fn get_next_vesting_schedule_merge_candidates() { BidParams::new(BIDDER_2, 50_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), ]; let remaining_contributions = vec![ - ContributionParams::new(BIDDER_1, 1_000 * CT_UNIT, 5u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BIDDER_1, 15_000 * CT_UNIT, 10u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BIDDER_1, 100 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BIDDER_1, 1_000 * CT_UNIT,ParticipationMode::Normal(5u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BIDDER_1, 15_000 * CT_UNIT, ParticipationMode::Normal(10u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BIDDER_1, 100 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), ]; let project_id = inst.create_finished_project( @@ -563,16 +563,16 @@ fn all_project_participations_by_did() { BidParams::new(BIDDER_2, 50_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), ]; let community_contributions = vec![ - ContributionParams::new(BUYER_1, 50_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_2, 130_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_3, 30_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_4, 210_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_5, 10_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_1, 50_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_2, 130_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_3, 30_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_4, 210_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_5, 10_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), ]; let remainder_contributions = vec![ - ContributionParams::new(EVALUATOR_2, 20_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BUYER_2, 5_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), - ContributionParams::new(BIDDER_1, 30_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT), + ContributionParams::new(EVALUATOR_2, 20_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BUYER_2, 5_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), + ContributionParams::new(BIDDER_1, 30_000 * CT_UNIT,ParticipationMode::Normal(1u8), AcceptedFundingAsset::USDT), ]; let evaluations_plmc = inst.calculate_evaluation_plmc_spent(evaluations.clone(), true); @@ -660,7 +660,7 @@ fn all_project_participations_by_did() { jwt, project_id, contribution.amount, - contribution.multiplier, + contribution.mode, contribution.asset, ) .unwrap(); diff --git a/pallets/funding/src/types.rs b/pallets/funding/src/types.rs index a18448195..902b15158 100644 --- a/pallets/funding/src/types.rs +++ b/pallets/funding/src/types.rs @@ -48,12 +48,12 @@ pub mod config { Decode, Eq, PartialEq, - RuntimeDebug, TypeInfo, MaxEncodedLen, Copy, Ord, PartialOrd, + RuntimeDebug, Serialize, Deserialize, )] @@ -392,14 +392,14 @@ pub mod storage { } #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] - pub struct ContributionInfo { + pub struct ContributionInfo { pub id: Id, pub did: Did, pub project_id: ProjectId, pub contributor: AccountId, pub ct_amount: Balance, pub usd_contribution_amount: Balance, - pub multiplier: Multiplier, + pub mode: ParticipationMode, pub funding_asset: AcceptedFundingAsset, pub funding_asset_amount: Balance, pub plmc_bond: Balance, @@ -800,13 +800,27 @@ pub mod inner { pub project_id: ProjectId, pub migration_origins: MigrationOrigins, } + + #[derive(Clone, Copy, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen, Serialize, Deserialize)] + pub enum ParticipationMode { + /// One Token Model. User only needs funding assets, and pays a fee to bond treasury PLMC. + OTM, + /// Normal model. User needs to bond PLMC based on a multiplier, and pays no fee. + Normal(u8), + } + impl ParticipationMode { + pub fn multiplier(&self) -> u8 { + match self { + // OTM multiplier is fixed at 5 + ParticipationMode::OTM => 5u8, + ParticipationMode::Normal(multiplier) => *multiplier, + } + } + } } pub mod extrinsic { - use crate::{ - AcceptedFundingAsset, AccountIdOf, Balance, Config, MultiplierOf, PriceOf, ProjectDetailsOf, ProjectId, - TicketSize, - }; + use crate::{AcceptedFundingAsset, AccountIdOf, Balance, Config, MultiplierOf, ParticipationMode, PriceOf, ProjectDetailsOf, ProjectId, TicketSize}; use frame_system::pallet_prelude::BlockNumberFor; use polimec_common::credentials::{Cid, Did, InvestorType}; @@ -840,7 +854,7 @@ pub mod extrinsic { pub contributor: AccountIdOf, pub project_id: ProjectId, pub ct_amount: Balance, - pub multiplier: MultiplierOf, + pub mode: ParticipationMode, pub funding_asset: AcceptedFundingAsset, pub did: Did, pub investor_type: InvestorType, @@ -852,7 +866,7 @@ pub mod extrinsic { pub project_id: ProjectId, pub project_details: &'a mut ProjectDetailsOf, pub buyable_tokens: Balance, - pub multiplier: MultiplierOf, + pub mode: ParticipationMode, pub funding_asset: AcceptedFundingAsset, pub investor_type: InvestorType, pub did: Did, diff --git a/pallets/proxy-bonding/Cargo.toml b/pallets/proxy-bonding/Cargo.toml index f860e13ca..f7b262e14 100644 --- a/pallets/proxy-bonding/Cargo.toml +++ b/pallets/proxy-bonding/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "proxy-bonding" +name = "pallet-proxy-bonding" authors.workspace = true documentation.workspace = true edition.workspace = true @@ -20,7 +20,7 @@ sp-runtime.workspace = true polimec-common.workspace = true parity-scale-codec.workspace = true scale-info.workspace = true -serde = { version = "1.0.204", features = ["derive"] } +serde = { workspace = true, features = ["derive"] } [dev-dependencies] sp-io.workspace = true @@ -44,14 +44,18 @@ std = [ "sp-io/std", "pallet-linear-release/std", "pallet-balances/std", - "pallet-assets/std" + "pallet-assets/std", + "serde/std" ] try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "sp-runtime/try-runtime", - "polimec-common/try-runtime" + "polimec-common/try-runtime", + "pallet-linear-release/try-runtime", + "pallet-assets/try-runtime", + "pallet-balances/try-runtime" ] runtime-benchmarks = [ @@ -59,5 +63,8 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "polimec-common/runtime-benchmarks" + "polimec-common/runtime-benchmarks", + "pallet-linear-release/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "pallet-balances/runtime-benchmarks" ] diff --git a/pallets/proxy-bonding/src/functions.rs b/pallets/proxy-bonding/src/functions.rs index 278f2f128..877f125c6 100644 --- a/pallets/proxy-bonding/src/functions.rs +++ b/pallets/proxy-bonding/src/functions.rs @@ -1,4 +1,4 @@ -use crate::{AccountIdOf, AssetId, BalanceOf, Config, Error, Pallet, ReleaseType, Releases}; +use crate::{AccountIdOf, AssetId, BalanceOf, Config, Error, Pallet, PriceProviderOf, ReleaseType, Releases}; use frame_support::{ ensure, traits::{ @@ -21,7 +21,7 @@ impl Pallet { /// e.g. if the fee is 1%, native token PLMC, fee_asset USDT, bond_amount 1000 PLMC, PLMC price 0.5USD, USDT price 1USD, /// Then the calculated fee would be 1% * 1000 * 0.5 = 5USD, which is 5 USDT at a price of 1USD. pub fn calculate_fee(bond_amount: BalanceOf, fee_asset: AssetId) -> Result, DispatchError> { - let bonding_token_price = T::PriceProvider::get_decimals_aware_price( + let bonding_token_price = >::get_decimals_aware_price( T::BondingTokenId::get(), T::UsdDecimals::get(), T::BondingTokenDecimals::get(), @@ -30,7 +30,7 @@ impl Pallet { let fee_asset_decimals = >>::decimals(fee_asset); let fee_token_price = - T::PriceProvider::get_decimals_aware_price(fee_asset, T::UsdDecimals::get(), fee_asset_decimals) + >::get_decimals_aware_price(fee_asset, T::UsdDecimals::get(), fee_asset_decimals) .ok_or(Error::::PriceNotAvailable)?; let bonded_in_usd = bonding_token_price.saturating_mul_int(bond_amount); diff --git a/pallets/proxy-bonding/src/lib.rs b/pallets/proxy-bonding/src/lib.rs index a97c4b4af..d29b374fc 100644 --- a/pallets/proxy-bonding/src/lib.rs +++ b/pallets/proxy-bonding/src/lib.rs @@ -46,6 +46,7 @@ pub mod pallet { pub type BalanceOf = <::BondingToken as fungible::Inspect>>::Balance; pub type AccountIdOf = ::AccountId; pub type HoldReasonOf = <::BondingToken as fungible::InspectHold>>::Reason; + pub type PriceProviderOf = ::PriceProvider; /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] diff --git a/polimec-common/common/src/lib.rs b/polimec-common/common/src/lib.rs index 8533c4459..c7d3472ca 100644 --- a/polimec-common/common/src/lib.rs +++ b/polimec-common/common/src/lib.rs @@ -224,7 +224,8 @@ pub mod migration_types { pub const USD_DECIMALS: u8 = 6; pub const USD_UNIT: u128 = 10u128.pow(USD_DECIMALS as u32); - +pub const PLMC_DECIMALS: u8 = 10; +pub const PLMC_FOREIGN_ID: u32 = 3344; pub struct DummyXcmSender; impl SendXcm for DummyXcmSender { type Ticket = (); diff --git a/runtimes/polimec/Cargo.toml b/runtimes/polimec/Cargo.toml index fd5af08e6..cac98208b 100644 --- a/runtimes/polimec/Cargo.toml +++ b/runtimes/polimec/Cargo.toml @@ -38,6 +38,7 @@ shared-configuration.workspace = true polimec-common.workspace = true pallet-parachain-staking.workspace = true on-slash-vesting.workspace = true +pallet-proxy-bonding.workspace = true # Substrate frame-benchmarking = { workspace = true, optional = true } @@ -187,6 +188,7 @@ std = [ "xcm-builder/std", "xcm-executor/std", "xcm/std", + "pallet-proxy-bonding/std" ] runtime-benchmarks = [ @@ -232,6 +234,7 @@ runtime-benchmarks = [ "sp-runtime/runtime-benchmarks", "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "pallet-proxy-bonding/runtime-benchmarks" ] try-runtime = [ @@ -276,6 +279,7 @@ try-runtime = [ "polkadot-runtime-common/try-runtime", "shared-configuration/try-runtime", "sp-runtime/try-runtime", + "pallet-proxy-bonding/try-runtime" ] # A feature that should be enabled when the runtime should be built for on-chain diff --git a/runtimes/polimec/src/benchmark_helpers.rs b/runtimes/polimec/src/benchmark_helpers.rs index 1cf82cb63..26aa3e4a5 100644 --- a/runtimes/polimec/src/benchmark_helpers.rs +++ b/runtimes/polimec/src/benchmark_helpers.rs @@ -1,6 +1,7 @@ use crate::{Oracle, Runtime, RuntimeOrigin}; use alloc::vec; use pallet_funding::{traits::SetPrices, AcceptedFundingAsset}; +use polimec_common::PLMC_FOREIGN_ID; use sp_runtime::{BoundedVec, FixedU128}; pub struct SetOraclePrices; @@ -9,7 +10,7 @@ impl SetPrices for SetOraclePrices { let dot = (AcceptedFundingAsset::DOT.id(), FixedU128::from_rational(69, 1)); let usdc = (AcceptedFundingAsset::USDC.id(), FixedU128::from_rational(1, 1)); let usdt = (AcceptedFundingAsset::USDT.id(), FixedU128::from_rational(1, 1)); - let plmc = (pallet_funding::PLMC_FOREIGN_ID, FixedU128::from_rational(840, 100)); + let plmc = (PLMC_FOREIGN_ID, FixedU128::from_rational(840, 100)); let values: BoundedVec<(u32, FixedU128), ::MaxFeedValues> = vec![dot, usdc, usdt, plmc].try_into().expect("benchmarks can panic"); diff --git a/runtimes/polimec/src/lib.rs b/runtimes/polimec/src/lib.rs index db0447098..9398e1d05 100644 --- a/runtimes/polimec/src/lib.rs +++ b/runtimes/polimec/src/lib.rs @@ -34,6 +34,7 @@ use frame_support::{ TransformOrigin, }, weights::{ConstantMultiplier, Weight}, + PalletId, }; use frame_system::{EnsureRoot, EnsureRootWithSuccess, EnsureSigned, EnsureSignedBy}; use pallet_aura::Authorities; @@ -51,7 +52,7 @@ use polimec_common::credentials::{Did, EnsureInvestor}; use polkadot_runtime_common::{BlockHashCount, CurrencyToVote, SlowAdjustingFeeUpdate}; use shared_configuration::proxy; use sp_api::impl_runtime_apis; -use sp_core::{crypto::KeyTypeId, ConstU64, OpaqueMetadata}; +use sp_core::{crypto::KeyTypeId, ConstU64, ConstU8, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ @@ -1078,6 +1079,29 @@ impl pallet_funding::Config for Runtime { type WeightInfo = weights::pallet_funding::WeightInfo; } +use polimec_common::{PLMC_DECIMALS, PLMC_FOREIGN_ID, USD_DECIMALS}; +parameter_types! { + pub const FeePercentage: Perbill = Perbill::from_percent(5); + // TODO: add a real account here + pub FeeRecipient: AccountId = [0u8; 32].into(); + pub const RootId: PalletId = PalletId(*b"treasury"); +} +impl pallet_proxy_bonding::Config for Runtime { + type BondingToken = Balances; + type BondingTokenDecimals = ConstU8; + type BondingTokenId = ConstU32; + type FeePercentage = FeePercentage; + type FeeRecipient = FeeRecipient; + type FeeToken = ForeignAssets; + type Id = PalletId; + type PriceProvider = OraclePriceProvider; + type RootId = TreasuryId; + type RuntimeEvent = RuntimeEvent; + type RuntimeHoldReason = RuntimeHoldReason; + type Treasury = TreasuryAccount; + type UsdDecimals = ConstU8; +} + #[cfg(feature = "runtime-benchmarks")] parameter_types! { pub BenchmarkReason: RuntimeHoldReason = RuntimeHoldReason::Funding(pallet_funding::HoldReason::Participation); @@ -1183,6 +1207,7 @@ construct_runtime!( Funding: pallet_funding = 80, LinearRelease: pallet_linear_release = 81, + ProxyBonding: pallet_proxy_bonding = 82, } ); diff --git a/runtimes/shared-configuration/src/currency.rs b/runtimes/shared-configuration/src/currency.rs index 133647402..a8379e918 100644 --- a/runtimes/shared-configuration/src/currency.rs +++ b/runtimes/shared-configuration/src/currency.rs @@ -19,6 +19,7 @@ use frame_support::parameter_types; use pallet_funding::AcceptedFundingAsset; use pallet_oracle_ocw::types::AssetName; use parachains_common::AssetIdForTrustBackedAssets as AssetId; +use polimec_common::PLMC_FOREIGN_ID; use sp_runtime::{traits::Convert, FixedU128}; /// One PLMC @@ -88,7 +89,7 @@ impl Convert<(AssetName, FixedU128), (AssetId, Price)> for AssetPriceConverter { AssetName::DOT => (AcceptedFundingAsset::DOT.id(), price), AssetName::USDC => (AcceptedFundingAsset::USDC.id(), price), AssetName::USDT => (AcceptedFundingAsset::USDT.id(), price), - AssetName::PLMC => (pallet_funding::PLMC_FOREIGN_ID, price), + AssetName::PLMC => (PLMC_FOREIGN_ID, price), } } } diff --git a/runtimes/shared-configuration/src/funding.rs b/runtimes/shared-configuration/src/funding.rs index 10ae7350f..ee9280698 100644 --- a/runtimes/shared-configuration/src/funding.rs +++ b/runtimes/shared-configuration/src/funding.rs @@ -18,7 +18,7 @@ use crate::{Balance, BlockNumber}; use frame_support::{parameter_types, PalletId}; use pallet_funding::types::AcceptedFundingAsset; use parachains_common::AssetIdForTrustBackedAssets; -use polimec_common::USD_UNIT; +use polimec_common::{PLMC_FOREIGN_ID, USD_UNIT}; use sp_arithmetic::{FixedU128, Percent}; use sp_runtime::Perquintill; use sp_std::{collections::btree_map::BTreeMap, vec, vec::Vec}; @@ -63,7 +63,7 @@ parameter_types! { (AcceptedFundingAsset::DOT.id(), FixedU128::from_rational(69, 1)), // DOT (AcceptedFundingAsset::USDC.id(), FixedU128::from_rational(100, 100)), // USDC (AcceptedFundingAsset::USDT.id(), FixedU128::from_rational(100, 100)), // USDT - (pallet_funding::PLMC_FOREIGN_ID, FixedU128::from_rational(840, 100)), // PLMC + (PLMC_FOREIGN_ID, FixedU128::from_rational(840, 100)), // PLMC ]); pub FeeBrackets: Vec<(Percent, Balance)> = vec![ (Percent::from_percent(10), 1_000_000 * USD_UNIT),