--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -15,8 +15,13 @@
// along with Unique Network. If not, see .
use core::marker::PhantomData;
-use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*};
-use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
+use evm_coder::{
+ abi::AbiWriter,
+ execution::{Result, Error},
+ generate_stubgen, solidity_interface,
+ types::*,
+};
+use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm};
use pallet_evm::{
ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,
account::CrossAccountId,
@@ -43,7 +48,10 @@
#[solidity_interface(name = "ContractHelpers")]
impl ContractHelpers {
fn contract_owner(&self, contract_address: address) -> Result {
- Ok(>::get(contract_address))
+ Ok(>::contract_owner(contract_address)
+ .map_err(dispatch_to_evm::)?
+ .as_eth()
+ .clone())
}
fn sponsoring_enabled(&self, contract_address: address) -> Result {
@@ -97,7 +105,7 @@
fn allowed(&self, contract_address: address, user: address) -> Result {
self.0.consume_sload()?;
- Ok(>::allowed(contract_address, user))
+ Ok(>::allowed(contract_address, T::CrossAccountId::from_eth(user)))
}
fn allowlist_enabled(&self, contract_address: address) -> Result {
@@ -141,7 +149,7 @@
fn call(handle: &mut impl PrecompileHandle) -> Option {
// TODO: Extract to another OnMethodCall handler
if >::get(handle.code_address())
- && !>::allowed(handle.code_address(), handle.context().caller)
+ && !>::allowed(handle.code_address(), T::CrossAccountId::from_eth(handle.context().caller))
{
return Some(Err(PrecompileFailure::Revert {
exit_status: ExitRevert::Reverted,
@@ -170,7 +178,7 @@
pub struct HelpersOnCreate(PhantomData<*const T>);
impl OnCreate for HelpersOnCreate {
fn on_create(owner: H160, contract: H160) {
- >::insert(contract, owner);
+ >::insert(contract, T::CrossAccountId::from_eth(owner));
}
}
@@ -184,7 +192,7 @@
return None;
}
- if mode == SponsoringModeT::Allowlisted && !>::allowed(call.0, *who.as_eth()) {
+ if mode == SponsoringModeT::Allowlisted && !>::allowed(call.0, who.clone()) {
return None;
}
let block_number = >::block_number() as T::BlockNumber;
--- a/pallets/evm-contract-helpers/src/lib.rs
+++ b/pallets/evm-contract-helpers/src/lib.rs
@@ -15,6 +15,7 @@
// along with Unique Network. If not, see .
#![cfg_attr(not(feature = "std"), no_std)]
+#![feature(is_some_with)]
use codec::{Decode, Encode, MaxEncodedLen};
pub use pallet::*;
@@ -25,9 +26,10 @@
#[frame_support::pallet]
pub mod pallet {
pub use super::*;
- use evm_coder::execution::Result;
use frame_support::pallet_prelude::*;
use sp_core::H160;
+ use pallet_evm::account::CrossAccountId;
+ use frame_system::pallet_prelude::BlockNumberFor;
#[pallet::config]
pub trait Config:
@@ -39,17 +41,31 @@
#[pallet::error]
pub enum Error {
- /// This method is only executable by owner
+ /// This method is only executable by owner.
NoPermission,
+
+ /// Contract has no owner.
+ NoContractOwner,
}
+ const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
+
#[pallet::pallet]
+ #[pallet::storage_version(STORAGE_VERSION)]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet(_);
+ /// Store owner for contract.
+ ///
+ /// * **Key** - contract address.
+ /// * **Value** - owner for contract.
#[pallet::storage]
- pub(super) type Owner =
- StorageMap;
+ pub(super) type Owner = StorageMap<
+ Hasher = Twox128,
+ Key = H160,
+ Value = T::CrossAccountId,
+ QueryKind = OptionQuery,
+ >;
#[pallet::storage]
#[deprecated]
@@ -57,10 +73,12 @@
StorageMap;
#[pallet::storage]
+ #[deprecated]
pub(super) type SponsoringMode =
StorageMap;
#[pallet::storage]
+ #[deprecated]
pub(super) type SponsoringRateLimit = StorageMap<
Hasher = Twox128,
Key = H160,
@@ -70,6 +88,7 @@
>;
#[pallet::storage]
+ #[deprecated]
pub(super) type SponsorBasket = StorageDoubleMap<
Hasher1 = Twox128,
Key1 = H160,
@@ -80,10 +99,12 @@
>;
#[pallet::storage]
+ #[deprecated]
pub(super) type AllowlistEnabled =
StorageMap;
#[pallet::storage]
+ #[deprecated]
pub(super) type Allowlist = StorageDoubleMap<
Hasher1 = Twox128,
Key1 = H160,
@@ -93,6 +114,18 @@
QueryKind = ValueQuery,
>;
+ #[pallet::hooks]
+ impl Hooks> for Pallet {
+ fn on_runtime_upgrade() -> Weight {
+ let storage_version = StorageVersion::get::>();
+ if storage_version < StorageVersion::new(1) {
+ >::translate_values::(|address| Some(T::CrossAccountId::from_eth(address)));
+ }
+
+ 0
+ }
+ }
+
impl Pallet {
pub fn sponsoring_mode(contract: H160) -> SponsoringModeT {
>::get(contract)
@@ -125,8 +158,9 @@
>::insert(contract, rate_limit);
}
- pub fn allowed(contract: H160, user: H160) -> bool {
- >::get(&contract, &user) || >::get(&contract) == user
+ pub fn allowed(contract: H160, user: T::CrossAccountId) -> bool {
+ >::get(&contract, user.as_eth())
+ || Pallet::::contract_owner(contract).is_ok_and(|owner| *owner == user)
}
pub fn toggle_allowlist(contract: H160, enabled: bool) {
@@ -137,11 +171,17 @@
>::insert(contract, user, allowed);
}
- pub fn ensure_owner(contract: H160, user: H160) -> Result<()> {
- ensure!(>::get(&contract) == user, "no permission");
+ pub fn ensure_owner(contract: H160, user: H160) -> evm_coder::execution::Result<()> {
+ ensure!(Pallet::::contract_owner(contract).is_ok_and(|owner| *owner.as_eth() == user), "no permission");
Ok(())
}
}
+
+ impl Pallet {
+ pub fn contract_owner(contract: H160) -> Result {
+ Ok(>::get(contract).ok_or::>(Error::NoContractOwner)?)
+ }
+ }
}
#[derive(Encode, Decode, PartialEq, TypeInfo, MaxEncodedLen)]