mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
Do not allow death on Crowdloan contribute + Introduce contribute_all (#4233)
* Add contirbute all, do not allow death on contribute * fmt * Revert "fmt" This reverts commit c4746e336ac105b1318d8ec6f4cebf504f5d2fba. * fmt
This commit is contained in:
@@ -55,9 +55,13 @@ use crate::{
|
||||
};
|
||||
use frame_support::{
|
||||
ensure,
|
||||
pallet_prelude::Weight,
|
||||
pallet_prelude::{DispatchResult, Weight},
|
||||
storage::{child, ChildTriePrefixIterator},
|
||||
traits::{Currency, ExistenceRequirement::AllowDeath, Get, ReservableCurrency},
|
||||
traits::{
|
||||
Currency,
|
||||
ExistenceRequirement::{self, AllowDeath, KeepAlive},
|
||||
Get, ReservableCurrency,
|
||||
},
|
||||
Identity, PalletId,
|
||||
};
|
||||
pub use pallet::*;
|
||||
@@ -444,81 +448,7 @@ pub mod pallet {
|
||||
signature: Option<MultiSignature>,
|
||||
) -> DispatchResult {
|
||||
let who = ensure_signed(origin)?;
|
||||
|
||||
ensure!(value >= T::MinContribution::get(), Error::<T>::ContributionTooSmall);
|
||||
let mut fund = Self::funds(index).ok_or(Error::<T>::InvalidParaId)?;
|
||||
fund.raised = fund.raised.checked_add(&value).ok_or(Error::<T>::Overflow)?;
|
||||
ensure!(fund.raised <= fund.cap, Error::<T>::CapExceeded);
|
||||
|
||||
// Make sure crowdloan has not ended
|
||||
let now = <frame_system::Pallet<T>>::block_number();
|
||||
ensure!(now < fund.end, Error::<T>::ContributionPeriodOver);
|
||||
|
||||
// Make sure crowdloan is in a valid lease period
|
||||
let now = frame_system::Pallet::<T>::block_number();
|
||||
let (current_lease_period, _) =
|
||||
T::Auctioneer::lease_period_index(now).ok_or(Error::<T>::NoLeasePeriod)?;
|
||||
ensure!(current_lease_period <= fund.first_period, Error::<T>::ContributionPeriodOver);
|
||||
|
||||
// Make sure crowdloan has not already won.
|
||||
let fund_account = Self::fund_account_id(index);
|
||||
ensure!(
|
||||
!T::Auctioneer::has_won_an_auction(index, &fund_account),
|
||||
Error::<T>::BidOrLeaseActive
|
||||
);
|
||||
|
||||
// We disallow any crowdloan contributions during the VRF Period, so that people do not sneak their
|
||||
// contributions into the auction when it would not impact the outcome.
|
||||
ensure!(!T::Auctioneer::auction_status(now).is_vrf(), Error::<T>::VrfDelayInProgress);
|
||||
|
||||
let (old_balance, memo) = Self::contribution_get(fund.trie_index, &who);
|
||||
|
||||
if let Some(ref verifier) = fund.verifier {
|
||||
let signature = signature.ok_or(Error::<T>::InvalidSignature)?;
|
||||
let payload = (index, &who, old_balance, value);
|
||||
let valid = payload.using_encoded(|encoded| {
|
||||
signature.verify(encoded, &verifier.clone().into_account())
|
||||
});
|
||||
ensure!(valid, Error::<T>::InvalidSignature);
|
||||
}
|
||||
|
||||
CurrencyOf::<T>::transfer(&who, &fund_account, value, AllowDeath)?;
|
||||
|
||||
let balance = old_balance.saturating_add(value);
|
||||
Self::contribution_put(fund.trie_index, &who, &balance, &memo);
|
||||
|
||||
if T::Auctioneer::auction_status(now).is_ending().is_some() {
|
||||
match fund.last_contribution {
|
||||
// In ending period; must ensure that we are in NewRaise.
|
||||
LastContribution::Ending(n) if n == now => {
|
||||
// do nothing - already in NewRaise
|
||||
},
|
||||
_ => {
|
||||
NewRaise::<T>::append(index);
|
||||
fund.last_contribution = LastContribution::Ending(now);
|
||||
},
|
||||
}
|
||||
} else {
|
||||
let endings_count = Self::endings_count();
|
||||
match fund.last_contribution {
|
||||
LastContribution::PreEnding(a) if a == endings_count => {
|
||||
// Not in ending period and no auctions have ended ending since our
|
||||
// previous bid which was also not in an ending period.
|
||||
// `NewRaise` will contain our ID still: Do nothing.
|
||||
},
|
||||
_ => {
|
||||
// Not in ending period; but an auction has been ending since our previous
|
||||
// bid, or we never had one to begin with. Add bid.
|
||||
NewRaise::<T>::append(index);
|
||||
fund.last_contribution = LastContribution::PreEnding(endings_count);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Funds::<T>::insert(index, &fund);
|
||||
|
||||
Self::deposit_event(Event::<T>::Contributed(who, index, value));
|
||||
Ok(())
|
||||
Self::do_contribute(who, index, value, signature, KeepAlive)
|
||||
}
|
||||
|
||||
/// Withdraw full balance of a specific contributor.
|
||||
@@ -706,6 +636,19 @@ pub mod pallet {
|
||||
Self::deposit_event(Event::<T>::AddedToNewRaise(index));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Contribute your entire balance to a crowd sale. This will transfer the entire balance of a user over to fund a parachain
|
||||
/// slot. It will be withdrawable when the crowdloan has ended and the funds are unused.
|
||||
#[pallet::weight(T::WeightInfo::contribute())]
|
||||
pub fn contribute_all(
|
||||
origin: OriginFor<T>,
|
||||
#[pallet::compact] index: ParaId,
|
||||
signature: Option<MultiSignature>,
|
||||
) -> DispatchResult {
|
||||
let who = ensure_signed(origin)?;
|
||||
let value = CurrencyOf::<T>::free_balance(&who);
|
||||
Self::do_contribute(who, index, value, signature, AllowDeath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -784,6 +727,89 @@ impl<T: Config> Pallet<T> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn do_contribute(
|
||||
who: T::AccountId,
|
||||
index: ParaId,
|
||||
value: BalanceOf<T>,
|
||||
signature: Option<MultiSignature>,
|
||||
existence: ExistenceRequirement,
|
||||
) -> DispatchResult {
|
||||
ensure!(value >= T::MinContribution::get(), Error::<T>::ContributionTooSmall);
|
||||
let mut fund = Self::funds(index).ok_or(Error::<T>::InvalidParaId)?;
|
||||
fund.raised = fund.raised.checked_add(&value).ok_or(Error::<T>::Overflow)?;
|
||||
ensure!(fund.raised <= fund.cap, Error::<T>::CapExceeded);
|
||||
|
||||
// Make sure crowdloan has not ended
|
||||
let now = <frame_system::Pallet<T>>::block_number();
|
||||
ensure!(now < fund.end, Error::<T>::ContributionPeriodOver);
|
||||
|
||||
// Make sure crowdloan is in a valid lease period
|
||||
let now = frame_system::Pallet::<T>::block_number();
|
||||
let (current_lease_period, _) =
|
||||
T::Auctioneer::lease_period_index(now).ok_or(Error::<T>::NoLeasePeriod)?;
|
||||
ensure!(current_lease_period <= fund.first_period, Error::<T>::ContributionPeriodOver);
|
||||
|
||||
// Make sure crowdloan has not already won.
|
||||
let fund_account = Self::fund_account_id(index);
|
||||
ensure!(
|
||||
!T::Auctioneer::has_won_an_auction(index, &fund_account),
|
||||
Error::<T>::BidOrLeaseActive
|
||||
);
|
||||
|
||||
// We disallow any crowdloan contributions during the VRF Period, so that people do not sneak their
|
||||
// contributions into the auction when it would not impact the outcome.
|
||||
ensure!(!T::Auctioneer::auction_status(now).is_vrf(), Error::<T>::VrfDelayInProgress);
|
||||
|
||||
let (old_balance, memo) = Self::contribution_get(fund.trie_index, &who);
|
||||
|
||||
if let Some(ref verifier) = fund.verifier {
|
||||
let signature = signature.ok_or(Error::<T>::InvalidSignature)?;
|
||||
let payload = (index, &who, old_balance, value);
|
||||
let valid = payload.using_encoded(|encoded| {
|
||||
signature.verify(encoded, &verifier.clone().into_account())
|
||||
});
|
||||
ensure!(valid, Error::<T>::InvalidSignature);
|
||||
}
|
||||
|
||||
CurrencyOf::<T>::transfer(&who, &fund_account, value, existence)?;
|
||||
|
||||
let balance = old_balance.saturating_add(value);
|
||||
Self::contribution_put(fund.trie_index, &who, &balance, &memo);
|
||||
|
||||
if T::Auctioneer::auction_status(now).is_ending().is_some() {
|
||||
match fund.last_contribution {
|
||||
// In ending period; must ensure that we are in NewRaise.
|
||||
LastContribution::Ending(n) if n == now => {
|
||||
// do nothing - already in NewRaise
|
||||
},
|
||||
_ => {
|
||||
NewRaise::<T>::append(index);
|
||||
fund.last_contribution = LastContribution::Ending(now);
|
||||
},
|
||||
}
|
||||
} else {
|
||||
let endings_count = Self::endings_count();
|
||||
match fund.last_contribution {
|
||||
LastContribution::PreEnding(a) if a == endings_count => {
|
||||
// Not in ending period and no auctions have ended ending since our
|
||||
// previous bid which was also not in an ending period.
|
||||
// `NewRaise` will contain our ID still: Do nothing.
|
||||
},
|
||||
_ => {
|
||||
// Not in ending period; but an auction has been ending since our previous
|
||||
// bid, or we never had one to begin with. Add bid.
|
||||
NewRaise::<T>::append(index);
|
||||
fund.last_contribution = LastContribution::PreEnding(endings_count);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Funds::<T>::insert(index, &fund);
|
||||
|
||||
Self::deposit_event(Event::<T>::Contributed(who, index, value));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> crate::traits::OnSwap for Pallet<T> {
|
||||
|
||||
Reference in New Issue
Block a user