difftreelog
fix lock and unstake logic
in: master
1 file changed
pallets/app-promotion/src/lib.rsdiffbeforeafterboth59use pallet_evm::account::CrossAccountId;59use pallet_evm::account::CrossAccountId;60use sp_runtime::{60use sp_runtime::{61 Perbill,61 Perbill,62 traits::{BlockNumberProvider, CheckedAdd, CheckedSub, AccountIdConversion},62 traits::{BlockNumberProvider, CheckedAdd, CheckedSub, AccountIdConversion, Zero},63 ArithmeticError,63 ArithmeticError,64};64};6565169 Value = (BalanceOf<T>, T::BlockNumber),169 Value = (BalanceOf<T>, T::BlockNumber),170 QueryKind = ValueQuery,170 QueryKind = ValueQuery,171 >;171 >;172 /// Amount of stakes for an Account173 #[pallet::storage]174 pub type StakesPerAccount<T: Config> =175 StorageMap<_, Blake2_128Concat, T::AccountId, u8, ValueQuery>;172176173 /// Amount of tokens pending unstake per user per block.177 /// Amount of tokens pending unstake per user per block.174 #[pallet::storage]178 #[pallet::storage]314 pub fn stake(staker: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {318 pub fn stake(staker: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {315 let staker_id = ensure_signed(staker)?;319 let staker_id = ensure_signed(staker)?;320321 ensure!(322 StakesPerAccount::<T>::get(&staker_id) < 10,323 Error::<T>::NoPermission324 );316325317 ensure!(326 ensure!(318 amount >= Into::<BalanceOf<T>>::into(100u128) * T::Nominal::get(),327 amount >= Into::<BalanceOf<T>>::into(100u128) * T::Nominal::get(),319 ArithmeticError::Underflow328 ArithmeticError::Underflow320 );329 );330331 let count = Staked::<T>::iter_prefix((staker_id.clone(),)).count();321332322 let balance =333 let balance =323 <<T as Config>::Currency as Currency<T::AccountId>>::free_balance(&staker_id);334 <<T as Config>::Currency as Currency<T::AccountId>>::free_balance(&staker_id);353 .ok_or(ArithmeticError::Overflow)?,364 .ok_or(ArithmeticError::Overflow)?,354 );365 );355366367 StakesPerAccount::<T>::mutate(&staker_id, |stakes| *stakes += 1);356 Ok(())368 Ok(())357 }369 }358370364376365 let total_staked: BalanceOf<T> = Staked::<T>::drain_prefix((&staker_id,))377 let total_staked: BalanceOf<T> = Staked::<T>::drain_prefix((&staker_id,))366 .map(|(_, (amount, _))| {378 .map(|(_, (amount, _))| {367 *&mut total_stakes += 1;379 total_stakes += 1;368 amount380 amount369 })381 })370 .sum();382 .sum();371383 384 if total_staked.is_zero() {385 return Ok(None.into());386 }372 let block =387 let block =373 T::RelayBlockNumberProvider::current_block_number() + T::PendingInterval::get();388 T::RelayBlockNumberProvider::current_block_number() + T::PendingInterval::get();374 <PendingUnstake<T>>::insert(389 <PendingUnstake<T>>::insert(384 .ok_or(ArithmeticError::Underflow)?,399 .ok_or(ArithmeticError::Underflow)?,385 ); // when error we should recover initial stake state for the staker400 ); // when error we should recover initial stake state for the staker401402 StakesPerAccount::<T>::remove(&staker_id);386403387 Ok(None.into())404 Ok(None.into())388389 // let staker_id = ensure_signed(staker)?;390391 // let mut stakes = Staked::<T>::iter_prefix((&staker_id,)).collect::<Vec<_>>();392393 // let total_staked = stakes394 // .iter()395 // .fold(<BalanceOf<T>>::default(), |acc, (_, amount)| acc + *amount);396397 // ensure!(total_staked >= amount, ArithmeticError::Underflow);398399 // <TotalStaked<T>>::set(400 // <TotalStaked<T>>::get()401 // .checked_sub(&amount)402 // .ok_or(ArithmeticError::Underflow)?,403 // );404405 // let block =406 // T::RelayBlockNumberProvider::current_block_number() + T::PendingInterval::get();407 // <PendingUnstake<T>>::insert(408 // (&staker_id, block),409 // <PendingUnstake<T>>::get((&staker_id, block))410 // .checked_add(&amount)411 // .ok_or(ArithmeticError::Overflow)?,412 // );413414 // stakes.sort_by_key(|(block, _)| *block);415416 // let mut acc_amount = amount;417 // let new_state = stakes418 // .into_iter()419 // .map_while(|(block, balance_per_block)| {420 // if acc_amount == <BalanceOf<T>>::default() {421 // return None;422 // }423 // if acc_amount <= balance_per_block {424 // let res = (block, balance_per_block - acc_amount, acc_amount);425 // acc_amount = <BalanceOf<T>>::default();426 // return Some(res);427 // } else {428 // acc_amount -= balance_per_block;429 // return Some((block, <BalanceOf<T>>::default(), acc_amount));430 // }431 // })432 // .collect::<Vec<_>>();433434 // new_state435 // .into_iter()436 // .for_each(|(block, to_staked, _to_pending)| {437 // if to_staked == <BalanceOf<T>>::default() {438 // <Staked<T>>::remove((&staker_id, block));439 // } else {440 // <Staked<T>>::insert((&staker_id, block), to_staked);441 // }442 // });443444 // Ok(())445 }405 }446406447 #[pallet::weight(T::WeightInfo::sponsor_collection())]407 #[pallet::weight(T::WeightInfo::sponsor_collection())]601 }561 }602562603 fn set_lock_unchecked(staker: &T::AccountId, amount: BalanceOf<T>) {563 fn set_lock_unchecked(staker: &T::AccountId, amount: BalanceOf<T>) {564 if amount.is_zero() {565 <T::Currency as LockableCurrency<T::AccountId>>::remove_lock(LOCK_IDENTIFIER, &staker);566 } else {604 <T::Currency as LockableCurrency<T::AccountId>>::set_lock(567 <T::Currency as LockableCurrency<T::AccountId>>::set_lock(605 LOCK_IDENTIFIER,568 LOCK_IDENTIFIER,606 staker,569 staker,607 amount,570 amount,608 WithdrawReasons::all(),571 WithdrawReasons::all(),609 )572 )610 }573 }574 }611575612 pub fn get_locked_balance(576 pub fn get_locked_balance(