git.delta.rocks / unique-network / refs/commits / 5aafe0c25b7b

difftreelog

add contracts consts

PraetorP2022-11-24parent: #c4f8efb.patch.diff
in: master

7 files changed

modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -376,6 +376,7 @@
 		type TreasuryAccountId: Get<Self::AccountId>;
 
 		/// Address under which the CollectionHelper contract would be available.
+		#[pallet::constant]
 		type ContractAddress: Get<H160>;
 
 		/// Mapper for token addresses to Ethereum addresses.
modifiedpallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth
after · pallets/evm-contract-helpers/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#![doc = include_str!("../README.md")]18#![cfg_attr(not(feature = "std"), no_std)]19#![warn(missing_docs)]2021use codec::{Decode, Encode, MaxEncodedLen};22pub use pallet::*;23pub use eth::*;24use scale_info::TypeInfo;25use frame_support::storage::bounded_btree_map::BoundedBTreeMap;26pub mod eth;2728/// Maximum number of methods per contract that could have fee limit29pub const MAX_FEE_LIMITED_METHODS: u32 = 5;3031#[frame_support::pallet]32pub mod pallet {33	pub use super::*;34	use crate::eth::ContractHelpersEvents;35	use frame_support::pallet_prelude::*;36	use pallet_evm_coder_substrate::DispatchResult;37	use sp_core::{H160, U256};38	use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};39	use up_data_structs::SponsorshipState;40	use evm_coder::ToLog;4142	#[pallet::config]43	pub trait Config:44		frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::Config45	{46		/// Overarching event type.47		type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;4849		/// Address, under which magic contract will be available50		#[pallet::constant]51		type ContractAddress: Get<H160>;5253		/// In case of enabled sponsoring, but no sponsoring rate limit set,54		/// this value will be used implicitly55		type DefaultSponsoringRateLimit: Get<Self::BlockNumber>;56	}5758	#[pallet::error]59	pub enum Error<T> {60		/// This method is only executable by contract owner61		NoPermission,6263		/// No pending sponsor for contract.64		NoPendingSponsor,6566		/// Number of methods that sponsored limit is defined for exceeds maximum.67		TooManyMethodsHaveSponsoredLimit,68	}6970	#[pallet::pallet]71	#[pallet::generate_store(pub(super) trait Store)]72	pub struct Pallet<T>(_);7374	/// Store owner for contract.75	///76	/// * **Key** - contract address.77	/// * **Value** - owner for contract.78	#[pallet::storage]79	pub(super) type Owner<T: Config> =80		StorageMap<Hasher = Twox128, Key = H160, Value = H160, QueryKind = ValueQuery>;8182	#[pallet::storage]83	#[deprecated]84	pub(super) type SelfSponsoring<T: Config> =85		StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;8687	/// Store for contract sponsorship state.88	///89	/// * **Key** - contract address.90	/// * **Value** - sponsorship state.91	#[pallet::storage]92	pub(super) type Sponsoring<T: Config> = StorageMap<93		Hasher = Twox64Concat,94		Key = H160,95		Value = SponsorshipState<T::CrossAccountId>,96		QueryKind = ValueQuery,97	>;9899	/// Store for sponsoring mode.100	///101	/// ### Usage102	/// Prefer to delete collection from storage if mode chaged to [`Disabled`](SponsoringModeT::Disabled).103	///104	/// * **Key** - contract address.105	/// * **Value** - [`sponsoring mode`](SponsoringModeT).106	#[pallet::storage]107	pub(super) type SponsoringMode<T: Config> =108		StorageMap<Hasher = Twox128, Key = H160, Value = SponsoringModeT, QueryKind = OptionQuery>;109110	/// Storage for sponsoring rate limit in blocks.111	///112	/// * **Key** - contract address.113	/// * **Value** - amount of sponsored blocks.114	#[pallet::storage]115	pub(super) type SponsoringRateLimit<T: Config> = StorageMap<116		Hasher = Twox128,117		Key = H160,118		Value = T::BlockNumber,119		QueryKind = ValueQuery,120		OnEmpty = T::DefaultSponsoringRateLimit,121	>;122123	/// Storage for last sponsored block.124	///125	/// * **Key1** - contract address.126	/// * **Key2** - sponsored user address.127	/// * **Value** - last sponsored block number.128	#[pallet::storage]129	pub(super) type SponsoringFeeLimit<T: Config> = StorageMap<130		Hasher = Twox128,131		Key = H160,132		Value = BoundedBTreeMap<u32, U256, ConstU32<MAX_FEE_LIMITED_METHODS>>,133		QueryKind = ValueQuery,134	>;135136	#[pallet::storage]137	pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<138		Hasher1 = Twox128,139		Key1 = H160,140		Hasher2 = Twox128,141		Key2 = H160,142		Value = T::BlockNumber,143		QueryKind = OptionQuery,144	>;145146	/// Storege for contracts with [`Allowlisted`](SponsoringModeT::Allowlisted) sponsoring mode.147	///148	/// ### Usage149	/// Prefer to delete collection from storage if mode chaged to non `Allowlisted`, than set **Value** to **false**.150	///151	/// * **Key** - contract address.152	/// * **Value** - is contract in [`Allowlisted`](SponsoringModeT::Allowlisted) mode.153	#[pallet::storage]154	pub(super) type AllowlistEnabled<T: Config> =155		StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;156157	/// Storage for users that allowed for sponsorship.158	///159	/// ### Usage160	/// Prefer to delete record from storage if user no more allowed for sponsorship.161	///162	/// * **Key1** - contract address.163	/// * **Key2** - user that allowed for sponsorship.164	/// * **Value** - allowance for sponsorship.165	#[pallet::storage]166	pub(super) type Allowlist<T: Config> = StorageDoubleMap<167		Hasher1 = Twox128,168		Key1 = H160,169		Hasher2 = Twox128,170		Key2 = H160,171		Value = bool,172		QueryKind = ValueQuery,173	>;174175	#[pallet::event]176	#[pallet::generate_deposit(fn deposit_event)]177	pub enum Event<T: Config> {178		/// Contract sponsor was set.179		ContractSponsorSet(180			/// Contract address of the affected collection.181			H160,182			/// New sponsor address.183			T::AccountId,184		),185186		/// New sponsor was confirm.187		ContractSponsorshipConfirmed(188			/// Contract address of the affected collection.189			H160,190			/// New sponsor address.191			T::AccountId,192		),193194		/// Collection sponsor was removed.195		ContractSponsorRemoved(196			/// Contract address of the affected collection.197			H160,198		),199	}200201	impl<T: Config> Pallet<T> {202		/// Get contract owner.203		pub fn contract_owner(contract: H160) -> H160 {204			<Owner<T>>::get(contract)205		}206207		/// Set `sponsor` for `contract`.208		///209		/// `sender` must be owner of contract.210		pub fn set_sponsor(211			sender: &T::CrossAccountId,212			contract: H160,213			sponsor: &T::CrossAccountId,214		) -> DispatchResult {215			Pallet::<T>::ensure_owner(contract, *sender.as_eth())?;216			Sponsoring::<T>::insert(217				contract,218				SponsorshipState::<T::CrossAccountId>::Unconfirmed(sponsor.clone()),219			);220221			<Pallet<T>>::deposit_event(Event::<T>::ContractSponsorSet(222				contract,223				sponsor.as_sub().clone(),224			));225			<PalletEvm<T>>::deposit_log(226				ContractHelpersEvents::ContractSponsorSet {227					contract_address: contract,228					sponsor: *sponsor.as_eth(),229				}230				.to_log(contract),231			);232			Ok(())233		}234235		/// Force set `sponsor` for `contract`.236		///237		/// Differs from `set_sponsor` in that confirmation238		/// from the sponsor is not required.239		pub fn force_set_sponsor(240			contract_address: H160,241			sponsor: &T::CrossAccountId,242		) -> DispatchResult {243			Sponsoring::<T>::insert(244				contract_address,245				SponsorshipState::<T::CrossAccountId>::Confirmed(sponsor.clone()),246			);247248			let eth_sponsor = *sponsor.as_eth();249			let sub_sponsor = sponsor.as_sub().clone();250251			<Pallet<T>>::deposit_event(Event::<T>::ContractSponsorSet(252				contract_address,253				sub_sponsor.clone(),254			));255			<PalletEvm<T>>::deposit_log(256				ContractHelpersEvents::ContractSponsorSet {257					contract_address,258					sponsor: eth_sponsor,259				}260				.to_log(contract_address),261			);262263			<Pallet<T>>::deposit_event(Event::<T>::ContractSponsorshipConfirmed(264				contract_address,265				sub_sponsor,266			));267			<PalletEvm<T>>::deposit_log(268				ContractHelpersEvents::ContractSponsorshipConfirmed {269					contract_address,270					sponsor: eth_sponsor,271				}272				.to_log(contract_address),273			);274275			Ok(())276		}277278		/// Remove sponsor for `contract`.279		///280		/// `sender` must be owner of contract.281		pub fn remove_sponsor(282			sender: &T::CrossAccountId,283			contract_address: H160,284		) -> DispatchResult {285			Self::ensure_owner(contract_address, *sender.as_eth())?;286			Self::force_remove_sponsor(contract_address)287		}288289		/// Force remove `sponsor` for `contract`.290		///291		/// Differs from `remove_sponsor` in that292		/// it doesn't require consent from the `owner` of the contract.293		pub fn force_remove_sponsor(contract_address: H160) -> DispatchResult {294			Sponsoring::<T>::remove(contract_address);295296			Self::deposit_event(Event::<T>::ContractSponsorRemoved(contract_address));297			<PalletEvm<T>>::deposit_log(298				ContractHelpersEvents::ContractSponsorRemoved { contract_address }299					.to_log(contract_address),300			);301302			Ok(())303		}304305		/// Confirm sponsorship.306		///307		/// `sender` must be same that set via [`set_sponsor`].308		pub fn confirm_sponsorship(309			sender: &T::CrossAccountId,310			contract_address: H160,311		) -> DispatchResult {312			match Sponsoring::<T>::get(contract_address) {313				SponsorshipState::Unconfirmed(sponsor) => {314					ensure!(sponsor == *sender, Error::<T>::NoPermission);315					let eth_sponsor = *sponsor.as_eth();316					let sub_sponsor = sponsor.as_sub().clone();317					Sponsoring::<T>::insert(318						contract_address,319						SponsorshipState::<T::CrossAccountId>::Confirmed(sponsor),320					);321322					<Pallet<T>>::deposit_event(Event::<T>::ContractSponsorshipConfirmed(323						contract_address,324						sub_sponsor,325					));326					<PalletEvm<T>>::deposit_log(327						ContractHelpersEvents::ContractSponsorshipConfirmed {328							contract_address,329							sponsor: eth_sponsor,330						}331						.to_log(contract_address),332					);333334					Ok(())335				}336				SponsorshipState::Disabled | SponsorshipState::Confirmed(_) => {337					Err(Error::<T>::NoPendingSponsor.into())338				}339			}340		}341342		/// Get sponsor.343		pub fn get_sponsor(contract: H160) -> Option<T::CrossAccountId> {344			match Sponsoring::<T>::get(contract) {345				SponsorshipState::Disabled | SponsorshipState::Unconfirmed(_) => None,346				SponsorshipState::Confirmed(sponsor) => Some(sponsor),347			}348		}349350		/// Get current sponsoring mode, performing lazy migration from legacy storage351		pub fn sponsoring_mode(contract: H160) -> SponsoringModeT {352			<SponsoringMode<T>>::get(contract)353				.or_else(|| {354					#[allow(deprecated)]355					<SelfSponsoring<T>>::get(contract).then(|| SponsoringModeT::Allowlisted)356				})357				.unwrap_or_default()358		}359360		/// Reconfigure contract sponsoring mode361		pub fn set_sponsoring_mode(contract: H160, mode: SponsoringModeT) {362			if mode == SponsoringModeT::Disabled {363				<SponsoringMode<T>>::remove(contract);364			} else {365				<SponsoringMode<T>>::insert(contract, mode);366			}367			#[allow(deprecated)]368			<SelfSponsoring<T>>::remove(contract)369		}370371		/// Set duration between two sponsored contract calls372		pub fn set_sponsoring_rate_limit(contract: H160, rate_limit: T::BlockNumber) {373			<SponsoringRateLimit<T>>::insert(contract, rate_limit);374		}375376		/// Set maximum for gas limit of transaction377		pub fn set_sponsoring_fee_limit(contract: H160, fee_limit: U256) -> DispatchResult {378			<SponsoringFeeLimit<T>>::try_mutate(contract, |limits_map| {379				limits_map380					.try_insert(0xffffffff, fee_limit)381					.map_err(|_| <Error<T>>::TooManyMethodsHaveSponsoredLimit)382			})?;383			Ok(())384		}385386		/// Is user added to allowlist, or he is owner of specified contract387		pub fn allowed(contract: H160, user: H160) -> bool {388			<Allowlist<T>>::get(&contract, &user) || <Owner<T>>::get(&contract) == user389		}390391		/// Toggle contract allowlist access392		pub fn toggle_allowlist(contract: H160, enabled: bool) {393			<AllowlistEnabled<T>>::insert(contract, enabled)394		}395396		/// Toggle user presence in contract's allowlist397		pub fn toggle_allowed(contract: H160, user: H160, allowed: bool) {398			<Allowlist<T>>::insert(contract, user, allowed);399		}400401		/// Throw error if user is not allowed to reconfigure target contract402		pub fn ensure_owner(contract: H160, user: H160) -> DispatchResult {403			ensure!(<Owner<T>>::get(&contract) == user, Error::<T>::NoPermission);404			Ok(())405		}406	}407}408409/// Available contract sponsoring modes410#[derive(Encode, Decode, PartialEq, TypeInfo, MaxEncodedLen, Default)]411pub enum SponsoringModeT {412	/// Sponsoring is disabled413	#[default]414	Disabled,415	/// Only users from allowlist will be sponsored416	Allowlisted,417	/// All users will be sponsored418	Generous,419}420421impl SponsoringModeT {422	fn from_eth(v: u8) -> Option<Self> {423		Some(match v {424			0 => Self::Disabled,425			1 => Self::Allowlisted,426			2 => Self::Generous,427			_ => return None,428		})429	}430	#[allow(dead_code)]431	fn to_eth(self) -> u8 {432		match self {433			SponsoringModeT::Disabled => 0,434			SponsoringModeT::Allowlisted => 1,435			SponsoringModeT::Generous => 2,436		}437	}438}
modifiedtests/src/apiConsts.test.tsdiffbeforeafterboth
--- a/tests/src/apiConsts.test.ts
+++ b/tests/src/apiConsts.test.ts
@@ -15,6 +15,7 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {ApiPromise} from '@polkadot/api';
+import {ApiBase} from '@polkadot/api/base';
 import {usingPlaygrounds, itSub, expect} from './util';
 
 
