git.delta.rocks / unique-network / refs/commits / d83ab4fde4e8

difftreelog

fix appPromotion RPC diasbling, refactor benchmarks, fix `WithdrawReasons`, rename `get_sponsor` to `sponsor` in hadlers traits + change their behavior in impl's blocks

PraetorP2022-09-07parent: #0102052.patch.diff
in: master

11 files changed

modifiednode/rpc/src/lib.rsdiffbeforeafterboth
--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -234,7 +234,7 @@
 
 	io.merge(Unique::new(client.clone()).into_rpc())?;
 
-	#[cfg(any(feature = "opal-runtime"))]
+	#[cfg(not(any(feature = "unique-runtime", feature = "quartz-runtime")))]
 	io.merge(AppPromotion::new(client.clone()).into_rpc())?;
 
 	#[cfg(not(feature = "unique-runtime"))]
modifiedpallets/app-promotion/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/app-promotion/src/benchmarking.rs
+++ b/pallets/app-promotion/src/benchmarking.rs
@@ -30,7 +30,7 @@
 
 const SEED: u32 = 0;
 
-fn set_admin<T>() -> DispatchResult
+fn set_admin<T>() -> Result<T::AccountId, sp_runtime::DispatchError>
 where
 	T: Config + pallet_unique::Config + pallet_evm_migration::Config,
 	T::BlockNumber: From<u32> + Into<u32>,
@@ -46,7 +46,9 @@
 	PromototionPallet::<T>::set_admin_address(
 		RawOrigin::Root.into(),
 		T::CrossAccountId::from_sub(pallet_admin.clone()),
-	)
+	)?;
+
+	Ok(pallet_admin)
 }
 
 benchmarks! {
@@ -73,12 +75,12 @@
 	set_admin_address {
 		let pallet_admin = account::<T::AccountId>("admin", 0, SEED);
 		let _ = <T as Config>::Currency::make_free_balance_be(&pallet_admin,  Perbill::from_rational(1u32, 2) * BalanceOf::<T>::max_value());
-	} : {PromototionPallet::<T>::set_admin_address(RawOrigin::Root.into(), T::CrossAccountId::from_sub(pallet_admin))?}
+	} : _(RawOrigin::Root, T::CrossAccountId::from_sub(pallet_admin))
 
 	payout_stakers{
 		let b in 1..101;
 
-		let pallet_admin = account::<T::AccountId>("admin", 0, SEED);
+		let pallet_admin = account::<T::AccountId>("admin", 1, SEED);
 		let share = Perbill::from_rational(1u32, 20);
 		PromototionPallet::<T>::set_admin_address(RawOrigin::Root.into(), T::CrossAccountId::from_sub(pallet_admin.clone()))?;
 		<T as Config>::Currency::make_free_balance_be(&pallet_admin,  Perbill::from_rational(1u32, 2) * BalanceOf::<T>::max_value());
@@ -92,22 +94,18 @@
 		(0..10).try_for_each(|_| {
 			stakers.iter()
 				.map(|staker| {
-
 					PromototionPallet::<T>::stake(RawOrigin::Signed(staker.clone()).into(), Into::<BalanceOf<T>>::into(100u128) * T::Nominal::get())
 				}).collect::<Result<Vec<_>, _>>()?;
 			<frame_system::Pallet<T>>::finalize();
 			Result::<(), sp_runtime::DispatchError>::Ok(())
 		})?;
-
-		// let _ = <T as Config>::Currency::make_free_balance_be(&staker,  Perbill::from_rational(1u32, 2) * BalanceOf::<T>::max_value());
-		// let _ = PromototionPallet::<T>::stake(RawOrigin::Signed(staker.clone()).into(), share * <T as Config>::Currency::total_balance(&staker))?;
-	} : {PromototionPallet::<T>::payout_stakers(RawOrigin::Signed(pallet_admin.clone()).into(), Some(b as u8))?}
+	} : _(RawOrigin::Signed(pallet_admin.clone()), Some(b as u8))
 
 	stake {
 		let caller = account::<T::AccountId>("caller", 0, SEED);
 		let share = Perbill::from_rational(1u32, 10);
 		let _ = <T as Config>::Currency::make_free_balance_be(&caller,  Perbill::from_rational(1u32, 2) * BalanceOf::<T>::max_value());
-	} : {PromototionPallet::<T>::stake(RawOrigin::Signed(caller.clone()).into(), share * <T as Config>::Currency::total_balance(&caller))?}
+	} : _(RawOrigin::Signed(caller.clone()), share * <T as Config>::Currency::total_balance(&caller))
 
 	unstake {
 		let caller = account::<T::AccountId>("caller", 0, SEED);
@@ -117,17 +115,8 @@
 			<frame_system::Pallet<T>>::finalize();
 			PromototionPallet::<T>::stake(RawOrigin::Signed(caller.clone()).into(), share * <T as Config>::Currency::total_balance(&caller))
 		}).collect::<Result<Vec<_>, _>>()?;
-
-	} : {PromototionPallet::<T>::unstake(RawOrigin::Signed(caller.clone()).into())?}
 
