difftreelog
fix PR comments
in: master
8 files changed
pallets/balances-adapter/src/common.rsdiffbeforeafterboth--- a/pallets/balances-adapter/src/common.rs
+++ b/pallets/balances-adapter/src/common.rs
@@ -7,6 +7,8 @@
use up_data_structs::TokenId;
pub struct CommonWeights<T: Config>(PhantomData<T>);
+
+// All implementations with `Weight::default` used in methods that return error `UnsupportedOperation`.
impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {
fn create_multiple_items(_amount: &[up_data_structs::CreateItemData]) -> Weight {
Weight::default()
pallets/balances-adapter/src/erc.rsdiffbeforeafterboth--- a/pallets/balances-adapter/src/erc.rs
+++ b/pallets/balances-adapter/src/erc.rs
@@ -1,9 +1,8 @@
use crate::{Config, NativeFungibleHandle, Pallet, SelfWeightOf};
-use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
-use frame_support::traits::{Currency, ExistenceRequirement};
+use evm_coder::{abi::AbiType, generate_stubgen, solidity_interface, types::*};
+use frame_support::traits::{Currency};
use pallet_balances::WeightInfo;
use pallet_common::{
- consume_store_reads,
erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult},
eth::CrossAddress,
};
@@ -14,38 +13,24 @@
};
use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
use sp_core::{U256, Get};
-use sp_std::vec::Vec;
frontier_contract! {
macro_rules! NativeFungibleHandle_result {...}
impl<T: Config> Contract for NativeFungibleHandle<T> {...}
}
-#[derive(ToLog)]
-pub enum ERC20Events {
- Transfer {
- #[indexed]
- from: Address,
- #[indexed]
- to: Address,
- value: U256,
- },
-}
-
-#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]
+#[solidity_interface(name = ERC20, enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]
impl<T: Config> NativeFungibleHandle<T> {
fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {
Ok(U256::zero())
}
- // #[weight(<SelfWeightOf<T>>::approve())]
fn approve(&mut self, _caller: Caller, _spender: Address, _amount: U256) -> Result<bool> {
- // self.consume_store_reads(1)?;
Err("Approve not supported".into())
}
fn balance_of(&self, owner: Address) -> Result<U256> {
- consume_store_reads(self, 1)?;
+ self.consume_store_reads(1)?;
let owner = T::CrossAccountId::from_eth(owner);
let balance = <T as Config>::Currency::free_balance(owner.as_sub());
Ok(balance.into())
@@ -64,7 +49,7 @@
}
fn total_supply(&self) -> Result<U256> {
- consume_store_reads(self, 1)?;
+ self.consume_store_reads(1)?;
let total = <T as Config>::Currency::total_issuance();
Ok(total.into())
}
@@ -111,7 +96,7 @@
T::AccountId: From<[u8; 32]>,
{
fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {
- consume_store_reads(self, 1)?;
+ self.consume_store_reads(1)?;
let owner = owner.into_sub_cross_account::<T>()?;
let balance = <T as Config>::Currency::free_balance(owner.as_sub());
Ok(balance.into())
@@ -122,18 +107,13 @@
let caller = T::CrossAccountId::from_eth(caller);
let to = to.into_sub_cross_account::<T>()?;
let amount = amount.try_into().map_err(|_| "amount overflow")?;
- // let budget = self
- // .recorder
- // .weight_calls_budget(<StructureWeight<T>>::find_parent());
+ let budget = self
+ .recorder()
+ .weight_calls_budget(<StructureWeight<T>>::find_parent());
+
+ <Pallet<T>>::transfer(self, &caller, &to, amount, &budget)
+ .map_err(|e| dispatch_to_evm::<T>(e.error))?;
- // <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;
- <T as Config>::Currency::transfer(
- caller.as_sub(),
- to.as_sub(),
- amount,
- ExistenceRequirement::KeepAlive,
- )
- .map_err(dispatch_to_evm::<T>)?;
Ok(true)
}
@@ -154,19 +134,13 @@
return Err("no permission".into());
}
- // let budget = self
- // .recorder
- // .weight_calls_budget(<StructureWeight<T>>::find_parent());
+ let budget = self
+ .recorder()
+ .weight_calls_budget(<StructureWeight<T>>::find_parent());
+
+ <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
+ .map_err(|e| dispatch_to_evm::<T>(e.error))?;
- // <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
- // .map_err(dispatch_to_evm::<T>)?;
- <T as Config>::Currency::transfer(
- caller.as_sub(),
- to.as_sub(),
- amount,
- ExistenceRequirement::KeepAlive,
- )
- .map_err(dispatch_to_evm::<T>)?;
Ok(true)
}
}
pallets/balances-adapter/src/lib.rsdiffbeforeafterboth--- a/pallets/balances-adapter/src/lib.rs
+++ b/pallets/balances-adapter/src/lib.rs
@@ -1,4 +1,3 @@
-// #![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
@@ -12,9 +11,6 @@
pub mod erc;
pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
-
-const NATIVE_FUNGIBLE_COLLECTION_ID: up_data_structs::CollectionId =
- up_data_structs::CollectionId(0);
/// Handle for native fungible collection
pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);
@@ -57,7 +53,10 @@
traits::{Currency, ExistenceRequirement, Get},
};
use pallet_balances::WeightInfo;
- use pallet_common::{erc::CrossAccountId, Error as CommonError, Pallet as PalletCommon};
+ use pallet_common::{
+ erc::CrossAccountId, Error as CommonError, Pallet as PalletCommon,
+ NATIVE_FUNGIBLE_COLLECTION_ID,
+ };
use pallet_structure::Pallet as PalletStructure;
use sp_core::U256;
use sp_runtime::DispatchError;
@@ -95,10 +94,9 @@
/// Checks if a non-owner has (enough) allowance from the owner to perform operations on the tokens.
/// Returns the expected remaining allowance - it should be set manually if the transaction proceeds.
///
- /// - `collection`: Collection that contains the token.
/// - `spender`: CrossAccountId who has the allowance rights.
/// - `from`: The owner of the tokens who sets the allowance.
- /// - `amount`: Amount of tokens by which the allowance sholud be reduced.
+ /// - `nesting_budget`: Limit for searching parents in-depth to check ownership.
fn check_allowed(
spender: &T::CrossAccountId,
from: &T::CrossAccountId,
@@ -127,10 +125,11 @@
/// Transfers the specified amount of tokens. Will check that
/// the transfer is allowed for the token.
///
+ /// - `collection`: Collection that contains the token.
/// - `from`: Owner of tokens to transfer.
/// - `to`: Recepient of transfered tokens.
/// - `amount`: Amount of tokens to transfer.
- /// - `collection`: Collection that contains the token
+ /// - `nesting_budget`: Limit for searching parents in-depth to check ownership.
pub fn transfer(
_collection: &NativeFungibleHandle<T>,
from: &T::CrossAccountId,
@@ -147,7 +146,7 @@
amount
.try_into()
.map_err(|_| sp_runtime::ArithmeticError::Overflow)?,
- ExistenceRequirement::KeepAlive,
+ ExistenceRequirement::AllowDeath,
)?;
<PalletStructure<T>>::nest_if_sent_to_token(
@@ -175,6 +174,17 @@
})
}
+ /// Transfer NFT token from one account to another.
+ ///
+ /// Same as the [`Self::transfer`] but spender doesn't needs to be the owner of the token.
+ /// The owner should set allowance for the spender to transfer token.
+ ///
+ /// - `collection`: Collection that contains the token.
+ /// - `spender`: Account that spend the money.
+ /// - `from`: Owner of tokens to transfer.
+ /// - `to`: Recepient of transfered tokens.
+ /// - `amount`: Amount of tokens to transfer.
+ /// - `nesting_budget`: Limit for searching parents in-depth to check ownership.
pub fn transfer_from(
collection: &NativeFungibleHandle<T>,
spender: &T::CrossAccountId,
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -77,14 +77,6 @@
fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult>;
}
-impl CommonEvmHandler for () {
- const CODE: &'static [u8] = &[];
-
- fn call(self, _handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
- None
- }
-}
-
/// @title A contract that allows you to work with collections.
#[solidity_interface(name = Collection, enum(derive(PreDispatch)), enum_attr(weight))]
impl<T: Config> CollectionHandle<T>
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -68,7 +68,6 @@
dispatch::Pays,
transactional, fail,
};
-use pallet_evm::GasWeightMapping;
use up_data_structs::{
AccessMode, COLLECTION_NUMBER_LIMIT, Collection, RpcCollection, CollectionFlags,
RpcCollectionFlags, CollectionId, CreateItemData, MAX_TOKEN_PREFIX_LENGTH,
@@ -101,7 +100,7 @@
/// Collection handle contains information about collection data and id.
/// Also provides functionality to count consumed gas.
///
-/// CollectionHandle is used as a generic wrapper for collections of all types.
+/// CollectionHandle is used as a generic wrapper for collections of all types (except native fungible).
/// It allows to perform common operations and queries on any collection type,
/// both completely general for all, as well as their respective implementations of [`CommonCollectionOperations`].
#[must_use = "Should call submit_logs or save, otherwise some data will be lost for evm side"]
@@ -153,7 +152,7 @@
&self,
reads: u64,
) -> pallet_evm_coder_substrate::execution::Result<()> {
- consume_store_reads(self.recorder(), reads)
+ self.recorder().consume_store_reads(reads)
}
/// Consume gas for writing.
@@ -161,7 +160,7 @@
&self,
writes: u64,
) -> pallet_evm_coder_substrate::execution::Result<()> {
- consume_store_writes(self.recorder(), writes)
+ self.recorder().consume_store_writes(writes)
}
/// Consume gas for reading and writing.
@@ -170,7 +169,8 @@
reads: u64,
writes: u64,
) -> pallet_evm_coder_substrate::execution::Result<()> {
- consume_store_reads_and_writes(self.recorder(), reads, writes)
+ self.recorder()
+ .consume_store_reads_and_writes(reads, writes)
}
/// Save collection to storage.
@@ -441,7 +441,7 @@
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
/// Collection id for native fungible collction.
- pub const NATIVE_FINGIBLE_COLLECTION_ID: CollectionId = CollectionId(0);
+ pub const NATIVE_FUNGIBLE_COLLECTION_ID: CollectionId = CollectionId(0);
#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
@@ -2322,48 +2322,4 @@
PropertiesError::EmptyPropertyKey => Self::EmptyPropertyKey,
}
}
-}
-
-/// Consume gas for reading.
-pub fn consume_store_reads<T: Config>(
- recorder: &SubstrateRecorder<T>,
- reads: u64,
-) -> pallet_evm_coder_substrate::execution::Result<()> {
- recorder.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_parts(
- <T as frame_system::Config>::DbWeight::get()
- .read
- .saturating_mul(reads),
- // TODO: measure proof
- 0,
- )))
-}
-
-/// Consume gas for writing.
-pub fn consume_store_writes<T: Config>(
- recorder: &SubstrateRecorder<T>,
- writes: u64,
-) -> pallet_evm_coder_substrate::execution::Result<()> {
- recorder.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_parts(
- <T as frame_system::Config>::DbWeight::get()
- .write
- .saturating_mul(writes),
- // TODO: measure proof
- 0,
- )))
-}
-
-/// Consume gas for reading and writing.
-pub fn consume_store_reads_and_writes<T: Config>(
- recorder: &SubstrateRecorder<T>,
- reads: u64,
- writes: u64,
-) -> pallet_evm_coder_substrate::execution::Result<()> {
- let weight = <T as frame_system::Config>::DbWeight::get();
- let reads = weight.read.saturating_mul(reads);
- let writes = weight.read.saturating_mul(writes);
- recorder.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_parts(
- reads.saturating_add(writes),
- // TODO: measure proof
- 0,
- )))
}
pallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth--- a/pallets/evm-coder-substrate/src/lib.rs
+++ b/pallets/evm-coder-substrate/src/lib.rs
@@ -37,7 +37,7 @@
ExitError, ExitRevert, ExitSucceed, GasWeightMapping, PrecompileFailure, PrecompileOutput,
PrecompileResult, PrecompileHandle,
};
-use sp_core::H160;
+use sp_core::{Get, H160};
// #[cfg(feature = "runtime-benchmarks")]
// pub mod benchmarking;
pub mod execution;
@@ -204,6 +204,40 @@
Err(Error::Error(e)) => Err(e.into()),
})
}
+
+ /// Consume gas for reading.
+ pub fn consume_store_reads(&self, reads: u64) -> execution::Result<()> {
+ self.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_parts(
+ <T as frame_system::Config>::DbWeight::get()
+ .read
+ .saturating_mul(reads),
+ // TODO: measure proof
+ 0,
+ )))
+ }
+
+ /// Consume gas for writing.
+ pub fn consume_store_writes(&self, writes: u64) -> execution::Result<()> {
+ self.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_parts(
+ <T as frame_system::Config>::DbWeight::get()
+ .write
+ .saturating_mul(writes),
+ // TODO: measure proof
+ 0,
+ )))
+ }
+
+ /// Consume gas for reading and writing.
+ pub fn consume_store_reads_and_writes(&self, reads: u64, writes: u64) -> execution::Result<()> {
+ let weight = <T as frame_system::Config>::DbWeight::get();
+ let reads = weight.read.saturating_mul(reads);
+ let writes = weight.read.saturating_mul(writes);
+ self.consume_gas(T::GasWeightMapping::weight_to_gas(Weight::from_parts(
+ reads.saturating_add(writes),
+ // TODO: measure proof
+ 0,
+ )))
+ }
}
pub fn dispatch_to_evm<T: Config>(err: DispatchError) -> execution::Error {
pallets/unique/src/lib.rsdiffbeforeafterboth--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -440,7 +440,7 @@
collection_id: CollectionId,
address: T::CrossAccountId,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
@@ -471,7 +471,7 @@
collection_id: CollectionId,
address: T::CrossAccountId,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
@@ -501,7 +501,7 @@
collection_id: CollectionId,
new_owner: T::AccountId,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -533,7 +533,7 @@
collection_id: CollectionId,
new_admin_id: T::CrossAccountId,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -562,7 +562,7 @@
collection_id: CollectionId,
account_id: T::CrossAccountId,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -590,7 +590,7 @@
collection_id: CollectionId,
new_sponsor: T::AccountId,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -617,7 +617,7 @@
origin: OriginFor<T>,
collection_id: CollectionId,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
let sender = ensure_signed(origin)?;
@@ -640,7 +640,7 @@
origin: OriginFor<T>,
collection_id: CollectionId,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -920,7 +920,7 @@
collection_id: CollectionId,
value: bool,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -1175,7 +1175,7 @@
collection_id: CollectionId,
new_limit: CollectionLimits,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -1202,7 +1202,7 @@
collection_id: CollectionId,
new_permission: CollectionPermissions,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
@@ -1273,7 +1273,7 @@
origin: OriginFor<T>,
collection_id: CollectionId,
) -> DispatchResult {
- if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {
+ if collection_id == pallet_common::NATIVE_FUNGIBLE_COLLECTION_ID {
fail!(<pallet_common::Error<T>>::UnsupportedOperation);
}
ensure_root(origin)?;
runtime/common/dispatch.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 frame_support::{dispatch::DispatchResult, ensure, fail};18use pallet_evm::{PrecompileHandle, PrecompileResult};19use sp_core::H160;20use sp_runtime::DispatchError;21use sp_std::{borrow::ToOwned, vec::Vec};22use pallet_common::{23 CollectionById, CollectionHandle, CommonCollectionOperations, erc::CommonEvmHandler,24 eth::map_eth_to_id,25};26pub use pallet_common::dispatch::CollectionDispatch;27use pallet_fungible::{Pallet as PalletFungible, FungibleHandle};28use pallet_balances_adapter::{NativeFungibleHandle};29use pallet_nonfungible::{Pallet as PalletNonfungible, NonfungibleHandle};30use pallet_refungible::{31 Pallet as PalletRefungible, RefungibleHandle, erc_token::RefungibleTokenHandle,32};33use up_data_structs::{34 CollectionMode, CreateCollectionData, MAX_DECIMAL_POINTS, mapping::TokenAddressMapping,35 CollectionId, CollectionFlags,36};3738#[cfg(not(feature = "refungible"))]39use pallet_common::unsupported;4041pub enum CollectionDispatchT<T>42where43 T: pallet_fungible::Config44 + pallet_nonfungible::Config45 + pallet_refungible::Config46 + pallet_balances_adapter::Config,47{48 Fungible(FungibleHandle<T>),49 Nonfungible(NonfungibleHandle<T>),50 Refungible(RefungibleHandle<T>),51 NativeFungible(NativeFungibleHandle<T>),52}5354impl<T> CollectionDispatch<T> for CollectionDispatchT<T>55where56 T: pallet_common::Config57 + pallet_unique::Config58 + pallet_fungible::Config59 + pallet_nonfungible::Config60 + pallet_refungible::Config61 + pallet_balances_adapter::Config,62{63 fn check_is_internal(&self) -> DispatchResult {64 match self {65 Self::Fungible(h) => h.check_is_internal(),66 Self::Nonfungible(h) => h.check_is_internal(),67 Self::Refungible(h) => h.check_is_internal(),68 Self::NativeFungible(h) => h.check_is_internal(),69 }70 }7172 fn create(73 sender: T::CrossAccountId,74 payer: T::CrossAccountId,75 data: CreateCollectionData<T::AccountId>,76 flags: CollectionFlags,77 ) -> Result<CollectionId, DispatchError> {78 let id = match data.mode {79 CollectionMode::NFT => {80 <PalletNonfungible<T>>::init_collection(sender, payer, data, flags)?81 }82 CollectionMode::Fungible(decimal_points) => {83 // check params84 ensure!(85 decimal_points <= MAX_DECIMAL_POINTS,86 pallet_unique::Error::<T>::CollectionDecimalPointLimitExceeded87 );88 <PalletFungible<T>>::init_collection(sender, payer, data, flags)?89 }9091 #[cfg(feature = "refungible")]92 CollectionMode::ReFungible => {93 <PalletRefungible<T>>::init_collection(sender, payer, data, flags)?94 }9596 #[cfg(not(feature = "refungible"))]97 CollectionMode::ReFungible => return unsupported!(T),98 };99 Ok(id)100 }101102 fn destroy(sender: T::CrossAccountId, collection_id: CollectionId) -> DispatchResult {103 if collection_id == pallet_common::NATIVE_FINGIBLE_COLLECTION_ID {104 fail!(<pallet_common::Error<T>>::UnsupportedOperation);105 }106107 let collection = <CollectionHandle<T>>::try_get(collection_id)?;108 collection.check_is_internal()?;109110 match collection.mode {111 CollectionMode::ReFungible => {112 PalletRefungible::destroy_collection(RefungibleHandle::cast(collection), &sender)?113 }114 CollectionMode::Fungible(_) => {115 PalletFungible::destroy_collection(FungibleHandle::cast(collection), &sender)?116 }117 CollectionMode::NFT => {118 PalletNonfungible::destroy_collection(NonfungibleHandle::cast(collection), &sender)?119 }120 }121 Ok(())122 }123124 fn dispatch(collection_id: CollectionId) -> Result<Self, DispatchError> {125 if collection_id == CollectionId(0) {126 return Ok(Self::NativeFungible(NativeFungibleHandle::new()));127 }128129 let handle = <CollectionHandle<T>>::try_get(collection_id)?;130 Ok(match handle.mode {131 CollectionMode::Fungible(_) => Self::Fungible(FungibleHandle::cast(handle)),132 CollectionMode::NFT => Self::Nonfungible(NonfungibleHandle::cast(handle)),133 CollectionMode::ReFungible => Self::Refungible(RefungibleHandle::cast(handle)),134 })135 }136137 fn as_dyn(&self) -> &dyn CommonCollectionOperations<T> {138 match self {139 Self::Fungible(h) => h,140 Self::Nonfungible(h) => h,141 Self::Refungible(h) => h,142 Self::NativeFungible(h) => h,143 }144 }145}146147impl<T> pallet_evm::OnMethodCall<T> for CollectionDispatchT<T>148where149 T: pallet_common::Config150 + pallet_unique::Config151 + pallet_fungible::Config152 + pallet_nonfungible::Config153 + pallet_refungible::Config154 + pallet_balances_adapter::Config,155 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,156{157 fn is_reserved(target: &H160) -> bool {158 map_eth_to_id(target).is_some()159 }160 fn is_used(target: &H160) -> bool {161 map_eth_to_id(target)162 .map(<CollectionById<T>>::contains_key)163 .unwrap_or(false)164 }165 fn get_code(target: &H160) -> Option<Vec<u8>> {166 if let Some(collection_id) = map_eth_to_id(target) {167 let collection = <CollectionById<T>>::get(collection_id)?;168 Some(169 match collection.mode {170 CollectionMode::NFT => <NonfungibleHandle<T>>::CODE,171 CollectionMode::Fungible(_) => <FungibleHandle<T>>::CODE,172 CollectionMode::ReFungible => <RefungibleHandle<T>>::CODE,173 }174 .to_owned(),175 )176 } else if let Some((collection_id, _token_id)) =177 <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(target)178 {179 let collection = <CollectionById<T>>::get(collection_id)?;180 if collection.mode != CollectionMode::ReFungible {181 return None;182 }183 // TODO: check token existence184 Some(<RefungibleTokenHandle<T>>::CODE.to_owned())185 } else {186 None187 }188 }189 fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {190 if let Some(collection_id) = map_eth_to_id(&handle.code_address()) {191 if collection_id == CollectionId(0) {192 <NativeFungibleHandle<T>>::new().call(handle)193 } else {194 let collection = <CollectionHandle<T>>::new_with_gas_limit(195 collection_id,196 handle.remaining_gas(),197 )?;198199 match collection.mode {200 CollectionMode::Fungible(_) => FungibleHandle::cast(collection).call(handle),201 CollectionMode::NFT => NonfungibleHandle::cast(collection).call(handle),202 CollectionMode::ReFungible => RefungibleHandle::cast(collection).call(handle),203 }204 }205 } else if let Some((collection_id, token_id)) =206 <T as pallet_common::Config>::EvmTokenAddressMapping::address_to_token(207 &handle.code_address(),208 ) {209 let collection =210 <CollectionHandle<T>>::new_with_gas_limit(collection_id, handle.remaining_gas())?;211 if collection.mode != CollectionMode::ReFungible {212 return None;213 }214215 let h = RefungibleHandle::cast(collection);216 // TODO: check token existence217 RefungibleTokenHandle(h, token_id).call(handle)218 } else {219 None220 }221 }222}