@@ -41,6 +42,9 @@
   transfersEnabled: true,
 };
 
+const EVM_COLLECTION_HELPERS_ADDRESS = '0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f';
+const HELPERS_CONTRACT_ADDRESS = '0x842899ECF380553E8a4de75bF534cdf6fBF64049';
+
 describe('integration test: API UNIQUE consts', () => {
   let api: ApiPromise;
   
@@ -101,6 +105,14 @@
   itSub('COLLECTION_ADMINS_LIMIT', () => {
     checkConst(api.consts.unique.collectionAdminsLimit, COLLECTION_ADMINS_LIMIT);
   });
+  
+  itSub('HELPERS_CONTRACT_ADDRESS', () => {
+    expect(api.consts.evmContractHelpers.contractAddress.toString().toLowerCase()).to.be.equal(HELPERS_CONTRACT_ADDRESS.toLowerCase());
+  });
+  
+  itSub('EVM_COLLECTION_HELPERS_ADDRESS', () => {
+    expect(api.consts.common.contractAddress.toString().toLowerCase()).to.be.equal(EVM_COLLECTION_HELPERS_ADDRESS.toLowerCase());
+  });
 });
 
 function checkConst<T>(constValue: any, expectedValue: T) {
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -103,12 +103,12 @@
 
   contractHelpers(caller: string): Contract {
     const web3 = this.helper.getWeb3();
-    return new web3.eth.Contract(contractHelpersAbi as any, '0x842899ECF380553E8a4de75bF534cdf6fBF64049', {from: caller, gas: this.helper.eth.DEFAULT_GAS});
+    return new web3.eth.Contract(contractHelpersAbi as any, this.helper.getApi().consts.evmContractHelpers.contractAddress.toString(), {from: caller, gas: this.helper.eth.DEFAULT_GAS});
   }
 
   collectionHelpers(caller: string) {
     const web3 = this.helper.getWeb3();
-    return new web3.eth.Contract(collectionHelpersAbi as any, '0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f', {from: caller, gas: this.helper.eth.DEFAULT_GAS});
+    return new web3.eth.Contract(collectionHelpersAbi as any, this.helper.getApi().consts.common.contractAddress.toString(), {from: caller, gas: this.helper.eth.DEFAULT_GAS});
   }
 
   collection(address: string, mode: TCollectionMode, caller?: string, mergeDeprecated = false): Contract {
modifiedtests/src/interfaces/augment-api-consts.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-consts.ts
+++ b/tests/src/interfaces/augment-api-consts.ts
@@ -8,7 +8,7 @@
 import type { ApiTypes, AugmentedConst } from '@polkadot/api-base/types';
 import type { Option, u128, u16, u32, u64, u8 } from '@polkadot/types-codec';
 import type { Codec } from '@polkadot/types-codec/types';
-import type { Perbill, Permill, Weight } from '@polkadot/types/interfaces/runtime';
+import type { H160, Perbill, Permill, Weight } from '@polkadot/types/interfaces/runtime';
 import type { FrameSupportPalletId, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, SpVersionRuntimeVersion, SpWeightsRuntimeDbWeight, UpDataStructsCollectionLimits, XcmV1MultiLocation } from '@polkadot/types/lookup';
 
 export type __AugmentedConst<ApiType extends ApiTypes> = AugmentedConst<ApiType>;
@@ -70,6 +70,10 @@
        **/
       collectionCreationPrice: u128 & AugmentedConst<ApiType>;
       /**
+       * Address under which the CollectionHelper contract would be available.
+       **/
+      contractAddress: H160 & AugmentedConst<ApiType>;
+      /**
        * Generic const
        **/
       [key: string]: Codec;
@@ -82,6 +86,16 @@
        **/
       [key: string]: Codec;
     };
+    evmContractHelpers: {
+      /**
+       * Address, under which magic contract will be available
+       **/
+      contractAddress: H160 & AugmentedConst<ApiType>;
+      /**
+       * Generic const
+       **/
+      [key: string]: Codec;
+    };
     inflation: {
       /**
        * Number of blocks that pass between treasury balance updates due to inflation
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -2936,13 +2936,13 @@
     }
   },
   /**
-   * Lookup340: pallet_maintenance::pallet::Call<T>
+   * Lookup338: pallet_maintenance::pallet::Call<T>
    **/
   PalletMaintenanceCall: {
     _enum: ['enable', 'disable']
   },
   /**
-   * Lookup341: pallet_test_utils::pallet::Call<T>
+   * Lookup339: pallet_test_utils::pallet::Call<T>
    **/
   PalletTestUtilsCall: {
     _enum: {
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -3175,14 +3175,14 @@
     readonly type: 'Begin' | 'SetData' | 'Finish' | 'InsertEthLogs' | 'InsertEvents';
   }
 
-  /** @name PalletMaintenanceCall (340) */
+  /** @name PalletMaintenanceCall (338) */
   interface PalletMaintenanceCall extends Enum {
     readonly isEnable: boolean;
     readonly isDisable: boolean;
     readonly type: 'Enable' | 'Disable';
   }
 
-  /** @name PalletTestUtilsCall (341) */
+  /** @name PalletTestUtilsCall (339) */
   interface PalletTestUtilsCall extends Enum {
     readonly isEnable: boolean;
     readonly isSetTestValue: boolean;