-	// recalculate_and_insert_stake{
-	// 	let caller = account::<T::AccountId>("caller", 0, SEED);
-	// 	let share = Perbill::from_rational(1u32, 10);
-	// 	let _ = <T as Config>::Currency::make_free_balance_be(&caller,  Perbill::from_rational(1u32, 2) * BalanceOf::<T>::max_value());
-	// 	let _ = PromototionPallet::<T>::stake(RawOrigin::Signed(caller.clone()).into(), share * <T as Config>::Currency::total_balance(&caller))?;
-	// 	let block = <T::RelayBlockNumberProvider as BlockNumberProvider>::current_block_number();
-	// 	let mut acc = <BalanceOf<T>>::default();
-	// } : {PromototionPallet::<T>::recalculate_and_insert_stake(&caller, block, share * <T as Config>::Currency::total_balance(&caller), &mut acc)}
+	} : _(RawOrigin::Signed(caller.clone()))
 
 	sponsor_collection {
 		let pallet_admin = account::<T::AccountId>("admin", 0, SEED);
@@ -136,7 +125,7 @@
 		let caller: T::AccountId = account("caller", 0, SEED);
 		let _ = <T as Config>::Currency::make_free_balance_be(&caller,  Perbill::from_rational(1u32, 2) * BalanceOf::<T>::max_value());
 		let collection = create_nft_collection::<T>(caller.clone())?;
-	} : {PromototionPallet::<T>::sponsor_collection(RawOrigin::Signed(pallet_admin.clone()).into(), collection)?}
+	} : _(RawOrigin::Signed(pallet_admin.clone()), collection)
 
 	stop_sponsoring_collection {
 		let pallet_admin = account::<T::AccountId>("admin", 0, SEED);
@@ -146,7 +135,7 @@
 		let _ = <T as Config>::Currency::make_free_balance_be(&caller,  Perbill::from_rational(1u32, 2) * BalanceOf::<T>::max_value());
 		let collection = create_nft_collection::<T>(caller.clone())?;
 		PromototionPallet::<T>::sponsor_collection(RawOrigin::Signed(pallet_admin.clone()).into(), collection)?;
-	} : {PromototionPallet::<T>::stop_sponsoring_collection(RawOrigin::Signed(pallet_admin.clone()).into(), collection)?}
+	} : _(RawOrigin::Signed(pallet_admin.clone()), collection)
 
 	sponsor_contract {
 		let pallet_admin = account::<T::AccountId>("admin", 0, SEED);
@@ -157,7 +146,7 @@
 		let data: Vec<u8> = (0..20 as u8).collect();
 		<EvmMigrationPallet<T>>::begin(RawOrigin::Root.into(), address)?;
 		<EvmMigrationPallet<T>>::finish(RawOrigin::Root.into(), address, data)?;
-	} : {PromototionPallet::<T>::sponsor_conract(RawOrigin::Signed(pallet_admin.clone()).into(), address)?}
+	} : _(RawOrigin::Signed(pallet_admin.clone()), address)
 
 	stop_sponsoring_contract {
 		let pallet_admin = account::<T::AccountId>("admin", 0, SEED);
@@ -168,6 +157,6 @@
 		let data: Vec<u8> = (0..20 as u8).collect();
 		<EvmMigrationPallet<T>>::begin(RawOrigin::Root.into(), address)?;
 		<EvmMigrationPallet<T>>::finish(RawOrigin::Root.into(), address, data)?;
-		PromototionPallet::<T>::sponsor_conract(RawOrigin::Signed(pallet_admin.clone()).into(), address)?;
-	} : {PromototionPallet::<T>::stop_sponsoring_contract(RawOrigin::Signed(pallet_admin.clone()).into(), address)?}
+		PromototionPallet::<T>::sponsor_contract(RawOrigin::Signed(pallet_admin.clone()).into(), address)?;
+	} : _(RawOrigin::Signed(pallet_admin.clone()), address)
 }
