Skip to content
Closed
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
2 changes: 1 addition & 1 deletion pallets/funding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ sp-arithmetic.workspace = true
polimec-common.workspace = true
parachains-common.workspace = true
sp-core.workspace = true
pallet-balances.workspace = true
xcm.workspace = true
xcm-executor.workspace = true
polkadot-parachain-primitives.workspace = true
Expand All @@ -54,6 +53,7 @@ cumulus-pallet-parachain-system.workspace = true
cumulus-primitives-core.workspace = true

[dev-dependencies]
pallet-balances.workspace = true
pallet-timestamp.workspace = true
pallet-assets.workspace = true
pallet-linear-release.workspace = true
Expand Down
3 changes: 1 addition & 2 deletions pallets/funding/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,11 @@ pub fn string_account<AccountId: Decode>(

#[benchmarks(
where
T: Config + frame_system::Config<RuntimeEvent = <T as Config>::RuntimeEvent> + pallet_balances::Config<Balance = Balance> + cumulus_pallet_parachain_system::Config + core::fmt::Debug,
T: Config + frame_system::Config<RuntimeEvent = <T as Config>::RuntimeEvent> + cumulus_pallet_parachain_system::Config + core::fmt::Debug,
<T as Config>::RuntimeEvent: TryInto<Event<T>> + Parameter + Member,
<T as Config>::Price: From<u128>,
T::Hash: From<H256>,
<T as frame_system::Config>::AccountId: Into<<<T as frame_system::Config>::RuntimeOrigin as OriginTrait>::AccountId> + core::fmt::Debug,
<T as pallet_balances::Config>::Balance: Into<Balance>,
)]
mod benchmarks {
use super::*;
Expand Down
6 changes: 3 additions & 3 deletions pallets/funding/src/functions/1_application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl<T: Config> Pallet<T> {
status: ProjectStatus::Application,
round_duration: BlockNumberPair::new(None, None),
remaining_contribution_tokens: project_metadata.total_allocation_size,
funding_amount_reached_usd: Balance::zero(),
funding_amount_reached_usd: BalanceOf::<T>::zero(),
evaluation_round_info: EvaluationRoundInfo {
total_bonded_usd: Zero::zero(),
total_bonded_plmc: Zero::zero(),
Expand Down Expand Up @@ -73,10 +73,10 @@ impl<T: Config> Pallet<T> {
// This should be paid by the issuer.
let escrow_account = Self::fund_account_id(project_id);
// transfer ED from issuer to escrow
T::NativeCurrency::transfer(
NativeCurrencyOf::<T>::transfer(
issuer,
&escrow_account,
<T as pallet_balances::Config>::ExistentialDeposit::get(),
NativeCurrencyOf::<T>::minimum_balance(),
Preservation::Preserve,
)
.map_err(|_| Error::<T>::IssuerNotEnoughFunds)?;
Expand Down
4 changes: 2 additions & 2 deletions pallets/funding/src/functions/2_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<T: Config> Pallet<T> {
pub fn do_evaluate(
evaluator: &AccountIdOf<T>,
project_id: ProjectId,
usd_amount: Balance,
usd_amount: BalanceOf<T>,
did: Did,
whitelisted_policy: Cid,
receiving_account: Junction,
Expand Down Expand Up @@ -140,7 +140,7 @@ impl<T: Config> Pallet<T> {
receiving_account,
};

T::NativeCurrency::hold(&HoldReason::Evaluation.into(), evaluator, plmc_bond)?;
NativeCurrencyOf::<T>::hold(&HoldReason::Evaluation.into(), evaluator, plmc_bond)?;
Evaluations::<T>::insert((project_id, evaluator, evaluation_id), new_evaluation);
NextEvaluationId::<T>::set(evaluation_id.saturating_add(One::one()));
evaluation_round_info.total_bonded_usd = evaluation_round_info.total_bonded_usd.saturating_add(usd_amount);
Expand Down
30 changes: 15 additions & 15 deletions pallets/funding/src/functions/5_settlement.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[allow(clippy::wildcard_imports)]
use super::*;
use crate::{traits::VestingDurationCalculation, Balance};
use crate::{traits::VestingDurationCalculation, BalanceOf};
use frame_support::{
dispatch::DispatchResult,
ensure,
Expand Down Expand Up @@ -115,15 +115,15 @@ impl<T: Config> Pallet<T> {
Error::<T>::SettlementNotStarted
);

let (plmc_released, ct_rewarded): (Balance, Balance) =
let (plmc_released, ct_rewarded): (BalanceOf<T>, BalanceOf<T>) =
match project_details.evaluation_round_info.evaluators_outcome {
Some(EvaluatorsOutcome::Slashed) => (Self::slash_evaluator(&evaluation)?, Zero::zero()),
Some(EvaluatorsOutcome::Rewarded(info)) => Self::reward_evaluator(project_id, &evaluation, &info)?,
None => (evaluation.current_plmc_bond, Zero::zero()),
};

// Release the held PLMC bond
T::NativeCurrency::release(
NativeCurrencyOf::<T>::release(
&HoldReason::Evaluation.into(),
&evaluation.evaluator,
plmc_released,
Expand Down Expand Up @@ -183,7 +183,7 @@ impl<T: Config> Pallet<T> {
Self::release_funding_asset(project_id, &bid.bidder, refunded_funding_asset_amount, bid.funding_asset)?;

if bid.mode == ParticipationMode::OTM {
if refunded_plmc > T::NativeCurrency::minimum_balance() {
if refunded_plmc > NativeCurrencyOf::<T>::minimum_balance() {
<pallet_proxy_bonding::Pallet<T>>::refund_fee(
project_id,
&bid.bidder,
Expand Down Expand Up @@ -297,7 +297,7 @@ impl<T: Config> Pallet<T> {
fn mint_contribution_tokens(
project_id: ProjectId,
participant: &AccountIdOf<T>,
amount: Balance,
amount: BalanceOf<T>,
) -> DispatchResult {
if !T::ContributionTokenCurrency::contains(&project_id, participant) {
T::ContributionTokenCurrency::touch(project_id, participant, participant)?;
Expand All @@ -310,7 +310,7 @@ impl<T: Config> Pallet<T> {
fn release_funding_asset(
project_id: ProjectId,
participant: &AccountIdOf<T>,
amount: Balance,
amount: BalanceOf<T>,
asset: AcceptedFundingAsset,
) -> DispatchResult {
if amount.is_zero() {
Expand All @@ -322,19 +322,19 @@ impl<T: Config> Pallet<T> {
}

/// Helper function to release the PLMC bond to the participant
fn release_participation_bond_for(participant: &AccountIdOf<T>, amount: Balance) -> DispatchResult {
fn release_participation_bond_for(participant: &AccountIdOf<T>, amount: BalanceOf<T>) -> DispatchResult {
if amount.is_zero() {
return Ok(());
}
// Release the held PLMC bond
T::NativeCurrency::release(&HoldReason::Participation.into(), participant, amount, Precision::Exact)?;
NativeCurrencyOf::<T>::release(&HoldReason::Participation.into(), participant, amount, Precision::Exact)?;
Ok(())
}

/// Set the PLMC release schedule if mode was `Classic`. Return the schedule either way.
fn set_plmc_bond_release_with_mode(
participant: AccountIdOf<T>,
plmc_amount: Balance,
plmc_amount: BalanceOf<T>,
mode: ParticipationMode,
funding_end_block: BlockNumberFor<T>,
) -> Result<BlockNumberFor<T>, DispatchError> {
Expand All @@ -349,7 +349,7 @@ impl<T: Config> Pallet<T> {
/// Calculate the vesting info and add the PLMC release schedule to the user, or fully release the funds if possible.
fn set_release_schedule_for(
participant: &AccountIdOf<T>,
plmc_amount: Balance,
plmc_amount: BalanceOf<T>,
multiplier: MultiplierOf<T>,
funding_end_block: BlockNumberFor<T>,
) -> Result<BlockNumberFor<T>, DispatchError> {
Expand All @@ -372,15 +372,15 @@ impl<T: Config> Pallet<T> {
}

/// Slash an evaluator and transfer funds to the treasury.
fn slash_evaluator(evaluation: &EvaluationInfoOf<T>) -> Result<Balance, DispatchError> {
fn slash_evaluator(evaluation: &EvaluationInfoOf<T>) -> Result<BalanceOf<T>, DispatchError> {
let slash_percentage = T::EvaluatorSlash::get();
let treasury_account = T::BlockchainOperationTreasury::get();

// * Calculate variables *
// We need to make sure that the current PLMC bond is always >= than the slash amount.
let slashed_amount = slash_percentage * evaluation.original_plmc_bond;

T::NativeCurrency::transfer_on_hold(
NativeCurrencyOf::<T>::transfer_on_hold(
&HoldReason::Evaluation.into(),
&evaluation.evaluator,
&treasury_account,
Expand All @@ -400,14 +400,14 @@ impl<T: Config> Pallet<T> {
project_id: ProjectId,
evaluation: &EvaluationInfoOf<T>,
info: &RewardInfo,
) -> Result<(Balance, Balance), DispatchError> {
) -> Result<(BalanceOf<T>, BalanceOf<T>), DispatchError> {
let reward = Self::calculate_evaluator_reward(evaluation, info);
Self::mint_contribution_tokens(project_id, &evaluation.evaluator, reward)?;

Ok((evaluation.current_plmc_bond, reward))
}

pub fn calculate_evaluator_reward(evaluation: &EvaluationInfoOf<T>, info: &RewardInfo) -> Balance {
pub fn calculate_evaluator_reward(evaluation: &EvaluationInfoOf<T>, info: &RewardInfo) -> BalanceOf<T> {
let early_reward_weight =
Perquintill::from_rational(evaluation.early_usd_amount, info.early_evaluator_total_bonded_usd);
let normal_reward_weight = Perquintill::from_rational(
Expand All @@ -423,7 +423,7 @@ impl<T: Config> Pallet<T> {
project_id: ProjectId,
origin: &AccountIdOf<T>,
participation_type: ParticipationType,
ct_amount: Balance,
ct_amount: BalanceOf<T>,
vesting_time: BlockNumberFor<T>,
receiving_account: Junction,
) -> DispatchResult {
Expand Down
43 changes: 27 additions & 16 deletions pallets/funding/src/functions/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ impl<T: Config> Pallet<T> {
Ok(bucket)
}

pub fn calculate_plmc_bond(ticket_size: Balance, multiplier: MultiplierOf<T>) -> Result<Balance, DispatchError> {
pub fn calculate_plmc_bond(
ticket_size: BalanceOf<T>,
multiplier: MultiplierOf<T>,
) -> Result<BalanceOf<T>, DispatchError> {
let plmc_usd_price =
<PriceProviderOf<T>>::get_decimals_aware_price(Location::here(), USD_DECIMALS, PLMC_DECIMALS)
.ok_or(Error::<T>::PriceNotFound)?;
Expand All @@ -49,9 +52,9 @@ impl<T: Config> Pallet<T> {
}

pub fn calculate_funding_asset_amount(
ticket_size: Balance,
ticket_size: BalanceOf<T>,
asset_id: AcceptedFundingAsset,
) -> Result<Balance, DispatchError> {
) -> Result<BalanceOf<T>, DispatchError> {
let asset_id = asset_id.id();
let asset_decimals = T::FundingCurrency::decimals(asset_id.clone());
let asset_usd_price = <PriceProviderOf<T>>::get_decimals_aware_price(asset_id, USD_DECIMALS, asset_decimals)
Expand All @@ -67,7 +70,7 @@ impl<T: Config> Pallet<T> {
pub fn calculate_vesting_info(
_caller: &AccountIdOf<T>,
multiplier: MultiplierOf<T>,
bonded_amount: Balance,
bonded_amount: BalanceOf<T>,
) -> Result<VestingInfo<BlockNumberFor<T>>, DispatchError> {
let duration: BlockNumberFor<T> = multiplier.calculate_vesting_duration::<T>();
let duration_as_balance = T::BlockNumberToBalance::convert(duration);
Expand All @@ -83,7 +86,7 @@ impl<T: Config> Pallet<T> {
pub fn bond_plmc_with_mode(
who: &T::AccountId,
project_id: ProjectId,
amount: Balance,
amount: BalanceOf<T>,
mode: ParticipationMode,
asset: AcceptedFundingAsset,
) -> DispatchResult {
Expand All @@ -99,7 +102,11 @@ impl<T: Config> Pallet<T> {
}
}

pub fn try_plmc_participation_lock(who: &T::AccountId, project_id: ProjectId, amount: Balance) -> DispatchResult {
pub fn try_plmc_participation_lock(
who: &T::AccountId,
project_id: ProjectId,
amount: BalanceOf<T>,
) -> DispatchResult {
// Check if the user has already locked tokens in the evaluation period
let user_evaluations = Evaluations::<T>::iter_prefix_values((project_id, who));

Expand All @@ -113,14 +120,14 @@ impl<T: Config> Pallet<T> {
let converted = to_convert.min(available_to_convert);
evaluation.current_plmc_bond = evaluation.current_plmc_bond.saturating_sub(converted);
Evaluations::<T>::insert((project_id, who, evaluation.id), evaluation);
T::NativeCurrency::release(&HoldReason::Evaluation.into(), who, converted, Precision::Exact)
NativeCurrencyOf::<T>::release(&HoldReason::Evaluation.into(), who, converted, Precision::Exact)
.map_err(|_| Error::<T>::ImpossibleState)?;
T::NativeCurrency::hold(&HoldReason::Participation.into(), who, converted)
NativeCurrencyOf::<T>::hold(&HoldReason::Participation.into(), who, converted)
.map_err(|_| Error::<T>::ImpossibleState)?;
to_convert = to_convert.saturating_sub(converted)
}

T::NativeCurrency::hold(&HoldReason::Participation.into(), who, to_convert)
NativeCurrencyOf::<T>::hold(&HoldReason::Participation.into(), who, to_convert)
.map_err(|_| Error::<T>::ParticipantNotEnoughFunds)?;

Ok(())
Expand All @@ -130,7 +137,7 @@ impl<T: Config> Pallet<T> {
pub fn try_funding_asset_hold(
who: &T::AccountId,
project_id: ProjectId,
amount: Balance,
amount: BalanceOf<T>,
asset_id: AssetIdOf<T>,
) -> DispatchResult {
let fund_account = Self::fund_account_id(project_id);
Expand All @@ -142,7 +149,7 @@ impl<T: Config> Pallet<T> {
}

// Calculate the total fee allocation for a project, based on the funding reached.
fn calculate_fee_allocation(project_id: ProjectId) -> Result<Balance, DispatchError> {
fn calculate_fee_allocation(project_id: ProjectId) -> Result<BalanceOf<T>, DispatchError> {
let project_metadata = ProjectsMetadata::<T>::get(project_id).ok_or(Error::<T>::ProjectMetadataNotFound)?;
let bucket = Buckets::<T>::get(project_id).ok_or(Error::<T>::BucketNotFound)?;
// Fetching the necessary data for a specific project.
Expand All @@ -164,23 +171,27 @@ impl<T: Config> Pallet<T> {
}

/// Computes the total fee from all defined fee brackets.
fn compute_total_fee_from_brackets(funding_reached: Balance) -> Balance {
fn compute_total_fee_from_brackets(funding_reached: BalanceOf<T>) -> BalanceOf<T> {
let mut remaining_for_fee = funding_reached;

T::FeeBrackets::get()
.into_iter()
.map(|(fee, limit)| Self::compute_fee_for_bracket(&mut remaining_for_fee, fee, limit))
.fold(Balance::zero(), |acc, fee| acc.saturating_add(fee))
.fold(BalanceOf::<T>::zero(), |acc, fee| acc.saturating_add(fee))
}

/// Calculate the fee for a particular bracket.
fn compute_fee_for_bracket(remaining_for_fee: &mut Balance, fee: Percent, limit: Balance) -> Balance {
fn compute_fee_for_bracket(
remaining_for_fee: &mut BalanceOf<T>,
fee: Percent,
limit: BalanceOf<T>,
) -> BalanceOf<T> {
if let Some(amount_to_bid) = remaining_for_fee.checked_sub(limit) {
*remaining_for_fee = amount_to_bid;
fee * limit
} else {
let fee_for_this_bracket = fee * *remaining_for_fee;
*remaining_for_fee = Balance::zero();
*remaining_for_fee = BalanceOf::<T>::zero();
fee_for_this_bracket
}
}
Expand Down Expand Up @@ -224,7 +235,7 @@ impl<T: Config> Pallet<T> {

pub fn generate_liquidity_pools_and_long_term_holder_rewards(
project_id: ProjectId,
) -> Result<(Balance, Balance), DispatchError> {
) -> Result<(BalanceOf<T>, BalanceOf<T>), DispatchError> {
let total_fee_allocation = Self::calculate_fee_allocation(project_id)?;

let liquidity_pools_percentage = Perquintill::from_percent(50);
Expand Down
Loading