git.delta.rocks / unique-network / refs/commits / dc1fefd785d4

difftreelog

source

pallets/fungible/src/erc.rs4.1 KiBsourcehistory
1use core::char::{REPLACEMENT_CHARACTER, decode_utf16};2use core::convert::TryInto;3use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight};4use nft_data_structs::CollectionMode;5use pallet_common::erc::CommonEvmHandler;6use sp_core::{H160, U256};7use sp_std::vec::Vec;8use pallet_common::account::CrossAccountId;9use pallet_common::erc::PrecompileOutput;10use pallet_evm_coder_substrate::{call, dispatch_to_evm};1112use crate::{13	Allowance, Balance, Config, FungibleHandle, Pallet, SelfWeightOf, TotalSupply,14	weights::WeightInfo,15};1617#[derive(ToLog)]18pub enum ERC20Events {19	Transfer {20		#[indexed]21		from: address,22		#[indexed]23		to: address,24		value: uint256,25	},26	Approval {27		#[indexed]28		owner: address,29		#[indexed]30		spender: address,31		value: uint256,32	},33}3435#[solidity_interface(name = "ERC20", events(ERC20Events))]36impl<T: Config> FungibleHandle<T> {37	fn name(&self) -> Result<string> {38		Ok(decode_utf16(self.name.iter().copied())39			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))40			.collect::<string>())41	}42	fn symbol(&self) -> Result<string> {43		Ok(string::from_utf8_lossy(&self.token_prefix).into())44	}45	fn total_supply(&self) -> Result<uint256> {46		self.consume_store_reads(1)?;47		Ok(<TotalSupply<T>>::get(self.id).into())48	}4950	fn decimals(&self) -> Result<uint8> {51		Ok(if let CollectionMode::Fungible(decimals) = &self.mode {52			*decimals53		} else {54			unreachable!()55		})56	}57	fn balance_of(&self, owner: address) -> Result<uint256> {58		self.consume_store_reads(1)?;59		let owner = T::CrossAccountId::from_eth(owner);60		let balance = <Balance<T>>::get((self.id, owner));61		Ok(balance.into())62	}63	#[weight(<SelfWeightOf<T>>::transfer())]64	fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {65		let caller = T::CrossAccountId::from_eth(caller);66		let to = T::CrossAccountId::from_eth(to);67		let amount = amount.try_into().map_err(|_| "amount overflow")?;6869		<Pallet<T>>::transfer(self, &caller, &to, amount).map_err(|_| "transfer error")?;70		Ok(true)71	}72	#[weight(<SelfWeightOf<T>>::transfer_from())]73	fn transfer_from(74		&mut self,75		caller: caller,76		from: address,77		to: address,78		amount: uint256,79	) -> Result<bool> {80		let caller = T::CrossAccountId::from_eth(caller);81		let from = T::CrossAccountId::from_eth(from);82		let to = T::CrossAccountId::from_eth(to);83		let amount = amount.try_into().map_err(|_| "amount overflow")?;8485		<Pallet<T>>::transfer_from(self, &caller, &from, &to, amount)86			.map_err(dispatch_to_evm::<T>)?;87		Ok(true)88	}89	#[weight(<SelfWeightOf<T>>::approve())]90	fn approve(&mut self, caller: caller, spender: address, amount: uint256) -> Result<bool> {91		let caller = T::CrossAccountId::from_eth(caller);92		let spender = T::CrossAccountId::from_eth(spender);93		let amount = amount.try_into().map_err(|_| "amount overflow")?;9495		<Pallet<T>>::set_allowance(self, &caller, &spender, amount)96			.map_err(dispatch_to_evm::<T>)?;97		Ok(true)98	}99	fn allowance(&self, owner: address, spender: address) -> Result<uint256> {100		self.consume_store_reads(1)?;101		let owner = T::CrossAccountId::from_eth(owner);102		let spender = T::CrossAccountId::from_eth(spender);103104		Ok(<Allowance<T>>::get((self.id, owner, spender)).into())105	}106}107108#[solidity_interface(name = "ERC20UniqueExtensions")]109impl<T: Config> FungibleHandle<T> {110	#[weight(<SelfWeightOf<T>>::burn_from())]111	fn burn_from(&mut self, caller: caller, from: address, amount: uint256) -> Result<bool> {112		let caller = T::CrossAccountId::from_eth(caller);113		let from = T::CrossAccountId::from_eth(from);114		let amount = amount.try_into().map_err(|_| "amount overflow")?;115116		<Pallet<T>>::burn_from(self, &caller, &from, amount).map_err(dispatch_to_evm::<T>)?;117		Ok(true)118	}119}120121#[solidity_interface(name = "UniqueFungible", is(ERC20))]122impl<T: Config> FungibleHandle<T> {}123124generate_stubgen!(gen_impl, UniqueFungibleCall<()>, true);125generate_stubgen!(gen_iface, UniqueFungibleCall<()>, false);126127impl<T: Config> CommonEvmHandler for FungibleHandle<T> {128	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueFungible.raw");129130	fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileOutput> {131		call::<T, UniqueFungibleCall<T>, _>(*source, self, value, input)132	}133}