modifiedpallets/app-promotion/src/lib.rsdiffbeforeafterboth
before · pallets/app-promotion/src/lib.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! # App promotion18//!19//! The app promotion pallet is designed to ... .20//!21//! ## Interface22//!23//! ### Dispatchable Functions24//!25//! * `start_inflation` - This method sets the inflation start date. Can be only called once.26//! Inflation start block can be backdated and will catch up. The method will create Treasury27//!	account if it does not exist and perform the first inflation deposit.2829// #![recursion_limit = "1024"]30#![cfg_attr(not(feature = "std"), no_std)]3132#[cfg(feature = "runtime-benchmarks")]33mod benchmarking;34#[cfg(test)]35mod tests;36pub mod types;37pub mod weights;3839use sp_std::{40	vec::{Vec},41	vec,42	iter::Sum,43	borrow::ToOwned,44	cell::RefCell,45};46use sp_core::H160;47use codec::EncodeLike;48use pallet_balances::BalanceLock;49pub use types::*;5051// use up_common::constants::{DAYS, UNIQUE};52use up_data_structs::CollectionId;5354use frame_support::{55	dispatch::{DispatchResult},56	traits::{57		Currency, Get, LockableCurrency, WithdrawReasons, tokens::Balance, ExistenceRequirement,58	},59	ensure,60};6162use weights::WeightInfo;6364pub use pallet::*;65use pallet_evm::account::CrossAccountId;66use sp_runtime::{67	Perbill,68	traits::{BlockNumberProvider, CheckedAdd, CheckedSub, AccountIdConversion, Zero},69	ArithmeticError,70};7172pub const LOCK_IDENTIFIER: [u8; 8] = *b"appstake";7374const PENDING_LIMIT_PER_BLOCK: u32 = 3;7576type BalanceOf<T> =77	<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;7879#[frame_support::pallet]80pub mod pallet {81	use super::*;82	use frame_support::{83		Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key, PalletId,84		traits::ReservableCurrency,85	};86	use frame_system::pallet_prelude::*;8788	#[pallet::config]89	pub trait Config: frame_system::Config + pallet_evm::account::Config {90		type Currency: ExtendedLockableCurrency<Self::AccountId>91			+ ReservableCurrency<Self::AccountId>;9293		type CollectionHandler: CollectionHandler<94			AccountId = Self::AccountId,95			CollectionId = CollectionId,96		>;9798		type ContractHandler: ContractHandler<AccountId = Self::CrossAccountId, ContractId = H160>;99100		type TreasuryAccountId: Get<Self::AccountId>;101102		/// The app's pallet id, used for deriving its sovereign account ID.103		#[pallet::constant]104		type PalletId: Get<PalletId>;105106		/// In relay blocks.107		#[pallet::constant]108		type RecalculationInterval: Get<Self::BlockNumber>;109		/// In relay blocks.110		#[pallet::constant]111		type PendingInterval: Get<Self::BlockNumber>;112113		// /// In chain blocks.114		// #[pallet::constant]115		// type Day: Get<Self::BlockNumber>; // useless116117		#[pallet::constant]118		type Nominal: Get<BalanceOf<Self>>;119120		#[pallet::constant]121		type IntervalIncome: Get<Perbill>;122123		/// Weight information for extrinsics in this pallet.124		type WeightInfo: WeightInfo;125126		// The relay block number provider127		type RelayBlockNumberProvider: BlockNumberProvider<BlockNumber = Self::BlockNumber>;128129		/// Events compatible with [`frame_system::Config::Event`].130		type Event: IsType<<Self as frame_system::Config>::Event> + From<Event<Self>>;131	}132133	#[pallet::pallet]134	#[pallet::generate_store(pub(super) trait Store)]135	pub struct Pallet<T>(_);136137	#[pallet::event]138	#[pallet::generate_deposit(fn deposit_event)]139	pub enum Event<T: Config> {140		StakingRecalculation(141			/// An recalculated staker142			T::AccountId,143			/// Base on which interest is calculated144			BalanceOf<T>,145			/// Amount of accrued interest146			BalanceOf<T>,147		),148		Stake(T::AccountId, BalanceOf<T>),149		Unstake(T::AccountId, BalanceOf<T>),150		SetAdmin(T::AccountId),151	}152153	#[pallet::error]154	pub enum Error<T> {155		/// Error due to action requiring admin to be set156		AdminNotSet,157		/// No permission to perform an action158		NoPermission,159		/// Insufficient funds to perform an action160		NotSufficientFunds,161		PendingForBlockOverflow,162		/// An error related to the fact that an invalid argument was passed to perform an action163		InvalidArgument,164	}165166	#[pallet::storage]167	pub type TotalStaked<T: Config> = StorageValue<Value = BalanceOf<T>, QueryKind = ValueQuery>;168169	#[pallet::storage]170	pub type Admin<T: Config> = StorageValue<Value = T::AccountId, QueryKind = OptionQuery>;171172	/// Amount of tokens staked by account in the blocknumber.173	#[pallet::storage]174	pub type Staked<T: Config> = StorageNMap<175		Key = (176			Key<Blake2_128Concat, T::AccountId>,177			Key<Twox64Concat, T::BlockNumber>,178		),179		Value = (BalanceOf<T>, T::BlockNumber),180		QueryKind = ValueQuery,181	>;182	/// Amount of stakes for an Account183	#[pallet::storage]184	pub type StakesPerAccount<T: Config> =185		StorageMap<_, Blake2_128Concat, T::AccountId, u8, ValueQuery>;186187	/// Amount of tokens pending unstake per user per block.188	// #[pallet::storage]189	// pub type PendingUnstake<T: Config> = StorageNMap<190	// 	Key = (191	// 		Key<Blake2_128Concat, T::AccountId>,192	// 		Key<Twox64Concat, T::BlockNumber>,193	// 	),194	// 	Value = BalanceOf<T>,195	// 	QueryKind = ValueQuery,196	// >;197	#[pallet::storage]198	pub type PendingUnstake<T: Config> = StorageMap<199		_,200		Twox64Concat,201		T::BlockNumber,202		BoundedVec<(T::AccountId, BalanceOf<T>), ConstU32<PENDING_LIMIT_PER_BLOCK>>,203		ValueQuery,204	>;205206	// /// A block when app-promotion has started .I think this is redundant, because we only need `NextInterestBlock`.207	// #[pallet::storage]208	// pub type StartBlock<T: Config> = StorageValue<Value = T::BlockNumber, QueryKind = ValueQuery>;209210	// /// Next target block when interest is recalculated211	// #[pallet::storage]212	// #[pallet::getter(fn get_interest_block)]213	// pub type NextInterestBlock<T: Config> =214	// 	StorageValue<Value = T::BlockNumber, QueryKind = ValueQuery>;215216	/// Stores hash a record for which the last revenue recalculation was performed.217	/// If `None`, then recalculation has not yet been performed or calculations have been completed for all stakers.218	#[pallet::storage]219	#[pallet::getter(fn get_next_calculated_record)]220	pub type NextCalculatedRecord<T: Config> =221		StorageValue<Value = (T::AccountId, T::BlockNumber), QueryKind = OptionQuery>;222223	#[pallet::hooks]224	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {225		fn on_initialize(current_block_number: T::BlockNumber) -> Weight226		where227			<T as frame_system::Config>::BlockNumber: From<u32>,228		{229			// let mut consumed_weight = 0;230			// let mut add_weight = |reads, writes, weight| {231			// 	consumed_weight += T::DbWeight::get().reads_writes(reads, writes);232			// 	consumed_weight += weight;233			// };234235			let block_pending = PendingUnstake::<T>::take(current_block_number);236			let counter = block_pending.len() as u32;237			// add_weight(0, 1, 0);238239			if !block_pending.is_empty() {240				block_pending.into_iter().for_each(|(staker, amount)| {241					<T::Currency as ReservableCurrency<T::AccountId>>::unreserve(&staker, amount);242				});243			}244245			T::WeightInfo::on_initialize(counter)246			// consumed_weight247		}248	}249250	#[pallet::call]251	impl<T: Config> Pallet<T>252	where253		T::BlockNumber: From<u32> + Into<u32>,254		<<T as Config>::Currency as Currency<T::AccountId>>::Balance: Sum + From<u128>,255	{256		#[pallet::weight(T::WeightInfo::set_admin_address())]257		pub fn set_admin_address(origin: OriginFor<T>, admin: T::CrossAccountId) -> DispatchResult {258			ensure_root(origin)?;259260			<Admin<T>>::set(Some(admin.as_sub().to_owned()));261262			Self::deposit_event(Event::SetAdmin(admin.as_sub().to_owned()));263264			Ok(())265		}266267		#[pallet::weight(T::WeightInfo::stake())]268		pub fn stake(staker: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {269			let staker_id = ensure_signed(staker)?;270271			ensure!(272				StakesPerAccount::<T>::get(&staker_id) < 10,273				Error::<T>::NoPermission274			);275276			ensure!(277				amount >= Into::<BalanceOf<T>>::into(100u128) * T::Nominal::get(),278				ArithmeticError::Underflow279			);280281			let balance =282				<<T as Config>::Currency as Currency<T::AccountId>>::free_balance(&staker_id);283284			// ensure!(balance >= amount, ArithmeticError::Underflow);285286			<<T as Config>::Currency as Currency<T::AccountId>>::ensure_can_withdraw(287				&staker_id,288				amount,289				WithdrawReasons::RESERVE,290				balance - amount,291			)?;292293			Self::add_lock_balance(&staker_id, amount)?;294295			let block_number = T::RelayBlockNumberProvider::current_block_number();296297			let recalculate_after_interval: T::BlockNumber =298				if block_number % T::RecalculationInterval::get() == 0u32.into() {299					1u32.into()300				} else {301					2u32.into()302				};303304			let recalc_block = (block_number / T::RecalculationInterval::get()305				+ recalculate_after_interval)306				* T::RecalculationInterval::get();307308			<Staked<T>>::insert((&staker_id, block_number), {309				let mut balance_and_recalc_block = <Staked<T>>::get((&staker_id, block_number));310				balance_and_recalc_block.0 = balance_and_recalc_block311					.0312					.checked_add(&amount)313					.ok_or(ArithmeticError::Overflow)?;314				balance_and_recalc_block.1 = recalc_block;315				balance_and_recalc_block316			});317318			<TotalStaked<T>>::set(319				<TotalStaked<T>>::get()320					.checked_add(&amount)321					.ok_or(ArithmeticError::Overflow)?,322			);323324			StakesPerAccount::<T>::mutate(&staker_id, |stakes| *stakes += 1);325326			Self::deposit_event(Event::Stake(staker_id, amount));327328			Ok(())329		}330331		#[pallet::weight(T::WeightInfo::unstake())]332		pub fn unstake(staker: OriginFor<T>) -> DispatchResultWithPostInfo {333			let staker_id = ensure_signed(staker)?;334			let block = <frame_system::Pallet<T>>::block_number() + T::PendingInterval::get();335			let mut pendings = <PendingUnstake<T>>::get(block);336337			ensure!(!pendings.is_full(), Error::<T>::PendingForBlockOverflow);338339			let mut total_stakes = 0u64;340341			let total_staked: BalanceOf<T> = Staked::<T>::drain_prefix((&staker_id,))342				.map(|(_, (amount, _))| {343					total_stakes += 1;344					amount345				})346				.sum();347348			if total_staked.is_zero() {349				return Ok(None.into()); // TO-DO350			}351352			pendings353				.try_push((staker_id.clone(), total_staked))354				.map_err(|_| Error::<T>::PendingForBlockOverflow)?;355356			<PendingUnstake<T>>::insert(block, pendings);357358			Self::unlock_balance_unchecked(&staker_id, total_staked);359360			<T::Currency as ReservableCurrency<T::AccountId>>::reserve(&staker_id, total_staked)?;361362			TotalStaked::<T>::set(363				TotalStaked::<T>::get()364					.checked_sub(&total_staked)365					.ok_or(ArithmeticError::Underflow)?,366			);367368			StakesPerAccount::<T>::remove(&staker_id);369370			Self::deposit_event(Event::Unstake(staker_id, total_staked));371372			Ok(None.into())373		}374375		#[pallet::weight(T::WeightInfo::sponsor_collection())]376		pub fn sponsor_collection(377			admin: OriginFor<T>,378			collection_id: CollectionId,379		) -> DispatchResult {380			let admin_id = ensure_signed(admin)?;381			ensure!(382				admin_id == Admin::<T>::get().ok_or(Error::<T>::AdminNotSet)?,383				Error::<T>::NoPermission384			);385386			T::CollectionHandler::set_sponsor(Self::account_id(), collection_id)387		}388		#[pallet::weight(T::WeightInfo::stop_sponsoring_collection())]389		pub fn stop_sponsoring_collection(390			admin: OriginFor<T>,391			collection_id: CollectionId,392		) -> DispatchResult {393			let admin_id = ensure_signed(admin)?;394395			ensure!(396				admin_id == Admin::<T>::get().ok_or(Error::<T>::AdminNotSet)?,397				Error::<T>::NoPermission398			);399400			ensure!(401				T::CollectionHandler::get_sponsor(collection_id)?402					.ok_or(<Error<T>>::InvalidArgument)?403					== Self::account_id(),404				<Error<T>>::NoPermission405			);406			T::CollectionHandler::remove_collection_sponsor(collection_id)407		}408409		#[pallet::weight(T::WeightInfo::sponsor_contract())]410		pub fn sponsor_conract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {411			let admin_id = ensure_signed(admin)?;412413			ensure!(414				admin_id == Admin::<T>::get().ok_or(Error::<T>::AdminNotSet)?,415				Error::<T>::NoPermission416			);417418			T::ContractHandler::set_sponsor(419				T::CrossAccountId::from_sub(Self::account_id()),420				contract_id,421			)422		}423424		#[pallet::weight(T::WeightInfo::stop_sponsoring_contract())]425		pub fn stop_sponsoring_contract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {426			let admin_id = ensure_signed(admin)?;427428			ensure!(429				admin_id == Admin::<T>::get().ok_or(Error::<T>::AdminNotSet)?,430				Error::<T>::NoPermission431			);432433			ensure!(434				T::ContractHandler::get_sponsor(contract_id)?.ok_or(<Error<T>>::InvalidArgument)?435					== T::CrossAccountId::from_sub(Self::account_id()),436				<Error<T>>::NoPermission437			);438			T::ContractHandler::remove_contract_sponsor(contract_id)439		}440441		#[pallet::weight(T::WeightInfo::payout_stakers(stakers_number.unwrap_or(20) as u32))]442		pub fn payout_stakers(admin: OriginFor<T>, stakers_number: Option<u8>) -> DispatchResult {443			let admin_id = ensure_signed(admin)?;444445			ensure!(446				admin_id == Admin::<T>::get().ok_or(Error::<T>::AdminNotSet)?,447				Error::<T>::NoPermission448			);449450			let current_recalc_block =451				Self::get_current_recalc_block(T::RelayBlockNumberProvider::current_block_number());452			let next_recalc_block = current_recalc_block + T::RecalculationInterval::get();453454			let mut storage_iterator = Self::get_next_calculated_key()455				.map_or(Staked::<T>::iter(), |key| Staked::<T>::iter_from(key));456457			NextCalculatedRecord::<T>::set(None);458459			// {460			// 	let mut stakers_number = stakers_number.unwrap_or(20);461			// 	let mut last_id = admin_id;462			// 	let mut income_acc = BalanceOf::<T>::default();463			// 	let mut amount_acc = BalanceOf::<T>::default();464465			// 	while let Some((466			// 		(current_id, staked_block),467			// 		(amount, next_recalc_block_for_stake),468			// 	)) = storage_iterator.next()469			// 	{470			// 		if last_id != current_id {471			// 			if income_acc != BalanceOf::<T>::default() {472			// 				<T::Currency as Currency<T::AccountId>>::transfer(473			// 					&T::TreasuryAccountId::get(),474			// 					&last_id,475			// 					income_acc,476			// 					ExistenceRequirement::KeepAlive,477			// 				)478			// 				.and_then(|_| Self::add_lock_balance(&last_id, income_acc))?;479480			// 				Self::deposit_event(Event::StakingRecalculation(481			// 					last_id, amount, income_acc,482			// 				));483			// 			}484485			// 			if stakers_number == 0 {486			// 				NextCalculatedRecord::<T>::set(Some((current_id, staked_block)));487			// 				break;488			// 			}489			// 			stakers_number -= 1;490			// 			income_acc = BalanceOf::<T>::default();491			// 			last_id = current_id;492			// 		};493			// 		if current_recalc_block >= next_recalc_block_for_stake {494			// 			Self::recalculate_and_insert_stake(495			// 				&last_id,496			// 				staked_block,497			// 				next_recalc_block,498			// 				amount,499			// 				((current_recalc_block - next_recalc_block_for_stake)500			// 					/ T::RecalculationInterval::get())501			// 				.into() + 1,502			// 				&mut income_acc,503			// 			);504			// 		}505			// 	}506			// }507508			// {509			// 	let mut stakers_number = stakers_number.unwrap_or(20);510			// 	let last_id = RefCell::new(None);511			// 	let income_acc = RefCell::new(BalanceOf::<T>::default());512			// 	let amount_acc = RefCell::new(BalanceOf::<T>::default());513514			// 	let flush_stake = || -> DispatchResult {515			// 		if let Some(last_id) = &*last_id.borrow() {516			// 			if !income_acc.borrow().is_zero() {517			// 				<T::Currency as Currency<T::AccountId>>::transfer(518			// 					&T::TreasuryAccountId::get(),519			// 					last_id,520			// 					*income_acc.borrow(),521			// 					ExistenceRequirement::KeepAlive,522			// 				)523			// 				.and_then(|_| {524			// 					Self::add_lock_balance(last_id, *income_acc.borrow());525			// 					<TotalStaked<T>>::try_mutate(|staked| {526			// 						staked527			// 							.checked_add(&*income_acc.borrow())528			// 							.ok_or(ArithmeticError::Overflow.into())529			// 					})530			// 				})?;531532			// 				Self::deposit_event(Event::StakingRecalculation(533			// 					last_id.clone(),534			// 					*amount_acc.borrow(),535			// 					*income_acc.borrow(),536			// 				));537			// 			}538539			// 			*income_acc.borrow_mut() = BalanceOf::<T>::default();540			// 			*amount_acc.borrow_mut() = BalanceOf::<T>::default();541			// 		}542			// 		Ok(())543			// 	};544545			// 	while let Some((546			// 		(current_id, staked_block),547			// 		(amount, next_recalc_block_for_stake),548			// 	)) = storage_iterator.next()549			// 	{550			// 		if stakers_number == 0 {551			// 			NextCalculatedRecord::<T>::set(Some((current_id, staked_block)));552			// 			break;553			// 		}554			// 		stakers_number -= 1;555			// 		if last_id.borrow().as_ref() != Some(&current_id) {556			// 			flush_stake()?;557			// 		};558			// 		*last_id.borrow_mut() = Some(current_id.clone());559			// 		if current_recalc_block >= next_recalc_block_for_stake {560			// 			*amount_acc.borrow_mut() += amount;561			// 			Self::recalculate_and_insert_stake(562			// 				&current_id,563			// 				staked_block,564			// 				next_recalc_block,565			// 				amount,566			// 				((current_recalc_block - next_recalc_block_for_stake)567			// 					/ T::RecalculationInterval::get())568			// 				.into() + 1,569			// 				&mut *income_acc.borrow_mut(),570			// 			);571			// 		}572			// 	}573			// 	flush_stake()?;574			// }575576			{577				let mut stakers_number = stakers_number.unwrap_or(20);578				let last_id = RefCell::new(None);579				let income_acc = RefCell::new(BalanceOf::<T>::default());580				let amount_acc = RefCell::new(BalanceOf::<T>::default());581582				let flush_stake = || -> DispatchResult {583					if let Some(last_id) = &*last_id.borrow() {584						if !income_acc.borrow().is_zero() {585							<T::Currency as Currency<T::AccountId>>::transfer(586								&T::TreasuryAccountId::get(),587								last_id,588								*income_acc.borrow(),589								ExistenceRequirement::KeepAlive,590							)591							.and_then(|_| {592								Self::add_lock_balance(last_id, *income_acc.borrow())?;593								<TotalStaked<T>>::try_mutate(|staked| {594									staked595										.checked_add(&*income_acc.borrow())596										.ok_or(ArithmeticError::Overflow.into())597								})598							})?;599600							Self::deposit_event(Event::StakingRecalculation(601								last_id.clone(),602								*amount_acc.borrow(),603								*income_acc.borrow(),604							));605						}606607						*income_acc.borrow_mut() = BalanceOf::<T>::default();608						*amount_acc.borrow_mut() = BalanceOf::<T>::default();609					}610					Ok(())611				};612613				while let Some((614					(current_id, staked_block),615					(amount, next_recalc_block_for_stake),616				)) = storage_iterator.next()617				{618					if stakers_number == 0 {619						NextCalculatedRecord::<T>::set(Some((current_id, staked_block)));620						break;621					}622					if last_id.borrow().as_ref() != Some(&current_id) {623						flush_stake()?;624						*last_id.borrow_mut() = Some(current_id.clone());625						stakers_number -= 1;626					};627					if current_recalc_block >= next_recalc_block_for_stake {628						*amount_acc.borrow_mut() += amount;629						Self::recalculate_and_insert_stake(630							&current_id,631							staked_block,632							next_recalc_block,633							amount,634							((current_recalc_block - next_recalc_block_for_stake)635								/ T::RecalculationInterval::get())636							.into() + 1,637							&mut *income_acc.borrow_mut(),638						);639					}640				}641				flush_stake()?;642			}643644			Ok(())645		}646	}647}648649impl<T: Config> Pallet<T> {650	pub fn account_id() -> T::AccountId {651		T::PalletId::get().into_account_truncating()652	}653654	fn unlock_balance_unchecked(staker: &T::AccountId, amount: BalanceOf<T>) {655		let mut locked_balance = Self::get_locked_balance(staker).map(|l| l.amount).unwrap();656		locked_balance -= amount;657		Self::set_lock_unchecked(staker, locked_balance);658	}659660	fn add_lock_balance(staker: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {661		Self::get_locked_balance(staker)662			.map_or(<BalanceOf<T>>::default(), |l| l.amount)663			.checked_add(&amount)664			.map(|new_lock| Self::set_lock_unchecked(staker, new_lock))665			.ok_or(ArithmeticError::Overflow.into())666	}667668	fn set_lock_unchecked(staker: &T::AccountId, amount: BalanceOf<T>) {669		if amount.is_zero() {670			<T::Currency as LockableCurrency<T::AccountId>>::remove_lock(LOCK_IDENTIFIER, &staker);671		} else {672			<T::Currency as LockableCurrency<T::AccountId>>::set_lock(673				LOCK_IDENTIFIER,674				staker,675				amount,676				WithdrawReasons::RESERVE,677			)678		}679	}680681	pub fn get_locked_balance(682		staker: impl EncodeLike<T::AccountId>,683	) -> Option<BalanceLock<BalanceOf<T>>> {684		<T::Currency as ExtendedLockableCurrency<T::AccountId>>::locks(staker)685			.into_iter()686			.find(|l| l.id == LOCK_IDENTIFIER)687	}688689	pub fn total_staked_by_id(staker: impl EncodeLike<T::AccountId>) -> Option<BalanceOf<T>> {690		let staked = Staked::<T>::iter_prefix((staker,))691			.into_iter()692			.fold(<BalanceOf<T>>::default(), |acc, (_, (amount, _))| {693				acc + amount694			});695		if staked != <BalanceOf<T>>::default() {696			Some(staked)697		} else {698			None699		}700	}701702	pub fn total_staked_by_id_per_block(703		staker: impl EncodeLike<T::AccountId>,704	) -> Option<Vec<(T::BlockNumber, BalanceOf<T>)>> {705		let mut staked = Staked::<T>::iter_prefix((staker,))706			.into_iter()707			.map(|(block, (amount, _))| (block, amount))708			.collect::<Vec<_>>();709		staked.sort_by_key(|(block, _)| *block);710		if !staked.is_empty() {711			Some(staked)712		} else {713			None714		}715	}716717	pub fn cross_id_total_staked(staker: Option<T::CrossAccountId>) -> Option<BalanceOf<T>> {718		staker.map_or(Some(<TotalStaked<T>>::get()), |s| {719			Self::total_staked_by_id(s.as_sub())720		})721		// Self::total_staked_by_id(staker.as_sub())722	}723724	pub fn cross_id_locked_balance(staker: T::CrossAccountId) -> BalanceOf<T> {725		Self::get_locked_balance(staker.as_sub())726			.map(|l| l.amount)727			.unwrap_or_default()728	}729730	pub fn cross_id_total_staked_per_block(731		staker: T::CrossAccountId,732	) -> Vec<(T::BlockNumber, BalanceOf<T>)> {733		Self::total_staked_by_id_per_block(staker.as_sub()).unwrap_or_default()734	}735736	fn recalculate_and_insert_stake(737		staker: &T::AccountId,738		staked_block: T::BlockNumber,739		next_recalc_block: T::BlockNumber,740		base: BalanceOf<T>,741		iters: u32,742		income_acc: &mut BalanceOf<T>,743	) {744		let income = Self::calculate_income(base, iters);745746		base.checked_add(&income).map(|res| {747			<Staked<T>>::insert((staker, staked_block), (res, next_recalc_block));748			*income_acc += income;749		});750	}751752	fn calculate_income<I>(base: I, iters: u32) -> I753	where754		I: EncodeLike<BalanceOf<T>> + Balance,755	{756		let mut income = base;757758		(0..iters).for_each(|_| income += T::IntervalIncome::get() * income);759760		income - base761	}762763	fn get_current_recalc_block(current_relay_block: T::BlockNumber) -> T::BlockNumber {764		(current_relay_block / T::RecalculationInterval::get()) * T::RecalculationInterval::get()765	}766767	// fn get_next_recalc_block(current_relay_block: T::BlockNumber) -> T::BlockNumber {768	// 	Self::get_current_recalc_block(current_relay_block) + T::RecalculationInterval::get()769	// }770771	fn get_next_calculated_key() -> Option<Vec<u8>> {772		Self::get_next_calculated_record().map(|key| Staked::<T>::hashed_key_for(key))773	}774}775776impl<T: Config> Pallet<T>777where778	<<T as Config>::Currency as Currency<T::AccountId>>::Balance: Sum,779{780	pub fn cross_id_pending_unstake(staker: Option<T::CrossAccountId>) -> BalanceOf<T> {781		staker.map_or(782			PendingUnstake::<T>::iter_values()783				.flat_map(|pendings| pendings.into_iter().map(|(_, amount)| amount))784				.sum(),785			|s| {786				PendingUnstake::<T>::iter_values()787					.flatten()788					.filter_map(|(id, amount)| {789						if id == *s.as_sub() {790							Some(amount)791						} else {792							None793						}794					})795					.sum()796			},797		)798	}799800	pub fn cross_id_pending_unstake_per_block(801		staker: T::CrossAccountId,802	) -> Vec<(T::BlockNumber, BalanceOf<T>)> {803		let mut unsorted_res = vec![];804		PendingUnstake::<T>::iter().for_each(|(block, pendings)| {805			pendings.into_iter().for_each(|(id, amount)| {806				if id == *staker.as_sub() {807					unsorted_res.push((block, amount));808				};809			})810		});811812		unsorted_res.sort_by_key(|(block, _)| *block);813		unsorted_res814	}815}
modifiedpallets/app-promotion/src/types.rsdiffbeforeafterboth
--- a/pallets/app-promotion/src/types.rs
+++ b/pallets/app-promotion/src/types.rs
@@ -37,9 +37,8 @@
 
 	fn remove_collection_sponsor(collection_id: Self::CollectionId) -> DispatchResult;
 
