Skip to content

Commit

Permalink
Remove unnecessary bid fields
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed Aug 13, 2024
1 parent 494a503 commit 5e0e89d
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 65 deletions.
10 changes: 0 additions & 10 deletions pallets/funding/src/functions/2_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ impl<T: Config> Pallet<T> {
project_id: ProjectId,
usd_amount: BalanceOf<T>,
did: Did,
investor_type: InvestorType,
whitelisted_policy: Cid,
) -> DispatchResultWithPostInfo {
// * Get variables *
Expand All @@ -142,15 +141,6 @@ impl<T: Config> Pallet<T> {
ensure!(total_evaluations_count < T::MaxEvaluationsPerProject::get(), Error::<T>::TooManyProjectParticipations);
ensure!(user_evaluations_count < T::MaxEvaluationsPerUser::get(), Error::<T>::TooManyUserParticipations);

// * Calculate new variables *
if investor_type == InvestorType::Retail {
RetailParticipations::<T>::mutate(&did, |project_participations| {
if project_participations.contains(&project_id).not() {
// We don't care if it fails, since it means the user already has access to the max multiplier
let _ = project_participations.try_push(project_id);
}
});
}
let plmc_bond = plmc_usd_price
.reciprocal()
.ok_or(Error::<T>::BadMath)?
Expand Down
2 changes: 0 additions & 2 deletions pallets/funding/src/functions/3_auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,6 @@ impl<T: Config> Pallet<T> {
status: BidStatus::YetUnknown,
original_ct_amount: ct_amount,
original_ct_usd_price: ct_usd_price,
final_ct_amount: ct_amount,
final_ct_usd_price: ct_usd_price,
funding_asset,
funding_asset_amount_locked,
multiplier,
Expand Down
12 changes: 2 additions & 10 deletions pallets/funding/src/functions/4_contribution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,11 @@ impl<T: Config> Pallet<T> {
InvestorType::Retail => project_metadata.contributing_ticket_sizes.retail,
};
let max_multiplier = match investor_type {
InvestorType::Retail => {
RetailParticipations::<T>::mutate(&did, |project_participations| {
if project_participations.contains(&project_id).not() {
// We don't care if it fails, since it means the user already has access to the max multiplier
let _ = project_participations.try_push(project_id);
}
retail_max_multiplier_for_participations(project_participations.len() as u8)
})
},

InvestorType::Retail => RETAIL_MAX_MULTIPLIER,
InvestorType::Professional => PROFESSIONAL_MAX_MULTIPLIER,
InvestorType::Institutional => INSTITUTIONAL_MAX_MULTIPLIER,
};

// * Validity checks *
ensure!(project_policy == whitelisted_policy, Error::<T>::PolicyMismatch);
ensure!(multiplier.into() <= max_multiplier && multiplier.into() > 0u8, Error::<T>::ForbiddenMultiplier);
Expand Down
25 changes: 17 additions & 8 deletions pallets/funding/src/functions/6_settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,17 @@ impl<T: Config> Pallet<T> {
ProjectStatus::SettlementStarted(FundingOutcome::Success) => true,
_ => false,
};
let wap = project_details.weighted_average_price.ok_or(Error::<T>::ImpossibleState)?;

ensure!(
matches!(project_details.status, ProjectStatus::SettlementStarted(..)) || bid.status == BidStatus::Rejected,
Error::<T>::SettlementNotStarted
);

// Return either the full amount to refund if bid is rejected/project failed,
// or a partial amount when the wap > paid price/bid is partially accepted
let (refunded_plmc, refunded_funding_asset_amount) = Self::calculate_refund(&bid, funding_success)?;
let (final_ct_price, final_ct_amount, refunded_plmc, refunded_funding_asset_amount) =
Self::calculate_refund(&bid, funding_success, wap)?;

Self::release_participation_bond(project_id, &bid.bidder, refunded_plmc)?;
Self::release_funding_asset(project_id, &bid.bidder, refunded_funding_asset_amount, bid.funding_asset)?;
Expand All @@ -173,14 +176,14 @@ impl<T: Config> Pallet<T> {
HoldReason::Participation(project_id).into(),
)?;

Self::mint_contribution_tokens(project_id, &bid.bidder, bid.final_ct_amount)?;
Self::mint_contribution_tokens(project_id, &bid.bidder, final_ct_amount)?;

Self::create_migration(
project_id,
&bid.bidder,
bid.id,
ParticipationType::Bid,
bid.final_ct_amount,
final_ct_amount,
plmc_vesting_info.duration,
)?;

Expand All @@ -198,7 +201,8 @@ impl<T: Config> Pallet<T> {
project_id,
account: bid.bidder,
id: bid.id,
ct_amount: bid.final_ct_amount,
final_ct_amount,
final_ct_price,
});

Ok(())
Expand All @@ -209,18 +213,23 @@ impl<T: Config> Pallet<T> {
fn calculate_refund(
bid: &BidInfoOf<T>,
funding_success: bool,
) -> Result<(BalanceOf<T>, BalanceOf<T>), DispatchError> {
wap: PriceOf<T>,
) -> Result<(PriceOf<T>, BalanceOf<T>, BalanceOf<T>, BalanceOf<T>), DispatchError> {
let final_ct_usd_price = if bid.original_ct_usd_price > wap { wap } else { bid.original_ct_usd_price };

if bid.status == BidStatus::Rejected || !funding_success {
return Ok((bid.plmc_bond, bid.funding_asset_amount_locked));
return Ok((final_ct_usd_price, Zero::zero(), bid.plmc_bond, bid.funding_asset_amount_locked));
}

let new_ticket_size = bid.final_ct_usd_price.checked_mul_int(bid.final_ct_amount).ok_or(Error::<T>::BadMath)?;
let final_ct_amount = bid.final_ct_amount();

let new_ticket_size = final_ct_usd_price.checked_mul_int(final_ct_amount).ok_or(Error::<T>::BadMath)?;
let new_plmc_bond = Self::calculate_plmc_bond(new_ticket_size, bid.multiplier)?;
let new_funding_asset_amount = Self::calculate_funding_asset_amount(new_ticket_size, bid.funding_asset)?;
let refund_plmc = bid.plmc_bond.saturating_sub(new_plmc_bond);
let refund_funding_asset = bid.funding_asset_amount_locked.saturating_sub(new_funding_asset_amount);

Ok((refund_plmc, refund_funding_asset))
Ok((final_ct_usd_price, final_ct_amount, refund_plmc, refund_funding_asset))
}

pub fn do_settle_contribution(contribution: ContributionInfoOf<T>, project_id: ProjectId) -> DispatchResult {
Expand Down
10 changes: 3 additions & 7 deletions pallets/funding/src/functions/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,14 @@ impl<T: Config> Pallet<T> {
let buyable_amount = auction_allocation_size.saturating_sub(bid_token_amount_sum);
if buyable_amount.is_zero() {
bid.status = BidStatus::Rejected;
bid.final_ct_amount = Zero::zero();
} else if bid.original_ct_amount <= buyable_amount {
if bid.final_ct_usd_price > wap {
bid.final_ct_usd_price = wap;
}
bid_token_amount_sum.saturating_accrue(bid.original_ct_amount);
bid.final_ct_amount = bid.original_ct_amount;
bid.status = BidStatus::Accepted;
DidWithWinningBids::<T>::mutate(project_id, bid.did.clone(), |flag| {
*flag = true;
});
} else {
bid_token_amount_sum.saturating_accrue(buyable_amount);
bid.final_ct_amount = buyable_amount;
bid.status = BidStatus::PartiallyAccepted(buyable_amount);
DidWithWinningBids::<T>::mutate(project_id, bid.did.clone(), |flag| {
*flag = true;
Expand All @@ -118,7 +112,9 @@ impl<T: Config> Pallet<T> {
let total_auction_allocation_usd: BalanceOf<T> = accepted_bids
.into_iter()
.try_fold(Zero::zero(), |acc: BalanceOf<T>, bid: BidInfoOf<T>| {
bid.final_ct_usd_price.checked_mul_int(bid.final_ct_amount).and_then(|ticket| acc.checked_add(&ticket))
let final_ct_usd_price = if bid.original_ct_usd_price > wap { wap } else { bid.original_ct_usd_price };
let final_ct_amount = bid.final_ct_amount();
final_ct_usd_price.checked_mul_int(final_ct_amount).and_then(|usd_ticket| acc.checked_add(&usd_ticket))
})
.ok_or(Error::<T>::BadMath)?;

Expand Down
3 changes: 1 addition & 2 deletions pallets/funding/src/instantiator/chain_interactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,6 @@ impl<
project_id,
usd_amount,
generate_did_from_account(account),
InvestorType::Professional,
project_policy.clone(),
)
})?;
Expand Down Expand Up @@ -816,7 +815,7 @@ impl<
for bid in bids {
let account = bid.bidder.clone();
assert_eq!(self.execute(|| { Bids::<T>::iter_prefix_values((&project_id, &account)).count() }), 0);
let amount: BalanceOf<T> = if is_successful { bid.final_ct_amount } else { 0u64.into() };
let amount: BalanceOf<T> = bid.final_ct_amount();
self.assert_migration(project_id, account, amount, bid.id, ParticipationType::Bid, is_successful);
}
}
Expand Down
6 changes: 0 additions & 6 deletions pallets/funding/src/instantiator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,12 +399,6 @@ impl<T: Config> BidInfoFilter<T> {
if self.original_ct_usd_price.is_some() && self.original_ct_usd_price.unwrap() != bid.original_ct_usd_price {
return false;
}
if self.final_ct_amount.is_some() && self.final_ct_amount.unwrap() != bid.final_ct_amount {
return false;
}
if self.final_ct_usd_price.is_some() && self.final_ct_usd_price.unwrap() != bid.final_ct_usd_price {
return false;
}
if self.funding_asset.is_some() && self.funding_asset.unwrap() != bid.funding_asset {
return false;
}
Expand Down
11 changes: 4 additions & 7 deletions pallets/funding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,10 +521,6 @@ pub mod pallet {
BalanceOf<T>,
ValueQuery,
>;
#[pallet::storage]
// After 25 participations, the retail user has access to the max multiplier of 10x, so no need to keep tracking it
pub type RetailParticipations<T: Config> =
StorageMap<_, Blake2_128Concat, Did, BoundedVec<ProjectId, MaxParticipationsForMaxMultiplier>, ValueQuery>;

#[pallet::storage]
pub type UserMigrations<T: Config> = StorageNMap<
Expand Down Expand Up @@ -629,7 +625,8 @@ pub mod pallet {
project_id: ProjectId,
account: AccountIdOf<T>,
id: u32,
ct_amount: BalanceOf<T>,
final_ct_amount: BalanceOf<T>,
final_ct_price: PriceOf<T>,
},
ContributionSettled {
project_id: ProjectId,
Expand Down Expand Up @@ -869,10 +866,10 @@ pub mod pallet {
project_id: ProjectId,
#[pallet::compact] usd_amount: BalanceOf<T>,
) -> DispatchResultWithPostInfo {
let (account, did, investor_type, whitelisted_policy) =
let (account, did, _investor_type, whitelisted_policy) =
T::InvestorOrigin::ensure_origin(origin, &jwt, T::VerifierPublicKey::get())?;

Self::do_evaluate(&account, project_id, usd_amount, did, investor_type, whitelisted_policy)
Self::do_evaluate(&account, project_id, usd_amount, did, whitelisted_policy)
}

#[pallet::call_index(5)]
Expand Down
2 changes: 1 addition & 1 deletion pallets/funding/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl<T: Config> Pallet<T> {

pub fn top_bids(project_id: ProjectId, amount: u32) -> Vec<BidInfoOf<T>> {
Bids::<T>::iter_prefix_values((project_id,))
.sorted_by(|a, b| b.final_ct_amount.cmp(&a.final_ct_amount))
.sorted_by(|a, b| b.final_ct_amount().cmp(&a.final_ct_amount()))
.take(amount as usize)
.collect_vec()
}
Expand Down
25 changes: 13 additions & 12 deletions pallets/funding/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,22 +149,14 @@ pub mod config_types {
}
}

pub type MaxParticipationsForMaxMultiplier = ConstU32<25>;
pub const fn retail_max_multiplier_for_participations(participations: u8) -> u8 {
match participations {
0..=2 => 1,
3..=4 => 2,
5..=9 => 4,
10..=24 => 7,
25..=u8::MAX => 10,
}
}
pub const RETAIL_MAX_MULTIPLIER: u8 = 5u8;
pub const PROFESSIONAL_MAX_MULTIPLIER: u8 = 10u8;
pub const INSTITUTIONAL_MAX_MULTIPLIER: u8 = 25u8;
}

pub mod storage_types {
use super::*;
use sp_runtime::traits::Zero;

#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo, Serialize, Deserialize)]
pub struct ProjectMetadata<BoundedString, Balance: PartialOrd + Copy, Price: FixedPointNumber, AccountId, Cid> {
Expand Down Expand Up @@ -383,14 +375,23 @@ pub mod storage_types {
#[codec(compact)]
pub original_ct_amount: Balance,
pub original_ct_usd_price: Price,
pub final_ct_amount: Balance,
pub final_ct_usd_price: Price,
pub funding_asset: AcceptedFundingAsset,
pub funding_asset_amount_locked: Balance,
pub multiplier: Multiplier,
pub plmc_bond: Balance,
pub when: BlockNumber,
}
impl<ProjectId, Did, Balance: BalanceT, Price: FixedPointNumber, AccountId, BlockNumber, Multiplier>
BidInfo<ProjectId, Did, Balance, Price, AccountId, BlockNumber, Multiplier>
{
pub fn final_ct_amount(&self) -> Balance {
match self.status {
BidStatus::Accepted => self.original_ct_amount,
BidStatus::PartiallyAccepted(amount) => amount,
_ => Zero::zero(),
}
}
}

impl<
ProjectId: Eq,
Expand Down

0 comments on commit 5e0e89d

Please sign in to comment.