1#![cfg_attr(not(feature = "std"), no_std)]23use codec::{Decode, Encode, MaxEncodedLen};4pub use pallet::*;5pub use eth::*;6use scale_info::TypeInfo;7pub mod eth;89#[frame_support::pallet]10pub mod pallet {11 pub use super::*;12 use evm_coder::execution::Result;13 use frame_support::pallet_prelude::*;14 use sp_core::H160;1516 #[pallet::config]17 pub trait Config: frame_system::Config + pallet_evm_coder_substrate::Config {18 type ContractAddress: Get<H160>;19 type DefaultSponsoringRateLimit: Get<Self::BlockNumber>;20 }2122 #[pallet::error]23 pub enum Error<T> {24 25 NoPermission,26 }2728 #[pallet::pallet]29 #[pallet::generate_store(pub(super) trait Store)]30 pub struct Pallet<T>(_);3132 #[pallet::storage]33 pub(super) type Owner<T: Config> =34 StorageMap<Hasher = Twox128, Key = H160, Value = H160, QueryKind = ValueQuery>;3536 #[pallet::storage]37 #[deprecated]38 pub(super) type SelfSponsoring<T: Config> =39 StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;4041 #[pallet::storage]42 pub(super) type SponsoringMode<T: Config> =43 StorageMap<Hasher = Twox128, Key = H160, Value = SponsoringModeT, QueryKind = OptionQuery>;4445 #[pallet::storage]46 pub(super) type SponsoringRateLimit<T: Config> = StorageMap<47 Hasher = Twox128,48 Key = H160,49 Value = T::BlockNumber,50 QueryKind = ValueQuery,51 OnEmpty = T::DefaultSponsoringRateLimit,52 >;5354 #[pallet::storage]55 pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<56 Hasher1 = Twox128,57 Key1 = H160,58 Hasher2 = Twox128,59 Key2 = H160,60 Value = T::BlockNumber,61 QueryKind = OptionQuery,62 >;6364 #[pallet::storage]65 pub(super) type AllowlistEnabled<T: Config> =66 StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;6768 #[pallet::storage]69 pub(super) type Allowlist<T: Config> = StorageDoubleMap<70 Hasher1 = Twox128,71 Key1 = H160,72 Hasher2 = Twox128,73 Key2 = H160,74 Value = bool,75 QueryKind = ValueQuery,76 >;7778 impl<T: Config> Pallet<T> {79 pub fn sponsoring_mode(contract: H160) -> SponsoringModeT {80 <SponsoringMode<T>>::get(contract)81 .or_else(|| {82 <SelfSponsoring<T>>::get(contract).then(|| SponsoringModeT::Allowlisted)83 })84 .unwrap_or_default()85 }86 pub fn set_sponsoring_mode(contract: H160, mode: SponsoringModeT) {87 if mode == SponsoringModeT::Disabled {88 <SponsoringMode<T>>::remove(contract);89 } else {90 <SponsoringMode<T>>::insert(contract, mode);91 }92 <SelfSponsoring<T>>::remove(contract)93 }9495 pub fn toggle_sponsoring(contract: H160, enabled: bool) {96 Self::set_sponsoring_mode(97 contract,98 if enabled {99 SponsoringModeT::Allowlisted100 } else {101 SponsoringModeT::Disabled102 },103 )104 }105106 pub fn set_sponsoring_rate_limit(contract: H160, rate_limit: T::BlockNumber) {107 <SponsoringRateLimit<T>>::insert(contract, rate_limit);108 }109110 pub fn allowed(contract: H160, user: H160) -> bool {111 <Allowlist<T>>::get(&contract, &user) || <Owner<T>>::get(&contract) == user112 }113114 pub fn toggle_allowlist(contract: H160, enabled: bool) {115 <AllowlistEnabled<T>>::insert(contract, enabled)116 }117118 pub fn toggle_allowed(contract: H160, user: H160, allowed: bool) {119 <Allowlist<T>>::insert(contract, user, allowed);120 }121122 pub fn ensure_owner(contract: H160, user: H160) -> Result<()> {123 ensure!(<Owner<T>>::get(&contract) == user, "no permission");124 Ok(())125 }126 }127}128129#[derive(Encode, Decode, PartialEq, TypeInfo, MaxEncodedLen)]130pub enum SponsoringModeT {131 Disabled,132 Allowlisted,133 Generous,134}135136impl SponsoringModeT {137 fn from_eth(v: u8) -> Option<Self> {138 Some(match v {139 0 => Self::Disabled,140 1 => Self::Allowlisted,141 2 => Self::Generous,142 _ => return None,143 })144 }145 fn to_eth(self) -> u8 {146 match self {147 SponsoringModeT::Disabled => 0,148 SponsoringModeT::Allowlisted => 1,149 SponsoringModeT::Generous => 2,150 }151 }152}153154impl Default for SponsoringModeT {155 fn default() -> Self {156 Self::Disabled157 }158}