Skip to content

Commit

Permalink
feat: for testing purposes let's assume 1 USDT = 1USD
Browse files Browse the repository at this point in the history
wip

wip: align TestBid creation

wip: switch to stable compiler

test: check the remainder

Update rust-toolchain.toml

Co-authored-by: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com>

chore(244): move dep to workspace

wip: check the ct amount

feat: restore assert_matches macro

test: add the remainder round from excel

test: add more dbg outputs

refactor: split the fees calculation login in several fn

test: cleanup debug artefacts

feat: calculate the CT amount in CT directly

fix: use the Y from the KH

feat: just return the total_fee_weight

doc: specify the denomination of the pot

test: restore the assert_matches macro

git merge --squash -Xours origin/main

Squashed commit of the following:

commit a71eff7
Author: Juan Ignacio Rios <juani.rios.99@gmail.com>
Date:   Mon Aug 14 16:20:48 2023 +0200

    feat(243): Remove T::StorageItemId and replace it with hardcoded u32

commit 368abd9
Author: Juan Ignacio Rios <juani.rios.99@gmail.com>
Date:   Mon Aug 14 16:20:48 2023 +0200

    feat(249): Remove Option from Multipliers

    feat(249): Option no longer required for multipliers

    fix(243): rebase error

    chore(243): add import

    feat(245): manual and automatic release of PLMC and funding assets implemented and tested

    feat(247): manual and automatic release of PLMC and funding assets implemented and tested

    feat(247): manual release implemented and tested

    feat(247): automatic release implemented and tested

    feat(247): automatic release implemented and tested

    feat(248): manual release implemented and tested

    feat(248): automatic release implemented and tested

    wip

    feat(242): small optimization

    chore(242): fmt

    feat(242): change week to day conversion on config type

    feat(242): small changes from Leonardo's feedback

    Update pallets/funding/src/types.rs

    Co-authored-by: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com>

    feat(244): linear increase of duration based on vesting

    wip

