difftreelog
fix evm nitpicks
in: master
11 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4290,9 +4290,6 @@
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-dependencies = [
- "spin",
-]
[[package]]
name = "lazycell"
@@ -5920,7 +5917,6 @@
"frame-benchmarking",
"frame-support",
"frame-system",
- "lazy_static",
"pallet-evm",
"pallet-evm-coder-substrate",
"parity-scale-codec 3.1.2",
pallets/common/Cargo.tomldiffbeforeafterboth--- a/pallets/common/Cargo.toml
+++ b/pallets/common/Cargo.toml
@@ -27,7 +27,6 @@
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
-lazy_static = { version = "1.4.0", default-features = false, features = ["spin_no_std"] }
[features]
default = ["std"]
pallets/common/src/erc.rsdiffbeforeafterboth1// 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/>.1617use evm_coder::{18 solidity_interface,19 types::*,20 execution::{Result, Error},21};22pub use pallet_evm::{PrecompileOutput, PrecompileResult, account::CrossAccountId};23use pallet_evm_coder_substrate::dispatch_to_evm;24use sp_core::{H160, U256};25use sp_std::vec::Vec;26use up_data_structs::{Property, SponsoringRateLimit};27use alloc::format;2829use crate::{Pallet, CollectionHandle, Config, CollectionProperties};3031/// Does not always represent a full collection, for RFT it is either32/// collection (Implementing ERC721), or specific collection token (Implementing ERC20)33pub trait CommonEvmHandler {34 const CODE: &'static [u8];3536 fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileResult>;37}3839#[solidity_interface(name = "Collection")]40impl<T: Config> CollectionHandle<T> {41 fn set_collection_property(&mut self, caller: caller, key: string, value: bytes) -> Result<()> {42 let caller = T::CrossAccountId::from_eth(caller);43 let key = <Vec<u8>>::from(key)44 .try_into()45 .map_err(|_| "key too large")?;46 let value = value.try_into().map_err(|_| "value too large")?;4748 <Pallet<T>>::set_collection_property(self, &caller, Property { key, value })49 .map_err(dispatch_to_evm::<T>)50 }5152 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {53 let caller = T::CrossAccountId::from_eth(caller);54 let key = <Vec<u8>>::from(key)55 .try_into()56 .map_err(|_| "key too large")?;5758 <Pallet<T>>::delete_collection_property(self, &caller, key).map_err(dispatch_to_evm::<T>)59 }6061 /// Throws error if key not found62 fn collection_property(&self, key: string) -> Result<bytes> {63 let key = <Vec<u8>>::from(key)64 .try_into()65 .map_err(|_| "key too large")?;6667 let props = <CollectionProperties<T>>::get(self.id);68 let prop = props.get(&key).ok_or("key not found")?;6970 Ok(prop.to_vec())71 }7273 fn eth_set_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {74 check_is_owner(caller, self)?;7576 let sponsor = T::CrossAccountId::from_eth(sponsor);77 self.set_sponsor(sponsor.as_sub().clone());78 save(self);79 Ok(())80 }8182 fn eth_confirm_sponsorship(&mut self, caller: caller) -> Result<void> {83 let caller = T::CrossAccountId::from_eth(caller);84 if !self.confirm_sponsorship(caller.as_sub()) {85 return Err(Error::Revert("Caller is not set as sponsor".into()));86 }87 save(self);88 Ok(())89 }9091 fn set_limit(&mut self, caller: caller, limit: string, value: string) -> Result<void> {92 check_is_owner(caller, self)?;93 let mut limits = self.limits.clone();9495 match limit.as_str() {96 "accountTokenOwnershipLimit" => {97 limits.account_token_ownership_limit = parse_int(value)?;98 }99 "sponsoredDataSize" => {100 limits.sponsored_data_size = parse_int(value)?;101 }102 "sponsoredDataRateLimit" => {103 limits.sponsored_data_rate_limit =104 Some(SponsoringRateLimit::Blocks(parse_int(value)?.unwrap()));105 }106 "tokenLimit" => {107 limits.token_limit = parse_int(value)?;108 }109 "sponsorTransferTimeout" => {110 limits.sponsor_transfer_timeout = parse_int(value)?;111 }112 "sponsorApproveTimeout" => {113 limits.sponsor_approve_timeout = parse_int(value)?;114 }115 "ownerCanTransfer" => {116 limits.owner_can_transfer = parse_bool(value)?;117 }118 "ownerCanDestroy" => {119 limits.owner_can_destroy = parse_bool(value)?;120 }121 "transfersEnabled" => {122 limits.transfers_enabled = parse_bool(value)?;123 }124 _ => return Err(Error::Revert(format!("Unknown limit \"{}\"", limit))),125 }126 self.limits = <Pallet<T>>::clamp_limits(self.mode.clone(), &self.limits, limits)127 .map_err(dispatch_to_evm::<T>)?;128 save(self);129 Ok(())130 }131132 fn contract_address(&self, _caller: caller) -> Result<address> {133 Ok(crate::eth::collection_id_to_address(self.id))134 }135}136137fn check_is_owner<T: Config>(caller: caller, collection: &CollectionHandle<T>) -> Result<()> {138 let caller = T::CrossAccountId::from_eth(caller);139 collection140 .check_is_owner(&caller)141 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;142 Ok(())143}144145fn save<T: Config>(collection: &CollectionHandle<T>) {146 <crate::CollectionById<T>>::insert(collection.id, collection.collection.clone());147}148149fn parse_int(value: string) -> Result<Option<u32>> {150 value151 .parse::<u32>()152 .map_err(|e| Error::Revert(format!("Int value \"{}\" parse error: {}", value, e)))153 .map(|value| Some(value))154}155156fn parse_bool(value: string) -> Result<Option<bool>> {157 value158 .parse::<bool>()159 .map_err(|e| Error::Revert(format!("Bool value \"{}\" parse error: {}", value, e)))160 .map(|value| Some(value))161}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/>.1617use evm_coder::{18 solidity_interface, solidity,19 types::*,20 execution::{Result, Error},21};22pub use pallet_evm::{PrecompileOutput, PrecompileResult, account::CrossAccountId};23use pallet_evm_coder_substrate::dispatch_to_evm;24use sp_core::{H160, U256};25use sp_std::vec::Vec;26use up_data_structs::{Property, SponsoringRateLimit};27use alloc::format;2829use crate::{Pallet, CollectionHandle, Config, CollectionProperties};3031/// Does not always represent a full collection, for RFT it is either32/// collection (Implementing ERC721), or specific collection token (Implementing ERC20)33pub trait CommonEvmHandler {34 const CODE: &'static [u8];3536 fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileResult>;37}3839#[solidity_interface(name = "Collection")]40impl<T: Config> CollectionHandle<T> {41 fn set_collection_property(&mut self, caller: caller, key: string, value: bytes) -> Result<()> {42 let caller = T::CrossAccountId::from_eth(caller);43 let key = <Vec<u8>>::from(key)44 .try_into()45 .map_err(|_| "key too large")?;46 let value = value.try_into().map_err(|_| "value too large")?;4748 <Pallet<T>>::set_collection_property(self, &caller, Property { key, value })49 .map_err(dispatch_to_evm::<T>)50 }5152 fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {53 let caller = T::CrossAccountId::from_eth(caller);54 let key = <Vec<u8>>::from(key)55 .try_into()56 .map_err(|_| "key too large")?;5758 <Pallet<T>>::delete_collection_property(self, &caller, key).map_err(dispatch_to_evm::<T>)59 }6061 /// Throws error if key not found62 fn collection_property(&self, key: string) -> Result<bytes> {63 let key = <Vec<u8>>::from(key)64 .try_into()65 .map_err(|_| "key too large")?;6667 let props = <CollectionProperties<T>>::get(self.id);68 let prop = props.get(&key).ok_or("key not found")?;6970 Ok(prop.to_vec())71 }7273 fn eth_set_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {74 check_is_owner(caller, self)?;7576 let sponsor = T::CrossAccountId::from_eth(sponsor);77 self.set_sponsor(sponsor.as_sub().clone());78 save(self);79 Ok(())80 }8182 fn eth_confirm_sponsorship(&mut self, caller: caller) -> Result<void> {83 let caller = T::CrossAccountId::from_eth(caller);84 if !self.confirm_sponsorship(caller.as_sub()) {85 return Err(Error::Revert("Caller is not set as sponsor".into()));86 }87 save(self);88 Ok(())89 }9091 #[solidity(rename_selector = "setLimit")]92 fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result<void> {93 check_is_owner(caller, self)?;94 let mut limits = self.limits.clone();9596 match limit.as_str() {97 "accountTokenOwnershipLimit" => {98 limits.account_token_ownership_limit = Some(value);99 }100 "sponsoredDataSize" => {101 limits.sponsored_data_size = Some(value);102 }103 "sponsoredDataRateLimit" => {104 limits.sponsored_data_rate_limit = Some(SponsoringRateLimit::Blocks(value));105 }106 "tokenLimit" => {107 limits.token_limit = Some(value);108 }109 "sponsorTransferTimeout" => {110 limits.sponsor_transfer_timeout = Some(value);111 }112 "sponsorApproveTimeout" => {113 limits.sponsor_approve_timeout = Some(value);114 }115 _ => {116 return Err(Error::Revert(format!(117 "Unknown integer limit \"{}\"",118 limit119 )))120 }121 }122 self.limits = <Pallet<T>>::clamp_limits(self.mode.clone(), &self.limits, limits)123 .map_err(dispatch_to_evm::<T>)?;124 save(self);125 Ok(())126 }127128 #[solidity(rename_selector = "setLimit")]129 fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result<void> {130 check_is_owner(caller, self)?;131 let mut limits = self.limits.clone();132133 match limit.as_str() {134 "ownerCanTransfer" => {135 limits.owner_can_transfer = Some(value);136 }137 "ownerCanDestroy" => {138 limits.owner_can_destroy = Some(value);139 }140 "transfersEnabled" => {141 limits.transfers_enabled = Some(value);142 }143 _ => {144 return Err(Error::Revert(format!(145 "Unknown boolean limit \"{}\"",146 limit147 )))148 }149 }150 self.limits = <Pallet<T>>::clamp_limits(self.mode.clone(), &self.limits, limits)151 .map_err(dispatch_to_evm::<T>)?;152 save(self);153 Ok(())154 }155156 fn contract_address(&self, _caller: caller) -> Result<address> {157 Ok(crate::eth::collection_id_to_address(self.id))158 }159}160161fn check_is_owner<T: Config>(caller: caller, collection: &CollectionHandle<T>) -> Result<()> {162 let caller = T::CrossAccountId::from_eth(caller);163 collection164 .check_is_owner(&caller)165 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;166 Ok(())167}168169fn save<T: Config>(collection: &CollectionHandle<T>) {170 <crate::CollectionById<T>>::insert(collection.id, collection.collection.clone());171}172173pub fn token_uri_key() -> up_data_structs::PropertyKey {174 b"tokenURI"175 .to_vec()176 .try_into()177 .expect("length < limit; qed")178}pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -17,14 +17,6 @@
use up_data_structs::CollectionId;
use sp_core::H160;
-lazy_static::lazy_static! {
- pub static ref KEY_TOKEN_URI: up_data_structs::PropertyKey = {
- let key: evm_coder::types::string = "tokenURI".into(); //TODO: make static
- let key: up_data_structs::PropertyKey = key.into_bytes().try_into().expect("Can't create \"tokenURI\" key");
- key
- };
-}
-
// 0x17c4e6453Cc49AAAaEACA894e6D9683e00000001 - collection 1
// TODO: Unhardcode prefix
const ETH_COLLECTION_PREFIX: [u8; 16] = [
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -22,14 +22,14 @@
use evm_coder::{ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight};
use frame_support::BoundedVec;
use up_data_structs::{
- TokenId, SchemaVersion, PropertyPermission, PropertyKeyPermission, Property, CollectionId,
- PropertyKey, CollectionPropertiesVec,
+ TokenId, PropertyPermission, PropertyKeyPermission, Property, CollectionId, PropertyKey,
+ CollectionPropertiesVec,
};
use pallet_evm_coder_substrate::dispatch_to_evm;
use sp_core::{H160, U256};
use sp_std::vec::Vec;
use pallet_common::{
- erc::{CommonEvmHandler, PrecompileResult, CollectionCall},
+ erc::{CommonEvmHandler, PrecompileResult, CollectionCall, token_uri_key},
CollectionHandle, CollectionPropertyPermissions,
};
use pallet_evm::account::CrossAccountId;
@@ -161,7 +161,7 @@
/// Returns token's const_metadata
#[solidity(rename_selector = "tokenURI")]
fn token_uri(&self, token_id: uint256) -> Result<string> {
- let key = pallet_common::eth::KEY_TOKEN_URI.clone();
+ let key = token_uri_key();
if !has_token_permission::<T>(self.id, &key) {
return Err("No tokenURI permission".into());
}
@@ -362,7 +362,7 @@
token_id: uint256,
token_uri: string,
) -> Result<bool> {
- let key = pallet_common::eth::KEY_TOKEN_URI.clone();
+ let key = token_uri_key();
let permission = get_token_permission::<T>(self.id, &key)?;
if !permission.collection_admin {
return Err("Operation is not allowed".into());
@@ -524,6 +524,7 @@
to: address,
tokens: Vec<(uint256, string)>,
) -> Result<bool> {
+ let key = token_uri_key();
let caller = T::CrossAccountId::from_eth(caller);
let to = T::CrossAccountId::from_eth(to);
let mut expected_index = <TokensMinted<T>>::get(self.id)
@@ -541,8 +542,19 @@
}
expected_index = expected_index.checked_add(1).ok_or("item id overflow")?;
+ let mut properties = CollectionPropertiesVec::default();
+ properties
+ .try_push(Property {
+ key: key.clone(),
+ value: token_uri
+ .into_bytes()
+ .try_into()
+ .map_err(|_| "token uri is too long")?,
+ })
+ .map_err(|e| Error::Revert(alloc::format!("Can't add property: {:?}", e)))?;
+
data.push(CreateItemData::<T> {
- properties: BoundedVec::default(),
+ properties,
owner: to.clone(),
});
}
pallets/unique/src/eth/mod.rsdiffbeforeafterboth--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -15,29 +15,20 @@
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
use core::marker::PhantomData;
-use evm_coder::{execution::*, generate_stubgen, solidity_interface, types::*, ToLog};
+use evm_coder::{execution::*, generate_stubgen, solidity_interface, weight, types::*};
use ethereum as _;
use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
-use pallet_evm::{OnMethodCall, PrecompileResult, account::CrossAccountId, Pallet as PalletEvm};
+use pallet_evm::{OnMethodCall, PrecompileResult, account::CrossAccountId};
use up_data_structs::{
CreateCollectionData, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
MAX_COLLECTION_NAME_LENGTH,
};
use frame_support::traits::Get;
-use sp_core::H160;
-use pallet_common::CollectionById;
+use pallet_common::{CollectionById, erc::token_uri_key};
+use crate::{SelfWeightOf, Config, weights::WeightInfo};
use sp_std::vec::Vec;
use alloc::format;
-
-pub trait Config:
- frame_system::Config
- + pallet_evm_coder_substrate::Config
- + pallet_evm::account::Config
- + pallet_nonfungible::Config
-{
- type ContractAddress: Get<H160>;
-}
struct EvmCollectionHelper<T: Config>(SubstrateRecorder<T>);
impl<T: Config> WithRecorder<T> for EvmCollectionHelper<T> {
@@ -51,8 +42,9 @@
}
#[solidity_interface(name = "CollectionHelper")]
-impl<T: Config> EvmCollectionHelper<T> {
- fn create_721_collection(
+impl<T: Config + pallet_nonfungible::Config> EvmCollectionHelper<T> {
+ #[weight(<SelfWeightOf<T>>::create_collection())]
+ fn create_nonfungible_collection(
&self,
caller: caller,
name: string,
@@ -77,7 +69,7 @@
.try_into()
.map_err(|_| error_feild_too_long(stringify!(token_prefix), MAX_TOKEN_PREFIX_LENGTH))?;
- let key = pallet_common::eth::KEY_TOKEN_URI.clone();
+ let key = token_uri_key();
let permission = up_data_structs::PropertyPermission {
mutable: true,
collection_admin: true,
@@ -102,13 +94,6 @@
.map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;
let address = pallet_common::eth::collection_id_to_address(collection_id);
- <PalletEvm<T>>::deposit_log(
- EthCollectionEvent::CollectionCreated {
- owner: *caller.as_eth(),
- collection_id: address,
- }
- .to_log(address),
- );
Ok(address)
}
@@ -122,18 +107,8 @@
}
}
-#[derive(ToLog)]
-pub enum EthCollectionEvent {
- CollectionCreated {
- #[indexed]
- owner: address,
- #[indexed]
- collection_id: address,
- },
-}
-
pub struct CollectionHelperOnMethodCall<T: Config>(PhantomData<*const T>);
-impl<T: Config> OnMethodCall<T> for CollectionHelperOnMethodCall<T> {
+impl<T: Config + pallet_nonfungible::Config> OnMethodCall<T> for CollectionHelperOnMethodCall<T> {
fn is_reserved(contract: &sp_core::H160) -> bool {
contract == &T::ContractAddress::get()
}
pallets/unique/src/lib.rsdiffbeforeafterboth--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -30,17 +30,18 @@
ensure,
weights::{Weight},
transactional,
- pallet_prelude::{DispatchResultWithPostInfo, ConstU32},
+ pallet_prelude::{DispatchResultWithPostInfo, ConstU32, Get},
BoundedVec,
};
+use sp_core::H160;
use scale_info::TypeInfo;
use frame_system::{self as system, ensure_signed};
use sp_runtime::{sp_std::prelude::Vec};
use up_data_structs::{
MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
- AccessMode, CreateItemData, CollectionLimits, CollectionPermissions, CollectionId,
- CollectionMode, TokenId, SponsorshipState, CreateCollectionData, CreateItemExData, budget,
- Property, PropertyKey, PropertyKeyPermission,
+ CreateItemData, CollectionLimits, CollectionPermissions, CollectionId, CollectionMode, TokenId,
+ SponsorshipState, CreateCollectionData, CreateItemExData, budget, Property, PropertyKey,
+ PropertyKeyPermission,
};
use pallet_evm::account::CrossAccountId;
use pallet_common::{
@@ -74,6 +75,7 @@
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
type CommonWeightInfo: CommonWeightInfo<Self::CrossAccountId>;
+ type ContractAddress: Get<H160>;
}
decl_event! {
runtime/opal/src/lib.rsdiffbeforeafterboth--- a/runtime/opal/src/lib.rs
+++ b/runtime/opal/src/lib.rs
@@ -917,6 +917,7 @@
type Event = Event;
type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
type CommonWeightInfo = CommonWeights<Self>;
+ type ContractAddress = EvmCollectionHelperAddress;
}
parameter_types! {
@@ -987,10 +988,6 @@
impl pallet_evm_contract_helpers::Config for Runtime {
type ContractAddress = HelpersContractAddress;
type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-}
-
-impl pallet_unique::eth::Config for Runtime {
- type ContractAddress = EvmCollectionHelperAddress;
}
construct_runtime!(
runtime/quartz/src/lib.rsdiffbeforeafterboth--- a/runtime/quartz/src/lib.rs
+++ b/runtime/quartz/src/lib.rs
@@ -900,6 +900,7 @@
type Event = Event;
type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
type CommonWeightInfo = CommonWeights<Self>;
+ type ContractAddress = EvmCollectionHelperAddress;
}
parameter_types! {
@@ -970,10 +971,6 @@
impl pallet_evm_contract_helpers::Config for Runtime {
type ContractAddress = HelpersContractAddress;
type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-}
-
-impl pallet_unique::eth::Config for Runtime {
- type ContractAddress = EvmCollectionHelperAddress;
}
construct_runtime!(
runtime/tests/src/lib.rsdiffbeforeafterboth--- a/runtime/tests/src/lib.rs
+++ b/runtime/tests/src/lib.rs
@@ -16,7 +16,7 @@
#![allow(clippy::from_over_into)]
-use sp_core::{H256, U256};
+use sp_core::{H160, H256, U256};
use frame_support::{
parameter_types,
traits::{Everything, ConstU32, ConstU64},
@@ -245,10 +245,18 @@
type WeightInfo = ();
}
+parameter_types! {
+ // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f
+ pub const EvmCollectionHelperAddress: H160 = H160([
+ 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f,
+ ]);
+}
+
impl pallet_unique::Config for Test {
type Event = ();
type WeightInfo = ();
type CommonWeightInfo = CommonWeights<Self>;
+ type ContractAddress = EvmCollectionHelperAddress;
}
// Build genesis storage according to the mock runtime.
runtime/unique/src/lib.rsdiffbeforeafterboth--- a/runtime/unique/src/lib.rs
+++ b/runtime/unique/src/lib.rs
@@ -905,6 +905,7 @@
type Event = Event;
type WeightInfo = pallet_unique::weights::SubstrateWeight<Self>;
type CommonWeightInfo = CommonWeights<Self>;
+ type ContractAddress = EvmCollectionHelperAddress;
}
parameter_types! {
@@ -975,10 +976,6 @@
impl pallet_evm_contract_helpers::Config for Runtime {
type ContractAddress = HelpersContractAddress;
type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
-}
-
-impl pallet_unique::eth::Config for Runtime {
- type ContractAddress = EvmCollectionHelperAddress;
}
construct_runtime!(