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

difftreelog

source

pallets/nft/src/eth/sponsoring.rs2.5 KiBsourcehistory
1//! Implements EVM sponsoring logic via OnChargeEVMTransaction23use crate::{Config, sponsorship::*};4use evm_coder::{Call, abi::AbiReader};5use pallet_common::{CollectionHandle, eth::map_eth_to_id};6use sp_core::H160;7use sp_std::prelude::*;8use up_sponsorship::SponsorshipHandler;9use core::marker::PhantomData;10use core::convert::TryInto;11use nft_data_structs::TokenId;12use up_evm_mapping::EvmBackwardsAddressMapping;13use pallet_evm::AddressMapping;1415use pallet_nonfungible::erc::{UniqueNFTCall, ERC721UniqueExtensionsCall, ERC721Call};16use pallet_fungible::erc::{UniqueFungibleCall, ERC20Call};1718pub struct NftEthSponsorshipHandler<T: Config>(PhantomData<*const T>);19impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for NftEthSponsorshipHandler<T> {20	fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {21		let collection_id = map_eth_to_id(&call.0)?;22		let collection = <CollectionHandle<T>>::new(collection_id)?;23		let sponsor = collection.sponsorship.sponsor()?.clone();24		let sponsor =25			<T as pallet_common::Config>::EvmBackwardsAddressMapping::from_account_id(sponsor);26		let who = <T as pallet_common::Config>::EvmAddressMapping::into_account_id(*who);27		let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;28		match &collection.mode {29			crate::CollectionMode::NFT => {30				let call = UniqueNFTCall::parse(method_id, &mut reader).ok()??;31				match call {32					UniqueNFTCall::ERC721UniqueExtensions(33						ERC721UniqueExtensionsCall::Transfer { token_id, .. },34					)35					| UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, .. }) => {36						let token_id: TokenId = token_id.try_into().ok()?;37						withdraw_transfer::<T>(&collection, &who, &token_id).map(|()| sponsor)38					}39					UniqueNFTCall::ERC721(ERC721Call::Approve { token_id, .. }) => {40						let token_id: TokenId = token_id.try_into().ok()?;41						withdraw_approve::<T>(&collection, &who, &token_id).map(|()| sponsor)42					}43					_ => None,44				}45			}46			crate::CollectionMode::Fungible(_) => {47				let call = UniqueFungibleCall::parse(method_id, &mut reader).ok()??;48				#[allow(clippy::single_match)]49				match call {50					UniqueFungibleCall::ERC20(51						ERC20Call::Transfer { .. } | ERC20Call::TransferFrom { .. },52					) => withdraw_transfer::<T>(&collection, &who, &TokenId::default())53						.map(|()| sponsor),54					UniqueFungibleCall::ERC20(ERC20Call::Approve { .. }) => {55						withdraw_approve::<T>(&collection, &who, &TokenId::default())56							.map(|()| sponsor)57					}58					_ => None,59				}60			}61			_ => None,62		}63	}64}