-	fn get_sponsor(
-		collection_id: Self::CollectionId,
-	) -> Result<Option<Self::AccountId>, DispatchError>;
+	fn sponsor(collection_id: Self::CollectionId)
+		-> Result<Option<Self::AccountId>, DispatchError>;
 }
 
 impl<T: pallet_unique::Config> CollectionHandler for pallet_unique::Pallet<T> {
@@ -58,12 +57,12 @@
 		Self::force_remove_collection_sponsor(collection_id)
 	}
 
-	fn get_sponsor(
+	fn sponsor(
 		collection_id: Self::CollectionId,
 	) -> Result<Option<Self::AccountId>, DispatchError> {
 		Ok(<CollectionHandle<T>>::try_get(collection_id)?
 			.sponsorship
-			.pending_sponsor()
+			.sponsor()
 			.map(|acc| acc.to_owned()))
 	}
 }
@@ -79,7 +78,7 @@
 
 	fn remove_contract_sponsor(contract_address: Self::ContractId) -> DispatchResult;
 
-	fn get_sponsor(
+	fn sponsor(
 		contract_address: Self::ContractId,
 	) -> Result<Option<Self::AccountId>, DispatchError>;
 }
@@ -100,7 +99,7 @@
 		Self::force_remove_sponsor(contract_address)
 	}
 
