git.delta.rocks / unique-network / refs/commits / 12dc7ebeba3c

difftreelog

source

pallets/balances-adapter/src/erc.rs5.9 KiBsourcehistory
1use crate::{Config, NativeFungibleHandle, SelfWeightOf};2use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};3use frame_support::traits::{Currency, ExistenceRequirement};4use pallet_balances::WeightInfo;5use pallet_common::{6	erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult},7	eth::CrossAddress,8};9use pallet_evm_coder_substrate::{10	call, dispatch_to_evm,11	execution::{PreDispatch, Result},12	frontier_contract,13};14use sp_core::{U256, Get};15use sp_std::vec::Vec;1617frontier_contract! {18	macro_rules! NativeFungibleHandle_result {...}19	impl<T: Config> Contract for NativeFungibleHandle<T> {...}20}2122#[derive(ToLog)]23pub enum ERC20Events {24	Transfer {25		#[indexed]26		from: Address,27		#[indexed]28		to: Address,29		value: U256,30	},31}3233#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]34impl<T: Config> NativeFungibleHandle<T> {35	fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {36		Ok(U256::zero())37	}3839	// #[weight(<SelfWeightOf<T>>::approve())]40	fn approve(&mut self, _caller: Caller, _spender: Address, _amount: U256) -> Result<bool> {41		// self.consume_store_reads(1)?;42		Err("Approve not supported".into())43	}4445	fn balance_of(&self, owner: Address) -> Result<U256> {46		// self.consume_store_reads(1)?;47		let owner = T::CrossAccountId::from_eth(owner);48		let balance = <T as Config>::Currency::free_balance(owner.as_sub());49		Ok(balance.into())50	}5152	fn decimals(&self) -> Result<u8> {53		Ok(T::Decimals::get())54	}5556	fn name(&self) -> Result<String> {57		Ok(T::Name::get())58	}5960	fn symbol(&self) -> Result<String> {61		Ok(T::Symbol::get())62	}6364	fn total_supply(&self) -> Result<U256> {65		// self.consume_store_reads(1)?;66		let total = <T as Config>::Currency::total_issuance();67		Ok(total.into())68	}6970	#[weight(<SelfWeightOf<T>>::transfer())]71	fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {72		let caller = T::CrossAccountId::from_eth(caller);73		let to = T::CrossAccountId::from_eth(to);74		let amount = amount.try_into().map_err(|_| "amount overflow")?;75		// let budget = self76		// 	.recorder77		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());7879		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;80		<T as Config>::Currency::transfer(81			caller.as_sub(),82			to.as_sub(),83			amount,84			ExistenceRequirement::KeepAlive,85		)86		.map_err(dispatch_to_evm::<T>)?;87		Ok(true)88	}8990	#[weight(<SelfWeightOf<T>>::transfer())]91	fn transfer_from(92		&mut self,93		caller: Caller,94		from: Address,95		to: Address,96		amount: U256,97	) -> Result<bool> {98		let caller = T::CrossAccountId::from_eth(caller);99		let from = T::CrossAccountId::from_eth(from);100		let to = T::CrossAccountId::from_eth(to);101		let amount = amount.try_into().map_err(|_| "amount overflow")?;102103		if from != caller {104			return Err("no permission".into());105		}106		// let budget = self107		// 	.recorder108		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());109110		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)111		// 	.map_err(dispatch_to_evm::<T>)?;112		<T as Config>::Currency::transfer(113			caller.as_sub(),114			to.as_sub(),115			amount,116			ExistenceRequirement::KeepAlive,117		)118		.map_err(dispatch_to_evm::<T>)?;119		Ok(true)120	}121}122123#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]124impl<T: Config> NativeFungibleHandle<T>125where126	T::AccountId: From<[u8; 32]>,127{128	fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {129		// self.consume_store_reads(1)?;130		let owner = owner.into_sub_cross_account::<T>()?;131		let balance = <T as Config>::Currency::free_balance(owner.as_sub());132		Ok(balance.into())133	}134135	#[weight(<SelfWeightOf<T>>::transfer())]136	fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {137		let caller = T::CrossAccountId::from_eth(caller);138		let to = to.into_sub_cross_account::<T>()?;139		let amount = amount.try_into().map_err(|_| "amount overflow")?;140		// let budget = self141		// 	.recorder142		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());143144		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;145		<T as Config>::Currency::transfer(146			caller.as_sub(),147			to.as_sub(),148			amount,149			ExistenceRequirement::KeepAlive,150		)151		.map_err(dispatch_to_evm::<T>)?;152		Ok(true)153	}154155	#[weight(<SelfWeightOf<T>>::transfer())]156	fn transfer_from_cross(157		&mut self,158		caller: Caller,159		from: CrossAddress,160		to: CrossAddress,161		amount: U256,162	) -> Result<bool> {163		let caller = T::CrossAccountId::from_eth(caller);164		let from = from.into_sub_cross_account::<T>()?;165		let to = to.into_sub_cross_account::<T>()?;166		let amount = amount.try_into().map_err(|_| "amount overflow")?;167168		if from != caller {169			return Err("no permission".into());170		}171172		// let budget = self173		// 	.recorder174		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());175176		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)177		// 	.map_err(dispatch_to_evm::<T>)?;178		<T as Config>::Currency::transfer(179			caller.as_sub(),180			to.as_sub(),181			amount,182			ExistenceRequirement::KeepAlive,183		)184		.map_err(dispatch_to_evm::<T>)?;185		Ok(true)186	}187}188189#[solidity_interface(190	name = UniqueNativeFungible,191	is(ERC20, ERC20UniqueExtensions),192	enum(derive(PreDispatch))193)]194impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}195196generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);197generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);198199impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>200where201	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,202{203	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");204205	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {206		call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)207	}208}