commit e576cdc
Author: Juan Ignacio Rios <54085674+JuaniRios@users.noreply.github.com>
Date:   Fri Aug 25 10:39:03 2023 +0100

    fix(243): rebase error (#72)

    chore(243): add import

    feat(245): manual and automatic release of PLMC and funding assets implemented and tested

    feat(247): manual and automatic release of PLMC and funding assets implemented and tested

    feat(247): manual release implemented and tested

    feat(247): automatic release implemented and tested

    feat(247): automatic release implemented and tested

    feat(248): manual release implemented and tested

    feat(248): automatic release implemented and tested

commit bdc9075
Author: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com>
Date:   Thu Aug 24 16:47:25 2023 +0200

    Update check.yml (#78)

    * Update check.yml

    * Update check.yml

commit 6894904
Author: Juan Ignacio Rios <54085674+JuaniRios@users.noreply.github.com>
Date:   Wed Aug 23 14:17:19 2023 +0100

    Feature/plmc 242 implement correct duration of vesting (#70)

    * wip

    * feat(244): linear increase of duration based on vesting

    * Update pallets/funding/src/types.rs

    Co-authored-by: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com>

    * feat(242): small changes from Leonardo's feedback

    * feat(242): change week to day conversion on config type

    * chore(242): fmt

    * feat(242): small optimization

    ---------

    Co-authored-by: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com>

commit 8057e2e
Author: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com>
Date:   Wed Aug 23 11:38:43 2023 +0200

    Update check.yml (#76)

commit b4579cc
Author: Leonardo Razovic <4128940+lrazovic@users.noreply.github.com>
Date:   Wed Aug 23 10:01:42 2023 +0200

    feat: update the CI to use paritytech/ci-linux:production (#73)

    * feat: update the CI to use paritytech/ci-linux:production

    * ci: execute fmt as a fail fast job

    * fmt: format to test the CI

    * feat: remove the check job
  • Loading branch information
lrazovic committed Aug 28, 2023
1 parent a71eff7 commit 2c31b44
Show file tree
Hide file tree
Showing 5 changed files with 613 additions and 42 deletions.
97 changes: 59 additions & 38 deletions pallets/funding/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1249,7 +1249,6 @@ impl<T: Config> Pallet<T> {
) -> Result<(), DispatchError> {
// * Get variables *
let project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectInfoNotFound)?;
let ct_price = project_details.weighted_average_price.ok_or(Error::<T>::ImpossibleState)?;
let reward_info =
if let EvaluatorsOutcome::Rewarded(info) = project_details.evaluation_round_info.evaluators_outcome {
info
Expand All @@ -1273,16 +1272,11 @@ impl<T: Config> Pallet<T> {
evaluation.late_usd_amount.saturating_add(evaluation.early_usd_amount),
reward_info.normal_evaluator_total_bonded_usd,
);
let total_reward_amount_usd = (early_reward_weight * reward_info.early_evaluator_reward_pot_usd)
.saturating_add(normal_reward_weight * reward_info.normal_evaluator_reward_pot_usd);
let reward_amount_ct: BalanceOf<T> = ct_price
.reciprocal()
.ok_or(Error::<T>::BadMath)?
.checked_mul_int(total_reward_amount_usd)
.ok_or(Error::<T>::BadMath)?;

let early_evaluators_rewards = early_reward_weight * reward_info.early_evaluator_reward_pot;
let normal_evaluators_rewards = normal_reward_weight * reward_info.normal_evaluator_reward_pot;
let total_reward_amount = early_evaluators_rewards.saturating_add(normal_evaluators_rewards);
// * Update storage *
T::ContributionTokenCurrency::mint_into(project_id, &evaluation.evaluator, reward_amount_ct)?;
T::ContributionTokenCurrency::mint_into(project_id, &evaluation.evaluator, total_reward_amount)?;
evaluation.rewarded_or_slashed = true;
Evaluations::<T>::insert((project_id, evaluator.clone(), evaluation_id), evaluation);

Expand All @@ -1291,7 +1285,7 @@ impl<T: Config> Pallet<T> {
project_id,
evaluator: evaluator.clone(),
id: evaluation_id,
amount: reward_amount_ct,
amount: total_reward_amount,
caller,
});

Expand Down Expand Up @@ -2140,44 +2134,68 @@ impl<T: Config> Pallet<T> {
Ok(())
}

pub fn calculate_fees(project_id: T::ProjectIdentifier) -> Result<BalanceOf<T>, DispatchError> {
let funding_reached =
ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectNotFound)?.funding_amount_reached;
pub fn calculate_fees(funding_reached: BalanceOf<T>) -> Perquintill {
let total_fee = Self::compute_total_fee_from_brackets(funding_reached);
Perquintill::from_rational(total_fee, funding_reached)
}

fn compute_total_fee_from_brackets(funding_reached: BalanceOf<T>) -> BalanceOf<T> {
let mut remaining_for_fee = funding_reached;

Ok(T::FeeBrackets::get()
T::FeeBrackets::get()
.into_iter()
.map(|(fee, limit)| {
let try_operation = remaining_for_fee.checked_sub(&limit);
if let Some(remaining_amount) = try_operation {
remaining_for_fee = remaining_amount;
fee * limit
} else {
let temp = remaining_for_fee;
remaining_for_fee = BalanceOf::<T>::zero();
fee * temp
}
})
.fold(BalanceOf::<T>::zero(), |acc, fee| acc.saturating_add(fee)))
.map(|(fee, limit)| Self::compute_fee_for_bracket(&mut remaining_for_fee, fee, limit))
.fold(BalanceOf::<T>::zero(), |acc, fee| acc.saturating_add(fee))
}

fn compute_fee_for_bracket(
remaining_for_fee: &mut BalanceOf<T>,
fee: Percent,
limit: BalanceOf<T>,
) -> BalanceOf<T> {
if let Some(remaining_amount) = remaining_for_fee.checked_sub(&limit) {
*remaining_for_fee = remaining_amount;
fee * limit
} else {
let fee_for_this_bracket = fee * *remaining_for_fee;
*remaining_for_fee = BalanceOf::<T>::zero();
fee_for_this_bracket
}
}

pub fn generate_evaluator_rewards_info(
project_id: <T as Config>::ProjectIdentifier,
) -> Result<RewardInfoOf<T>, DispatchError> {
let project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectNotFound)?;
let project_metadata = ProjectsMetadata::<T>::get(project_id).ok_or(Error::<T>::ProjectNotFound)?;
let evaluations = Evaluations::<T>::iter_prefix((project_id,)).collect::<Vec<_>>();

let target_funding = project_details.fundraising_target;
let funding_reached = project_details.funding_amount_reached;

// This is the "Y" variable from the knowledge hub
let percentage_of_target_funding = Perquintill::from_rational(funding_reached, target_funding);
let total_issuer_fees = Self::calculate_fees(funding_reached);

let token_sold = project_metadata
.total_allocation_size
.checked_sub(&project_details.remaining_contribution_tokens)
// This should never happen, but we still want to make sure we don't panic
.unwrap_or(project_metadata.total_allocation_size);
let total_fee_allocation = total_issuer_fees * token_sold;

let fees = Self::calculate_fees(project_id)?;
let evaluator_fees = percentage_of_target_funding * (Perquintill::from_percent(30) * fees);
// This is the "Y" variable from the Knowledge Hub. src: https://hub.polimec.org/learn/funding-process/reward-payouts#issuer-fee-allocation
let percentage_of_target_funding =
Perquintill::from_rational(funding_reached, project_details.fundraising_target);

let early_evaluator_reward_pot_usd = Perquintill::from_percent(20) * evaluator_fees;
let normal_evaluator_reward_pot_usd = Perquintill::from_percent(80) * evaluator_fees;
let evaluator_rewards = percentage_of_target_funding * Perquintill::from_percent(30) * total_fee_allocation;

// Unused and not really tested yet, but they will be handy in the future
let _liquidity_pool = Perquintill::from_percent(50) * total_fee_allocation;
let _raw_long_term_holder_bonus = Perquintill::from_percent(20) * total_fee_allocation;
let _one_minus_percentage_of_target_funding = Perquintill::from_percent(100) - percentage_of_target_funding;
let _temp = Perquintill::from_percent(30) * _one_minus_percentage_of_target_funding * total_fee_allocation;
let _long_term_holder_bonus = _raw_long_term_holder_bonus.saturating_add(_temp);

let early_evaluator_reward_pot = Perquintill::from_percent(20) * evaluator_rewards;
let normal_evaluator_reward_pot = Perquintill::from_percent(80) * evaluator_rewards;

let early_evaluator_total_bonded_usd =
evaluations.iter().fold(BalanceOf::<T>::zero(), |acc, ((_evaluator, _id), evaluation)| {
Expand All @@ -2187,14 +2205,17 @@ impl<T: Config> Pallet<T> {
evaluations.iter().fold(BalanceOf::<T>::zero(), |acc, ((_evaluator, _id), evaluation)| {
acc.saturating_add(evaluation.late_usd_amount)
});

let normal_evaluator_total_bonded_usd =
early_evaluator_total_bonded_usd.saturating_add(late_evaluator_total_bonded_usd);
Ok(RewardInfo {
early_evaluator_reward_pot_usd,
normal_evaluator_reward_pot_usd,

let reward_info = RewardInfo {
early_evaluator_reward_pot,
normal_evaluator_reward_pot,
early_evaluator_total_bonded_usd,
normal_evaluator_total_bonded_usd,
})
};
Ok(reward_info)
}

pub fn make_project_funding_successful(
Expand Down
2 changes: 1 addition & 1 deletion pallets/funding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1232,4 +1232,4 @@ pub mod local_macros {
};
}
pub(crate) use unwrap_result_or_skip;
}
}
2 changes: 1 addition & 1 deletion pallets/funding/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ parameter_types! {
pub PriceMap: BTreeMap<AssetId, FixedU128> = BTreeMap::from_iter(vec![
(0u32, FixedU128::from_float(69f64)), // DOT
(420u32, FixedU128::from_float(0.97f64)), // USDC
(1984u32, FixedU128::from_float(0.95f64)), // USDT
(1984u32, FixedU128::from_float(1.0f64)), // USDT
(2069u32, FixedU128::from_float(8.4f64)), // PLMC
]);
pub FeeBrackets: Vec<(Percent, Balance)> = vec![
Expand Down
Loading

0 comments on commit 2c31b44

Please sign in to comment.