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 2, 2024
1 parent 0e334fa commit 75c005f
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 61 deletions.
9 changes: 0 additions & 9 deletions pallets/funding/src/functions/2_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,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 @@ -252,8 +252,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
29 changes: 21 additions & 8 deletions pallets/funding/src/functions/6_settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,16 @@ 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
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 @@ -172,14 +175,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 @@ -197,7 +200,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 @@ -208,18 +212,27 @@ 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 = match bid.status {
BidStatus::Accepted => bid.original_ct_amount,
BidStatus::PartiallyAccepted(amount) => amount,
_ => Zero::zero(),
};

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 mut refund_plmc = bid.plmc_bond.saturating_sub(new_plmc_bond);
let mut 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
15 changes: 8 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,14 @@ 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 = match bid.status {
BidStatus::Accepted => bid.original_ct_amount,
BidStatus::PartiallyAccepted(amount) => amount,
_ => Zero::zero(),
};

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
7 changes: 6 additions & 1 deletion pallets/funding/src/instantiator/chain_interactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,12 @@ 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> = match bid.status {
BidStatus::Accepted => bid.original_ct_amount,
BidStatus::PartiallyAccepted(amount) => amount,
BidStatus::Rejected => 0u64.into(),
BidStatus::YetUnknown => {panic!("Bid should have a different status than YetUnknown")}
};
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
7 changes: 2 additions & 5 deletions pallets/funding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,10 +522,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 @@ -630,7 +626,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
17 changes: 16 additions & 1 deletion pallets/funding/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,22 @@ 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| {
let a_final_ct_amount = match a.status {
BidStatus::YetUnknown => {panic!("Something on-chain went very wrong")}
BidStatus::Accepted => {a.original_ct_amount}
BidStatus::Rejected => {Zero::zero()}
BidStatus::PartiallyAccepted(amount) => {amount}
} ;

let b_final_ct_amount = match b.status {
BidStatus::YetUnknown => {panic!("Something on-chain went very wrong")}
BidStatus::Accepted => {b.original_ct_amount}
BidStatus::Rejected => {Zero::zero()}
BidStatus::PartiallyAccepted(amount) => {amount}
} ;
b_final_ct_amount.cmp(&a_final_ct_amount)
})
.take(amount as usize)
.collect_vec()
}
Expand Down
13 changes: 1 addition & 12 deletions pallets/funding/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,16 +149,7 @@ 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;
}
Expand Down Expand Up @@ -383,8 +374,6 @@ 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,
Expand Down

0 comments on commit 75c005f

Please sign in to comment.