diff --git a/pallets/system-staking/src/lib.rs b/pallets/system-staking/src/lib.rs index 13d32627c..2cad2b4ea 100644 --- a/pallets/system-staking/src/lib.rs +++ b/pallets/system-staking/src/lib.rs @@ -283,6 +283,8 @@ pub mod pallet { vfree: BalanceOf, shadow: BalanceOf, }, + /// payout error + PayoutFailed { token: CurrencyIdOf }, } #[pallet::error] @@ -355,6 +357,11 @@ pub mod pallet { // token_info.current_config.exec_delay ===> true if round.check_delay(n, token_info.current_config.exec_delay) { Self::process_token_info(pallet_account.clone(), token_info, i).ok(); + + if let Err(_) = Self::do_payout(i) { + log::error!("System staking auto payout failed, token: {:?}", i); + Self::deposit_event(Event::PayoutFailed { token: i }); + } } } } @@ -515,51 +522,7 @@ pub mod pallet { pub fn payout(origin: OriginFor, token: CurrencyIdOf) -> DispatchResultWithPostInfo { T::EnsureConfirmAsGovernance::ensure_origin(origin)?; - let token_info = >::get(&token).ok_or(Error::::TokenInfoNotFound)?; - - // token_id convert to vtoken_id - let vtoken_id = token.to_vtoken().map_err(|_| Error::::TokenInfoNotFound)?; - - let pallet_account: AccountIdOf = T::PalletId::get().into_account_truncating(); - - // Calculate the revenue generated by vtoken - let vfree_amount = T::MultiCurrency::free_balance(vtoken_id, &pallet_account); - let free_amount = T::VtokenMintingInterface::get_currency_amount_by_v_currency_amount( - token, - vtoken_id, - vfree_amount, - )?; - let token_amount = free_amount.saturating_sub(token_info.system_shadow_amount); - - // Calculate the number of benefits converted to vtoken - let vtoken_amount = - T::VtokenMintingInterface::get_v_currency_amount_by_currency_amount( - token, - vtoken_id, - token_amount, - )?; - - // Transfer vtoken(benefits) to BenefitReceivingAccount - T::MultiCurrency::transfer( - vtoken_id, - &pallet_account, - &T::BenefitReceivingAccount::get(), - vtoken_amount, - ) - .map_err(|_| Error::::PayoutFailed)?; - - Self::deposit_event(Event::Payout { - token, - vtoken: vtoken_id, - from: pallet_account, - to: T::BenefitReceivingAccount::get(), - amount: vtoken_amount, - vfree: vfree_amount, - free: free_amount, - shadow: token_info.system_shadow_amount, - }); - - Ok(().into()) + Self::do_payout(token) } } } @@ -683,6 +646,53 @@ impl Pallet { Ok(().into()) } + fn do_payout(token: CurrencyIdOf) -> DispatchResultWithPostInfo { + let token_info = >::get(&token).ok_or(Error::::TokenInfoNotFound)?; + + // token_id convert to vtoken_id + let vtoken_id = token.to_vtoken().map_err(|_| Error::::TokenInfoNotFound)?; + + let pallet_account: AccountIdOf = T::PalletId::get().into_account_truncating(); + + // Calculate the revenue generated by vtoken + let vfree_amount = T::MultiCurrency::free_balance(vtoken_id, &pallet_account); + let free_amount = T::VtokenMintingInterface::get_currency_amount_by_v_currency_amount( + token, + vtoken_id, + vfree_amount, + )?; + let token_amount = free_amount.saturating_sub(token_info.system_shadow_amount); + + // Calculate the number of benefits converted to vtoken + let vtoken_amount = T::VtokenMintingInterface::get_v_currency_amount_by_currency_amount( + token, + vtoken_id, + token_amount, + )?; + + // Transfer vtoken(benefits) to BenefitReceivingAccount + T::MultiCurrency::transfer( + vtoken_id, + &pallet_account, + &T::BenefitReceivingAccount::get(), + vtoken_amount, + ) + .map_err(|_| Error::::PayoutFailed)?; + + Self::deposit_event(Event::Payout { + token, + vtoken: vtoken_id, + from: pallet_account, + to: T::BenefitReceivingAccount::get(), + amount: vtoken_amount, + vfree: vfree_amount, + free: free_amount, + shadow: token_info.system_shadow_amount, + }); + + Ok(().into()) + } + // vTokenMinting on_initialize_update_ledger , update pending_redeem_amount -= token_amount , // update system_shadow_amount -= token_amount pub fn on_redeem_success(