Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

🧹 General Cleanup #450

Merged
merged 1 commit into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions pallets/funding/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,21 +542,14 @@ mod benchmarks {

// Storage
for (bid_params, price) in extrinsic_bids_post_bucketing.clone() {
let bid_filter = BidInfoFilter::<T> {
id: None,
project_id: Some(project_id),
bidder: Some(bidder.clone()),
status: Some(BidStatus::YetUnknown),
original_ct_amount: Some(bid_params.amount),
original_ct_usd_price: Some(price),
funding_asset: Some(AcceptedFundingAsset::USDT),
funding_asset_amount_locked: None,
mode: Some(bid_params.mode),
plmc_bond: None,
when: None,
};
Bids::<T>::iter_prefix_values(project_id)
.find(|stored_bid| bid_filter.matches_bid(stored_bid))
.find(|stored_bid| {
stored_bid.bidder == bidder.clone() &&
stored_bid.original_ct_amount == bid_params.amount &&
stored_bid.original_ct_usd_price == price &&
stored_bid.funding_asset == AcceptedFundingAsset::USDT &&
stored_bid.mode == bid_params.mode
})
.expect("bid not found");
}
}
Expand Down
4 changes: 4 additions & 0 deletions pallets/funding/src/functions/1_application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use super::*;

impl<T: Config> Pallet<T> {
/// Make sure the data provided by the issuer on project creation makes sense.
fn project_validation(
project_metadata: &ProjectMetadataOf<T>,
issuer: AccountIdOf<T>,
Expand Down Expand Up @@ -53,6 +54,7 @@ impl<T: Config> Pallet<T> {
Ok((project_details, bucket))
}

/// Create a new project.
#[transactional]
pub fn do_create_project(
issuer: &AccountIdOf<T>,
Expand Down Expand Up @@ -93,6 +95,7 @@ impl<T: Config> Pallet<T> {
Ok(PostDispatchInfo { actual_weight: None, pays_fee: Pays::No })
}

/// Edit the project information before starting the raise
#[transactional]
pub fn do_edit_project(
issuer: AccountIdOf<T>,
Expand Down Expand Up @@ -121,6 +124,7 @@ impl<T: Config> Pallet<T> {
Ok(PostDispatchInfo { actual_weight: None, pays_fee: Pays::No })
}

/// Remove the project before the raise started.
#[transactional]
pub fn do_remove_project(issuer: AccountIdOf<T>, project_id: ProjectId, did: Did) -> DispatchResultWithPostInfo {
// * Get variables *
Expand Down
8 changes: 4 additions & 4 deletions pallets/funding/src/functions/2_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use super::*;
use polimec_common::ProvideAssetPrice;
impl<T: Config> Pallet<T> {
/// Start the evaluation round of a project. This is how the raise is started.
#[transactional]
pub fn do_start_evaluation(caller: AccountIdOf<T>, project_id: ProjectId) -> DispatchResultWithPostInfo {
// * Get variables *
Expand Down Expand Up @@ -29,6 +30,7 @@ impl<T: Config> Pallet<T> {
Ok(PostDispatchInfo { actual_weight: None, pays_fee: Pays::No })
}

/// End the evaluation round of a project, and start the auction round.
#[transactional]
pub fn do_end_evaluation(project_id: ProjectId) -> DispatchResult {
// * Get variables *
Expand All @@ -45,10 +47,7 @@ impl<T: Config> Pallet<T> {
// * Branch in possible project paths *
// Successful path
return if is_funded {
let mut project_ids = ProjectsInAuctionRound::<T>::get().to_vec();
project_ids.push(project_id);
let project_ids = WeakBoundedVec::force_from(project_ids, None);
ProjectsInAuctionRound::<T>::put(project_ids);
ProjectsInAuctionRound::<T>::insert(project_id, ());
Self::transition_project(
project_id,
project_details,
Expand All @@ -72,6 +71,7 @@ impl<T: Config> Pallet<T> {
}
}

/// Place an evaluation on a project
#[transactional]
pub fn do_evaluate(
evaluator: &AccountIdOf<T>,
Expand Down
18 changes: 12 additions & 6 deletions pallets/funding/src/functions/3_auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use super::*;

impl<T: Config> Pallet<T> {
/// Place a bid on a project in the auction round
#[transactional]
pub fn do_bid(params: DoBidParams<T>) -> DispatchResult {
// * Get variables *
Expand Down Expand Up @@ -119,6 +120,8 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Inner function to perform bids within a bucket. do_bid makes sure to split the bid into buckets and call this as
/// many times as necessary
#[transactional]
fn do_perform_bid(do_perform_bid_params: DoPerformBidParams<T>) -> Result<BidInfoOf<T>, DispatchError> {
let DoPerformBidParams {
Expand Down Expand Up @@ -192,11 +195,13 @@ impl<T: Config> Pallet<T> {
Ok(new_bid)
}

/// Process a bid that was outbid by a new bid. This will set it to Rejected so the user can get their funds back with `settle_bid` and bid again.
pub fn do_process_next_oversubscribed_bid(project_id: ProjectId) -> DispatchResult {
// Load and validate initial state
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)?;
let mut ct_amount_oversubscribed = CTAmountOversubscribed::<T>::get(project_id);

ensure!(ct_amount_oversubscribed > Zero::zero(), Error::<T>::NoBidsOversubscribed);

// Determine the current cutoff
Expand All @@ -206,21 +211,21 @@ impl<T: Config> Pallet<T> {
if matches!(bid.status, BidStatus::PartiallyAccepted(_)) {
cutoff
} else {
let (new_price, new_index) = Self::get_next_cutoff(project_id, bucket.delta_price, bid_price, bid_index)?;
let (new_price, new_index) =
Self::get_next_cutoff(project_id, bucket.delta_price, bid_price, bid_index)?;
OutbidBidsCutoff { bid_price: new_price, bid_index: new_index }
}
},
None => {
let first_price = project_metadata.minimum_price;
let first_bounds = BidsBucketBounds::<T>::get(project_id, first_price)
.ok_or(Error::<T>::ImpossibleState)?;
let first_bounds =
BidsBucketBounds::<T>::get(project_id, first_price).ok_or(Error::<T>::ImpossibleState)?;
OutbidBidsCutoff { bid_price: first_price, bid_index: first_bounds.last_bid_index }
}
},
};

// Process the bid at the cutoff
let mut bid = Bids::<T>::get(project_id, current_cutoff.bid_index)
.ok_or(Error::<T>::ImpossibleState)?;
let mut bid = Bids::<T>::get(project_id, current_cutoff.bid_index).ok_or(Error::<T>::ImpossibleState)?;

let bid_amount = match bid.status {
BidStatus::PartiallyAccepted(amount) => amount,
Expand All @@ -244,6 +249,7 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Get the next bid that should be processed by do_process_next_oversubscribed_bid
pub fn get_next_cutoff(
project_id: ProjectId,
delta_price: PriceOf<T>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#[allow(clippy::wildcard_imports)]
use super::*;
use itertools::Itertools;

impl<T: Config> Pallet<T> {
/// End the auction round and the fundraise. Check if the raise was successful or not.
#[transactional]
pub fn do_end_funding(project_id: ProjectId) -> DispatchResult {
// * Get variables *
Expand All @@ -20,10 +20,7 @@ impl<T: Config> Pallet<T> {
);
ensure!(ct_amount_oversubscribed.is_zero(), Error::<T>::OversubscribedBidsRemaining);

let mut project_ids = ProjectsInAuctionRound::<T>::get().to_vec();
let (pos, _) = project_ids.iter().find_position(|id| **id == project_id).ok_or(Error::<T>::ImpossibleState)?;
project_ids.remove(pos);
ProjectsInAuctionRound::<T>::put(WeakBoundedVec::force_from(project_ids, None));
ProjectsInAuctionRound::<T>::remove(project_id);

let auction_allocation_size = project_metadata.total_allocation_size;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use polimec_common::{
use sp_runtime::{traits::Zero, Perquintill};

impl<T: Config> Pallet<T> {
/// Start the settlement round. Now users can mint their contribution tokens or get their funds back, and the issuer
/// will get the funds in their funding account.
#[transactional]
pub fn do_start_settlement(project_id: ProjectId) -> DispatchResult {
let mut project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;
Expand Down Expand Up @@ -104,6 +106,7 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Settle an evaluation, by maybe minting CTs, and releasing the PLMC bond.
pub fn do_settle_evaluation(evaluation: EvaluationInfoOf<T>, project_id: ProjectId) -> DispatchResult {
let project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;

Expand Down Expand Up @@ -154,6 +157,9 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Settle a bid. If bid was successful mint the CTs and release the PLMC bond (if multiplier > 1 and mode is Classic).
/// If was unsuccessful, release the PLMC bond and refund the funds.
/// If the project was successful, the issuer will get the funds.
pub fn do_settle_bid(project_id: ProjectId, bid_id: u32) -> DispatchResult {
let project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;
let project_metadata = ProjectsMetadata::<T>::get(project_id).ok_or(Error::<T>::ProjectMetadataNotFound)?;
Expand Down Expand Up @@ -261,6 +267,7 @@ impl<T: Config> Pallet<T> {
}
}

/// Mark a project as fully settled. Only once this is done we can mark migrations as completed.
pub fn do_mark_project_as_settled(project_id: ProjectId) -> DispatchResult {
let project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;
let outcome = match project_details.status {
Expand Down Expand Up @@ -288,6 +295,7 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Helper function to Mint CTs and handle the payment of new storage with "touch"
fn mint_contribution_tokens(
project_id: ProjectId,
participant: &AccountIdOf<T>,
Expand All @@ -300,6 +308,7 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Helper function to release the funding asset to the participant
fn release_funding_asset(
project_id: ProjectId,
participant: &AccountIdOf<T>,
Expand All @@ -313,7 +322,7 @@ impl<T: Config> Pallet<T> {
T::FundingCurrency::transfer(asset.id(), &project_pot, participant, amount, Preservation::Expendable)?;
Ok(())
}

/// Helper function to release the PLMC bond to the participant
fn release_participation_bond_for(participant: &AccountIdOf<T>, amount: Balance) -> DispatchResult {
if amount.is_zero() {
return Ok(());
Expand All @@ -323,6 +332,7 @@ impl<T: Config> Pallet<T> {
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,
Expand All @@ -337,6 +347,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,
Expand All @@ -361,6 +372,7 @@ impl<T: Config> Pallet<T> {
Ok(vesting_info.duration)
}

/// Slash an evaluator and transfer funds to the treasury.
fn slash_evaluator(evaluation: &EvaluationInfoOf<T>) -> Result<Balance, DispatchError> {
let slash_percentage = T::EvaluatorSlash::get();
let treasury_account = T::BlockchainOperationTreasury::get();
Expand All @@ -384,6 +396,7 @@ impl<T: Config> Pallet<T> {
Ok(evaluation.current_plmc_bond.saturating_sub(slashed_amount))
}

/// Reward an evaluator and mint CTs.
fn reward_evaluator(
project_id: ProjectId,
evaluation: &EvaluationInfoOf<T>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use xcm::v4::MaxPalletNameLen;

// Offchain migration functions
impl<T: Config> Pallet<T> {
/// Mark a project as ready for offchain migration confirmations.
#[transactional]
pub fn do_start_offchain_migration(project_id: ProjectId, caller: AccountIdOf<T>) -> DispatchResultWithPostInfo {
let mut project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectDetailsNotFound)?;
Expand All @@ -24,6 +25,7 @@ impl<T: Config> Pallet<T> {
Ok(PostDispatchInfo { actual_weight: None, pays_fee: Pays::No })
}

/// Confirm a user's migrations as completed
#[transactional]
pub fn do_confirm_offchain_migration(
project_id: ProjectId,
Expand Down
8 changes: 5 additions & 3 deletions pallets/funding/src/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ const QUERY_RESPONSE_TIME_WINDOW_BLOCKS: u32 = 20u32;
mod application;
#[path = "3_auction.rs"]
mod auction;
#[path = "7_ct_migration.rs"]
#[path = "6_ct_migration.rs"]
mod ct_migration;
#[path = "2_evaluation.rs"]
mod evaluation;
#[path = "5_funding_end.rs"]
#[path = "4_funding_end.rs"]
mod funding_end;
pub mod misc;
#[path = "6_settlement.rs"]
#[path = "5_settlement.rs"]
mod settlement;

pub mod runtime_api;
Loading