Skip to content

Commit

Permalink
pallet funding OTM integration
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed Sep 18, 2024
1 parent b13ff8f commit 3849071
Show file tree
Hide file tree
Showing 30 changed files with 350 additions and 202 deletions.
38 changes: 20 additions & 18 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
4 changes: 4 additions & 0 deletions pallets/funding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -95,6 +96,7 @@ std = [
"xcm-builder/std",
"xcm-executor/std",
"xcm/std",
"pallet-proxy-bonding/std"
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
Expand All @@ -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",
Expand All @@ -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 = []
6 changes: 3 additions & 3 deletions pallets/funding/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
];

Expand Down Expand Up @@ -1078,7 +1078,7 @@ mod benchmarks {
jwt,
project_id,
contributions[0].amount,
contributions[0].multiplier,
contributions[0].mode,
contributions[0].asset,
);

Expand Down Expand Up @@ -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,
multiplier: contributions[0].mode,
}
.into(),
);
Expand Down
5 changes: 3 additions & 2 deletions pallets/funding/src/functions/2_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,9 @@ impl<T: Config> Pallet<T> {
let mut project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;
let now = <frame_system::Pallet<T>>::block_number();
let evaluation_id = NextEvaluationId::<T>::get();
let plmc_usd_price = T::PriceProvider::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS)
.ok_or(Error::<T>::PriceNotFound)?;
let plmc_usd_price =
<PriceProviderOf<T>>::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS)
.ok_or(Error::<T>::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;
Expand Down
11 changes: 6 additions & 5 deletions pallets/funding/src/functions/4_contribution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl<T: Config> Pallet<T> {
contributor,
project_id,
ct_amount: token_amount,
multiplier,
mode,
funding_asset,
investor_type,
did,
Expand Down Expand Up @@ -48,7 +48,7 @@ impl<T: Config> Pallet<T> {
project_id,
project_details: &mut project_details,
buyable_tokens,
multiplier,
mode,
funding_asset,
investor_type,
did,
Expand All @@ -65,7 +65,7 @@ impl<T: Config> Pallet<T> {
project_id,
project_details,
buyable_tokens,
multiplier,
mode,
funding_asset,
investor_type,
did,
Expand All @@ -91,6 +91,7 @@ impl<T: Config> Pallet<T> {
InvestorType::Professional => PROFESSIONAL_MAX_MULTIPLIER,
InvestorType::Institutional => INSTITUTIONAL_MAX_MULTIPLIER,
};
let multiplier: MultiplierOf<T> = mode.multiplier().try_into().map_err(|_| Error::<T>::ForbiddenMultiplier)?;

// * Validity checks *
ensure!(project_policy == whitelisted_policy, Error::<T>::PolicyMismatch);
Expand Down Expand Up @@ -125,15 +126,15 @@ impl<T: Config> Pallet<T> {
contributor: contributor.clone(),
ct_amount: buyable_tokens,
usd_contribution_amount: ticket_size,
multiplier,
mode: mode.clone(),
funding_asset,
funding_asset_amount,
plmc_bond,
when: now,
};

// 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::<T>::insert((project_id, contributor.clone(), contribution_id), &new_contribution);
Expand Down
73 changes: 50 additions & 23 deletions pallets/funding/src/functions/6_settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl<T: Config> Pallet<T> {
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 {
Expand All @@ -162,7 +162,7 @@ impl<T: Config> Pallet<T> {
.map_err(|_| Error::<T>::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::<T>::add_release_schedule(
&bid.bidder,
Expand Down Expand Up @@ -245,7 +245,7 @@ impl<T: Config> Pallet<T> {

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,
Expand All @@ -254,25 +254,13 @@ impl<T: Config> Pallet<T> {
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::<T>::BadMath)?;

if vesting_info.duration == 1u32.into() {
Self::release_participation_bond(&contribution.contributor, vesting_info.total_amount)?;
} else {
VestingOf::<T>::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)?;
Expand All @@ -292,7 +280,7 @@ impl<T: Config> Pallet<T> {
contribution.id,
ParticipationType::Contribution,
contribution.ct_amount,
vesting_info.duration,
ct_vesting_duration
)?;

final_ct_amount = contribution.ct_amount;
Expand Down Expand Up @@ -367,7 +355,14 @@ impl<T: Config> Pallet<T> {
Ok(())
}

fn release_participation_bond(participant: &AccountIdOf<T>, amount: Balance) -> DispatchResult {
fn unbond_participation_with_mode(participant: AccountIdOf<T>, 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<T>, amount: Balance) -> DispatchResult {
if amount.is_zero() {
return Ok(());
}
Expand All @@ -376,6 +371,38 @@ impl<T: Config> Pallet<T> {
Ok(())
}

fn set_bond_release_with_mode(participant: AccountIdOf<T>, plmc_amount: Balance, mode: ParticipationMode, funding_end_block: BlockNumberFor<T>) -> Result<BlockNumberFor<T>, DispatchError> {
let multiplier = mode.multiplier().try_into().map_err(|_| Error::<T>::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<T>, plmc_amount: Balance, multiplier: MultiplierOf<T>, funding_end_block: BlockNumberFor<T>) -> Result<BlockNumberFor<T>, DispatchError> {
// Calculate the vesting info and add the release schedule
let vesting_info = Self::calculate_vesting_info(
participant,
multiplier,
plmc_amount,
)
.map_err(|_| Error::<T>::BadMath)?;

if vesting_info.duration == 1u32.into() {
Self::release_participation_bond_for(participant, vesting_info.total_amount)?;
} else {
VestingOf::<T>::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<T>) -> Result<Balance, DispatchError> {
let slash_percentage = T::EvaluatorSlash::get();
let treasury_account = T::BlockchainOperationTreasury::get();
Expand Down
26 changes: 23 additions & 3 deletions pallets/funding/src/functions/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ impl<T: Config> Pallet<T> {
}

pub fn calculate_plmc_bond(ticket_size: Balance, multiplier: MultiplierOf<T>) -> Result<Balance, DispatchError> {
let plmc_usd_price = T::PriceProvider::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS)
.ok_or(Error::<T>::PriceNotFound)?;
let plmc_usd_price =
<PriceProviderOf<T>>::get_decimals_aware_price(PLMC_FOREIGN_ID, USD_DECIMALS, PLMC_DECIMALS)
.ok_or(Error::<T>::PriceNotFound)?;
let usd_bond = multiplier.calculate_bonding_requirement::<T>(ticket_size).ok_or(Error::<T>::BadMath)?;
plmc_usd_price
.reciprocal()
Expand All @@ -45,7 +46,7 @@ impl<T: Config> Pallet<T> {
) -> Result<Balance, DispatchError> {
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 = <PriceProviderOf<T>>::get_decimals_aware_price(asset_id, USD_DECIMALS, asset_decimals)
.ok_or(Error::<T>::PriceNotFound)?;
asset_usd_price
.reciprocal()
Expand Down Expand Up @@ -130,6 +131,25 @@ impl<T: Config> Pallet<T> {
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::<T>::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::<T>::iter_prefix_values((project_id, who));
Expand Down
Loading

0 comments on commit 3849071

Please sign in to comment.