1use crate::{AccountId, AssetId};
20
21use fp_evm::AccountProvider;
22use frame_support::{
23 ensure,
24 traits::{
25 fungible::{Balanced, Credit},
26 tokens::{fungible::Inspect, imbalance::OnUnbalanced},
27 },
28};
29use pallet_evm::OnChargeEVMTransaction;
30pub use sp_core::{H160, H256, U256};
31use sp_runtime::traits::UniqueSaturatedInto;
32use sp_std::marker::PhantomData;
33
34use pallet_assets::AssetsCallback;
35use pallet_evm_precompile_assets_erc20::AddressToAssetId;
36
37pub type EvmAddress = H160;
38
39pub const EVM_REVERT_CODE: &[u8] = &[0x60, 0x00, 0x60, 0x00, 0xfd];
41
42pub const TX_MAX_GAS_LIMIT: u64 = 35_000_000;
45
46pub struct EvmRevertCodeHandler<A, R>(PhantomData<(A, R)>);
54impl<A, R> AssetsCallback<AssetId, AccountId> for EvmRevertCodeHandler<A, R>
55where
56 A: AddressToAssetId<AssetId>,
57 R: pallet_evm::Config,
58{
59 fn created(id: &AssetId, _: &AccountId) -> Result<(), ()> {
60 let address = A::asset_id_to_address(*id);
61 ensure!(!pallet_evm::AccountCodes::<R>::contains_key(&address), ());
63 pallet_evm::AccountCodes::<R>::insert(address, EVM_REVERT_CODE.to_vec());
64 Ok(())
65 }
66
67 fn destroyed(id: &AssetId) -> Result<(), ()> {
68 let address = A::asset_id_to_address(*id);
69 pallet_evm::AccountCodes::<R>::remove(address);
70 Ok(())
71 }
72}
73
74pub struct EVMFungibleAdapterWrapper<F, FeeHandler, TipHandler>(
84 core::marker::PhantomData<(F, FeeHandler, TipHandler)>,
85);
86impl<T, F, FeeHandler, TipHandler> OnChargeEVMTransaction<T>
87 for EVMFungibleAdapterWrapper<F, FeeHandler, TipHandler>
88where
89 T: pallet_evm::Config,
90 F: Balanced<<T::AccountProvider as AccountProvider>::AccountId>,
91 FeeHandler: OnUnbalanced<Credit<<T::AccountProvider as AccountProvider>::AccountId, F>>,
92 TipHandler: OnUnbalanced<Credit<<T::AccountProvider as AccountProvider>::AccountId, F>>,
93 U256: UniqueSaturatedInto<
94 <F as Inspect<<T::AccountProvider as AccountProvider>::AccountId>>::Balance,
95 >,
96{
97 type LiquidityInfo = Option<Credit<<T::AccountProvider as AccountProvider>::AccountId, F>>;
99
100 fn withdraw_fee(who: &H160, fee: U256) -> Result<Self::LiquidityInfo, pallet_evm::Error<T>> {
101 pallet_evm::EVMFungibleAdapter::<F, FeeHandler>::withdraw_fee(who, fee)
102 }
103
104 fn can_withdraw(who: &H160, amount: U256) -> Result<(), pallet_evm::Error<T>> {
105 pallet_evm::EVMFungibleAdapter::<F, FeeHandler>::can_withdraw(who, amount)
106 }
107
108 fn correct_and_deposit_fee(
109 who: &H160,
110 corrected_fee: U256,
111 base_fee: U256,
112 already_withdrawn: Self::LiquidityInfo,
113 ) -> Self::LiquidityInfo {
114 <pallet_evm::EVMFungibleAdapter::<F, FeeHandler> as OnChargeEVMTransaction<T>>::correct_and_deposit_fee(
115 who,
116 corrected_fee,
117 base_fee,
118 already_withdrawn,
119 )
120 }
121
122 fn pay_priority_fee(tip: Self::LiquidityInfo) {
123 if let Some(tip) = tip {
124 TipHandler::on_unbalanceds(Some(tip).into_iter());
125 }
126 }
127}