-	fn get_sponsor(
+	fn sponsor(
 		contract_address: Self::ContractId,
 	) -> Result<Option<Self::AccountId>, DispatchError> {
 		Ok(Self::get_sponsor(contract_address))
modifiedpallets/app-promotion/src/weights.rsdiffbeforeafterboth
--- a/pallets/app-promotion/src/weights.rs
+++ b/pallets/app-promotion/src/weights.rs
@@ -3,7 +3,7 @@
 //! Autogenerated weights for pallet_app_promotion
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2022-09-06, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2022-09-07, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
 
 // Executed Command:
@@ -51,16 +51,16 @@
 	// Storage: AppPromotion PendingUnstake (r:1 w:0)
 	// Storage: System Account (r:1 w:1)
 	fn on_initialize(b: u32, ) -> Weight {
-		(2_461_000 as Weight)
-			// Standard Error: 87_000
-			.saturating_add((6_006_000 as Weight).saturating_mul(b as Weight))
+		(2_651_000 as Weight)
+			// Standard Error: 103_000
+			.saturating_add((6_024_000 as Weight).saturating_mul(b as Weight))
 			.saturating_add(T::DbWeight::get().reads(1 as Weight))
 			.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
 			.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
 	}
 	// Storage: AppPromotion Admin (r:0 w:1)
 	fn set_admin_address() -> Weight {
-		(5_467_000 as Weight)
+		(7_117_000 as Weight)
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
@@ -68,21 +68,21 @@
 	// Storage: AppPromotion NextCalculatedRecord (r:1 w:1)
 	// Storage: AppPromotion Staked (r:2 w:0)
 	fn payout_stakers(b: u32, ) -> Weight {
-		(4_946_000 as Weight)
-			// Standard Error: 5_000
-			.saturating_add((4_599_000 as Weight).saturating_mul(b as Weight))
+		(9_958_000 as Weight)
+			// Standard Error: 8_000
+			.saturating_add((4_406_000 as Weight).saturating_mul(b as Weight))
 			.saturating_add(T::DbWeight::get().reads(4 as Weight))
 			.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
+	// Storage: AppPromotion StakesPerAccount (r:1 w:1)
 	// Storage: System Account (r:1 w:1)
-	// Storage: AppPromotion StakesPerAccount (r:1 w:1)
 	// Storage: Balances Locks (r:1 w:1)
 	// Storage: ParachainSystem ValidationData (r:1 w:0)
 	// Storage: AppPromotion Staked (r:1 w:1)
 	// Storage: AppPromotion TotalStaked (r:1 w:1)
 	fn stake() -> Weight {
-		(17_766_000 as Weight)
+		(20_574_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(6 as Weight))
 			.saturating_add(T::DbWeight::get().writes(5 as Weight))
 	}
@@ -93,35 +93,35 @@
 	// Storage: AppPromotion TotalStaked (r:1 w:1)
 	// Storage: AppPromotion StakesPerAccount (r:0 w:1)
 	fn unstake() -> Weight {
-		(27_250_000 as Weight)
+		(31_703_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(6 as Weight))
 			.saturating_add(T::DbWeight::get().writes(6 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
 	// Storage: Common CollectionById (r:1 w:1)
 	fn sponsor_collection() -> Weight {
-		(11_014_000 as Weight)
+		(12_932_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
 	// Storage: Common CollectionById (r:1 w:1)
 	fn stop_sponsoring_collection() -> Weight {
-		(10_494_000 as Weight)
+		(12_453_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
 	// Storage: EvmContractHelpers Sponsoring (r:0 w:1)
 	fn sponsor_contract() -> Weight {
-		(9_754_000 as Weight)
+		(11_952_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(1 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
 	// Storage: EvmContractHelpers Sponsoring (r:1 w:1)
 	fn stop_sponsoring_contract() -> Weight {
-		(10_063_000 as Weight)
+		(12_538_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
@@ -132,16 +132,16 @@
 	// Storage: AppPromotion PendingUnstake (r:1 w:0)
 	// Storage: System Account (r:1 w:1)
 	fn on_initialize(b: u32, ) -> Weight {
-		(2_461_000 as Weight)
-			// Standard Error: 87_000
-			.saturating_add((6_006_000 as Weight).saturating_mul(b as Weight))
+		(2_651_000 as Weight)
+			// Standard Error: 103_000
+			.saturating_add((6_024_000 as Weight).saturating_mul(b as Weight))
 			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
 			.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
 			.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(b as Weight)))
 	}
 	// Storage: AppPromotion Admin (r:0 w:1)
 	fn set_admin_address() -> Weight {
-		(5_467_000 as Weight)
+		(7_117_000 as Weight)
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
@@ -149,21 +149,21 @@
 	// Storage: AppPromotion NextCalculatedRecord (r:1 w:1)
 	// Storage: AppPromotion Staked (r:2 w:0)
 	fn payout_stakers(b: u32, ) -> Weight {
-		(4_946_000 as Weight)
-			// Standard Error: 5_000
-			.saturating_add((4_599_000 as Weight).saturating_mul(b as Weight))
+		(9_958_000 as Weight)
+			// Standard Error: 8_000
+			.saturating_add((4_406_000 as Weight).saturating_mul(b as Weight))
 			.saturating_add(RocksDbWeight::get().reads(4 as Weight))
 			.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(b as Weight)))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
+	// Storage: AppPromotion StakesPerAccount (r:1 w:1)
 	// Storage: System Account (r:1 w:1)
-	// Storage: AppPromotion StakesPerAccount (r:1 w:1)
 	// Storage: Balances Locks (r:1 w:1)
 	// Storage: ParachainSystem ValidationData (r:1 w:0)
 	// Storage: AppPromotion Staked (r:1 w:1)
 	// Storage: AppPromotion TotalStaked (r:1 w:1)
 	fn stake() -> Weight {
-		(17_766_000 as Weight)
+		(20_574_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(6 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(5 as Weight))
 	}
@@ -174,35 +174,35 @@
 	// Storage: AppPromotion TotalStaked (r:1 w:1)
 	// Storage: AppPromotion StakesPerAccount (r:0 w:1)
 	fn unstake() -> Weight {
-		(27_250_000 as Weight)
+		(31_703_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(6 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(6 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
 	// Storage: Common CollectionById (r:1 w:1)
 	fn sponsor_collection() -> Weight {
-		(11_014_000 as Weight)
+		(12_932_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
 	// Storage: Common CollectionById (r:1 w:1)
 	fn stop_sponsoring_collection() -> Weight {
-		(10_494_000 as Weight)
+		(12_453_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
 	// Storage: EvmContractHelpers Sponsoring (r:0 w:1)
 	fn sponsor_contract() -> Weight {
-		(9_754_000 as Weight)
+		(11_952_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 	// Storage: AppPromotion Admin (r:1 w:0)
 	// Storage: EvmContractHelpers Sponsoring (r:1 w:1)
 	fn stop_sponsoring_contract() -> Weight {
-		(10_063_000 as Weight)
+		(12_538_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
modifiedtests/src/app-promotion.test.tsdiffbeforeafterboth
--- a/tests/src/app-promotion.test.ts
+++ b/tests/src/app-promotion.test.ts
@@ -460,7 +460,7 @@
       const flipper = await deployFlipper(web3, contractOwner);
       const contractMethods = contractHelpers(web3, contractOwner);
 
-      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorConract(flipper.options.address));
+      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));
       
       expect(await contractMethods.methods.hasSponsor(flipper.options.address).call()).to.be.true;  
       expect((await api.query.evmContractHelpers.owner(flipper.options.address)).toJSON()).to.be.equal(contractOwner);  
@@ -488,7 +488,7 @@
       });
 
       // set promotion sponsoring
-      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorConract(flipper.options.address));
+      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));
 
       // new sponsor is pallet address
       expect(await contractMethods.methods.hasSponsor(flipper.options.address).call()).to.be.true;  
@@ -508,7 +508,7 @@
       const contractMethods = contractHelpers(web3, contractOwner);
 
       // contract sponsored by pallet
-      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorConract(flipper.options.address));
+      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));
 
       // owner sets self sponsoring
       await expect(contractMethods.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;
@@ -532,8 +532,8 @@
 
       await expect(contractMethods.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;
 
-      // nonAdmin calls sponsorConract
-      await expect(helper.signTransaction(nonAdmin, api.tx.appPromotion.sponsorConract(flipper.options.address))).to.be.rejected;
+      // nonAdmin calls sponsorContract
+      await expect(helper.signTransaction(nonAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address))).to.be.rejected;
 
       // contract still self-sponsored 
       expect((await api.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({
@@ -560,7 +560,7 @@
       await contractHelper.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: contractOwner});
       await transferBalanceToEth(api, alice, flipper.options.address, 1000n);
 
-      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorConract(flipper.options.address));
+      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));
       await flipper.methods.flip().send({from: caller});
       expect(await flipper.methods.getValue().call()).to.be.true;
 
@@ -582,7 +582,7 @@
       await transferBalanceToEth(api, alice, flipper.options.address);
       const contractHelper = contractHelpers(web3, contractOwner);
       await contractHelper.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: contractOwner});
-      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorConract(flipper.options.address));
+      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));
       await helper.signTransaction(palletAdmin, api.tx.appPromotion.stopSponsoringContract(flipper.options.address));
 
       expect(await contractHelper.methods.hasSponsor(flipper.options.address).call()).to.be.false;  
@@ -609,7 +609,7 @@
       const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();
       const flipper = await deployFlipper(web3, contractOwner);
 
-      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorConract(flipper.options.address));
+      await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));
       await expect(helper.signTransaction(nonAdmin, api.tx.appPromotion.stopSponsoringContract(flipper.options.address))).to.be.rejected;
     });
   });
modifiedtests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-tx.ts
+++ b/tests/src/interfaces/augment-api-tx.ts
@@ -21,7 +21,7 @@
       payoutStakers: AugmentedSubmittable<(stakersNumber: Option<u8> | null | Uint8Array | u8 | AnyNumber) => SubmittableExtrinsic<ApiType>, [Option<u8>]>;
       setAdminAddress: AugmentedSubmittable<(admin: PalletEvmAccountBasicCrossAccountIdRepr | { Substrate: any } | { Ethereum: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [PalletEvmAccountBasicCrossAccountIdRepr]>;
       sponsorCollection: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
-      sponsorConract: AugmentedSubmittable<(contractId: H160 | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [H160]>;
+      sponsorContract: AugmentedSubmittable<(contractId: H160 | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [H160]>;
       stake: AugmentedSubmittable<(amount: u128 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u128]>;
       stopSponsoringCollection: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32]>;
       stopSponsoringContract: AugmentedSubmittable<(contractId: H160 | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [H160]>;
modifiedtests/src/interfaces/default/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/default/types.ts
+++ b/tests/src/interfaces/default/types.ts
@@ -825,8 +825,8 @@
   readonly asStopSponsoringCollection: {
     readonly collectionId: u32;
   } & Struct;
-  readonly isSponsorConract: boolean;
-  readonly asSponsorConract: {
+  readonly isSponsorContract: boolean;
+  readonly asSponsorContract: {
     readonly contractId: H160;
   } & Struct;
   readonly isStopSponsoringContract: boolean;
@@ -837,7 +837,7 @@
   readonly asPayoutStakers: {
     readonly stakersNumber: Option<u8>;
   } & Struct;
-  readonly type: 'SetAdminAddress' | 'Stake' | 'Unstake' | 'SponsorCollection' | 'StopSponsoringCollection' | 'SponsorConract' | 'StopSponsoringContract' | 'PayoutStakers';
+  readonly type: 'SetAdminAddress' | 'Stake' | 'Unstake' | 'SponsorCollection' | 'StopSponsoringCollection' | 'SponsorContract' | 'StopSponsoringContract' | 'PayoutStakers';
 }
 
 /** @name PalletAppPromotionError */
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -2483,7 +2483,7 @@
       stop_sponsoring_collection: {
         collectionId: 'u32',
       },
-      sponsor_conract: {
+      sponsor_contract: {
         contractId: 'H160',
       },
       stop_sponsoring_contract: {
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -2695,8 +2695,8 @@
     readonly asStopSponsoringCollection: {
       readonly collectionId: u32;
     } & Struct;
-    readonly isSponsorConract: boolean;
-    readonly asSponsorConract: {
+    readonly isSponsorContract: boolean;
+    readonly asSponsorContract: {
       readonly contractId: H160;
     } & Struct;
     readonly isStopSponsoringContract: boolean;
@@ -2707,7 +2707,7 @@
     readonly asPayoutStakers: {
       readonly stakersNumber: Option<u8>;
     } & Struct;
-    readonly type: 'SetAdminAddress' | 'Stake' | 'Unstake' | 'SponsorCollection' | 'StopSponsoringCollection' | 'SponsorConract' | 'StopSponsoringContract' | 'PayoutStakers';
+    readonly type: 'SetAdminAddress' | 'Stake' | 'Unstake' | 'SponsorCollection' | 'StopSponsoringCollection' | 'SponsorContract' | 'StopSponsoringContract' | 'PayoutStakers';
   }
 
   /** @name PalletEvmCall (307) */
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -68,7 +68,7 @@
       const refungible = 'refungible';
       const scheduler = 'scheduler';
       const rmrkPallets = ['rmrkcore', 'rmrkequip'];
-      const appPromotion = 'promotion';
+      const appPromotion = 'apppromotion';
 
       if (chain.eq('OPAL by UNIQUE')) {
         requiredPallets.push(refungible, scheduler, appPromotion, ...rmrkPallets);