@@ -738,8 +738,6 @@ fn evm_permit_set_currency_dispatch_should_pay_evm_fee_in_chosen_erc20_currency(
738738 ) ) ;
739739 let fee_currency = asset;
740740
741- //let fee_currency = DAI;
742-
743741 init_omnipool_with_oracle_for_block_10 ( ) ;
744742 //Add new erc20 token to omnipool and populate oracle
745743 assert_ok ! ( hydradx_runtime:: Omnipool :: add_token(
@@ -864,6 +862,177 @@ fn evm_permit_set_currency_dispatch_should_pay_evm_fee_in_chosen_erc20_currency(
864862 } )
865863}
866864
865+ #[ test]
866+ fn evm_permit_set_currency_dispatch_should_work_when_wrapped_in_dispatch_with_extra_gas_by_frontend ( ) {
867+ TestNet :: reset ( ) ;
868+
869+ let user_evm_address = alith_evm_address ( ) ;
870+ let user_secret_key = alith_secret_key ( ) ;
871+ let user_acc = MockAccount :: new ( alith_truncated_account ( ) ) ;
872+ let treasury_acc = MockAccount :: new ( Treasury :: account_id ( ) ) ;
873+
874+ Hydra :: execute_with ( || {
875+ //Create new erc20, fund user with it and set it as fee payment currency
876+ let contract = crate :: erc20:: deploy_token_contract ( ) ;
877+ let asset = crate :: erc20:: bind_erc20 ( contract) ;
878+ let balance = Currencies :: free_balance ( asset, & ALICE . into ( ) ) ;
879+ let initial_treasury_fee_balance = treasury_acc. balance ( asset) ;
880+ let erc20_balance = 2000000000000000 ;
881+ assert_eq ! ( erc20_balance, 2000000000000000 ) ;
882+ assert_ok ! ( <Erc20Currency <Runtime > as ERC20 >:: transfer(
883+ CallContext {
884+ contract: contract,
885+ sender: crate :: erc20:: deployer( ) ,
886+ origin: crate :: erc20:: deployer( )
887+ } ,
888+ user_evm_address,
889+ erc20_balance
890+ ) ) ;
891+
892+ assert_ok ! ( Currencies :: transfer(
893+ hydradx_runtime:: RuntimeOrigin :: signed( alith_evm_account( ) ) ,
894+ hydradx_runtime:: Omnipool :: protocol_account( ) ,
895+ asset,
896+ erc20_balance / 2
897+ ) ) ;
898+
899+ let alith_balance = Currencies :: free_balance ( asset, & alith_evm_account ( ) . into ( ) ) ;
900+ assert_eq ! ( alith_balance, erc20_balance / 2 ) ;
901+
902+ assert_ok ! ( MultiTransactionPayment :: add_currency(
903+ hydradx_runtime:: RuntimeOrigin :: root( ) ,
904+ asset,
905+ FixedU128 :: from_rational( 1 , 2 )
906+ ) ) ;
907+ assert_ok ! ( MultiTransactionPayment :: set_currency(
908+ hydradx_runtime:: RuntimeOrigin :: signed( alith_evm_account( ) ) ,
909+ DAI ,
910+ ) ) ;
911+ let fee_currency = asset;
912+
913+ init_omnipool_with_oracle_for_block_10 ( ) ;
914+ //Add new erc20 token to omnipool and populate oracle
915+ assert_ok ! ( hydradx_runtime:: Omnipool :: add_token(
916+ hydradx_runtime:: RuntimeOrigin :: root( ) ,
917+ asset,
918+ FixedU128 :: from_rational( 1 , 2 ) ,
919+ Permill :: from_percent( 100 ) ,
920+ AccountId :: from( alith_evm_account( ) ) ,
921+ ) ) ;
922+ assert_ok ! ( Omnipool :: sell(
923+ RuntimeOrigin :: signed( alith_evm_account( ) ) ,
924+ asset,
925+ 0 ,
926+ erc20_balance / 10 ,
927+ Balance :: MIN
928+ ) ) ;
929+ hydradx_run_to_next_block ( ) ;
930+
931+ pallet_transaction_payment:: pallet:: NextFeeMultiplier :: < hydradx_runtime:: Runtime > :: put (
932+ hydradx_runtime:: MinimumMultiplier :: get ( ) ,
933+ ) ;
934+
935+ let initial_user_fee_currency_balance = user_acc. balance ( fee_currency) ;
936+ let initial_user_weth_balance = user_acc. balance ( WETH ) ;
937+
938+ let initial_fee_currency_issuance = Currencies :: total_issuance ( fee_currency) ;
939+
940+ // just reset the weth balance to 0 - to make sure we don't have enough WETH
941+ assert_ok ! ( hydradx_runtime:: Currencies :: update_balance(
942+ hydradx_runtime:: RuntimeOrigin :: root( ) ,
943+ user_acc. address( ) ,
944+ WETH ,
945+ -( initial_user_weth_balance as i128 ) ,
946+ ) ) ;
947+
948+ let initial_user_weth_balance = user_acc. balance ( WETH ) ;
949+ assert_eq ! ( initial_user_weth_balance, 0 ) ;
950+
951+ let set_currency_call = hydradx_runtime:: RuntimeCall :: MultiTransactionPayment (
952+ pallet_transaction_multi_payment:: Call :: set_currency { currency : fee_currency } ,
953+ ) ;
954+ let dispatch_set_currency_call =
955+ hydradx_runtime:: RuntimeCall :: Dispatcher ( pallet_dispatcher:: Call :: dispatch_with_extra_gas {
956+ call : Box :: new ( set_currency_call. clone ( ) ) ,
957+ extra_gas : 100_000 ,
958+ } ) ;
959+
960+ let gas_limit = 1000000 ;
961+ let deadline = U256 :: from ( 1000000000000u128 ) ;
962+
963+ let permit =
964+ pallet_evm_precompile_call_permit:: CallPermitPrecompile :: < hydradx_runtime:: Runtime > :: generate_permit (
965+ CALLPERMIT ,
966+ user_evm_address,
967+ DISPATCH_ADDR ,
968+ U256 :: from ( 0 ) ,
969+ dispatch_set_currency_call. encode ( ) ,
970+ gas_limit,
971+ U256 :: zero ( ) ,
972+ deadline,
973+ ) ;
974+ let secret_key = SecretKey :: parse ( & user_secret_key) . unwrap ( ) ;
975+ let message = Message :: parse ( & permit) ;
976+ let ( rs, v) = sign ( & message, & secret_key) ;
977+
978+ // Validate unsigned first
979+ let call: pallet_transaction_multi_payment:: Call < hydradx_runtime:: Runtime > =
980+ pallet_transaction_multi_payment:: Call :: dispatch_permit {
981+ from : user_evm_address,
982+ to : DISPATCH_ADDR ,
983+ value : U256 :: from ( 0 ) ,
984+ data : dispatch_set_currency_call. encode ( ) ,
985+ gas_limit,
986+ deadline,
987+ v : v. serialize ( ) ,
988+ r : H256 :: from ( rs. r . b32 ( ) ) ,
989+ s : H256 :: from ( rs. s . b32 ( ) ) ,
990+ } ;
991+
992+ let tag: Vec < u8 > = ( "EVMPermit" , ( U256 :: zero ( ) , user_evm_address) ) . encode ( ) ;
993+ assert_eq ! (
994+ MultiTransactionPayment :: validate_unsigned( TransactionSource :: External , & call) ,
995+ Ok ( ValidTransaction {
996+ priority: 0 ,
997+ requires: vec![ ] ,
998+ provides: vec![ tag] ,
999+ longevity: 64 ,
1000+ propagate: true ,
1001+ } )
1002+ ) ;
1003+
1004+ // And Dispatch
1005+ assert_ok ! ( MultiTransactionPayment :: dispatch_permit(
1006+ hydradx_runtime:: RuntimeOrigin :: none( ) ,
1007+ user_evm_address,
1008+ DISPATCH_ADDR ,
1009+ U256 :: from( 0 ) ,
1010+ dispatch_set_currency_call. encode( ) ,
1011+ gas_limit,
1012+ deadline,
1013+ v. serialize( ) ,
1014+ H256 :: from( rs. r. b32( ) ) ,
1015+ H256 :: from( rs. s. b32( ) ) ,
1016+ ) ) ;
1017+
1018+ let currency =
1019+ pallet_transaction_multi_payment:: Pallet :: < hydradx_runtime:: Runtime > :: account_currency ( & user_acc. address ( ) ) ;
1020+ assert_eq ! ( currency, fee_currency) ;
1021+
1022+ let fee_currency_issuance = Currencies :: total_issuance ( fee_currency) ;
1023+ assert_eq ! ( initial_fee_currency_issuance, fee_currency_issuance) ;
1024+
1025+ let user_fee_currency_balance = user_acc. balance ( fee_currency) ;
1026+ assert ! ( user_fee_currency_balance < initial_user_fee_currency_balance) ;
1027+ let final_treasury_fee_balance = treasury_acc. balance ( asset) ;
1028+
1029+ assert ! ( final_treasury_fee_balance > initial_treasury_fee_balance) ;
1030+ let fee_amount = initial_user_fee_currency_balance - user_fee_currency_balance;
1031+ let treasury_received = final_treasury_fee_balance - initial_treasury_fee_balance;
1032+ assert_eq ! ( fee_amount, treasury_received) ;
1033+ } )
1034+ }
1035+
8671036#[ test]
8681037fn evm_permit_set_currency_dispatch_should_pay_evm_fee_in_insufficient_asset ( ) {
8691038 TestNet :: reset ( ) ;
0 commit comments