From 06c3db2f3f0eac4259991168d52fbdb950e1fc1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Rodriguez?= Date: Thu, 2 Jan 2025 11:03:35 -0300 Subject: [PATCH] Add more TS tests for pallet-xcm precompile (#3107) * add tests for native fee payment * fix sudo * add tests for transferAssetsUsingTypeAndThen() * fix test name * try using evm foreign assets in pallet-xcm precompile * fix: pallet-xcm-precompile shall allow subcalls * increase recursion_limit to 1 in pallet-xcm-precompile * fix formatting * test(): correctly check balance of evm native assets * fix tests * clean code * refactor test --------- Co-authored-by: Rodrigo Quelhas <22591718+RomarQ@users.noreply.github.com> Co-authored-by: Rodrigo Quelhas Co-authored-by: Gonza Montiel --- runtime/moonbase/src/precompiles.rs | 16 +- runtime/moonbeam/src/precompiles.rs | 6 +- runtime/moonriver/src/precompiles.rs | 6 +- test/helpers/assets.ts | 11 +- .../test-precompile-pallet-xcm-2.ts | 423 ++++++++++++++++++ .../test-precompile-pallet-xcm.ts | 164 +++---- 6 files changed, 499 insertions(+), 127 deletions(-) create mode 100644 test/suites/dev/moonbase/test-precompile/test-precompile-pallet-xcm-2.ts diff --git a/runtime/moonbase/src/precompiles.rs b/runtime/moonbase/src/precompiles.rs index 0ea4e50fac..9f23ba2167 100644 --- a/runtime/moonbase/src/precompiles.rs +++ b/runtime/moonbase/src/precompiles.rs @@ -16,11 +16,10 @@ use super::moonbase_weights; use crate::{ - asset_config::ForeignAssetInstance, - xcm_config::{AssetType, XcmExecutorConfig}, - OpenTechCommitteeInstance, TreasuryCouncilInstance, + asset_config::ForeignAssetInstance, xcm_config::XcmExecutorConfig, OpenTechCommitteeInstance, + TreasuryCouncilInstance, }; -use crate::{AccountId, AssetId, AssetManager, Balances, Erc20XcmBridge, Runtime, H160}; +use crate::{AccountId, AssetId, Balances, Erc20XcmBridge, EvmForeignAssets, Runtime, H160}; use frame_support::parameter_types; use moonkit_xcm_primitives::{ location_matcher::{Erc20PalletMatcher, ForeignAssetMatcher, SingleAddressMatcher}, @@ -61,7 +60,6 @@ use pallet_precompile_benchmarks::WeightInfo; use precompile_foreign_asset_migrator::ForeignAssetMigratorPrecompile; use precompile_utils::precompile_set::*; use sp_std::prelude::*; -use xcm_primitives::AsAssetType; parameter_types! { pub P256VerifyWeight: frame_support::weights::Weight = @@ -113,7 +111,7 @@ type EthereumPrecompilesChecks = (AcceptDelegateCall, CallableByContract, Callab // Pallet-xcm precompile types. // Type that converts AssetId into Location -type AssetIdToLocationManager = AsAssetType; +type AssetIdToLocationManager = EvmForeignAssets; // The pallet-balances address is identified by ERC20_BALANCES_PRECOMPILE const type SingleAddressMatch = SingleAddressMatcher; @@ -280,7 +278,11 @@ type MoonbasePrecompilesAt = ( PrecompileAt< AddressU64<2074>, PalletXcmPrecompile, - (CallableByContract, CallableByPrecompile), + ( + CallableByContract, + CallableByPrecompile, + SubcallWithMaxNesting<1>, + ), >, PrecompileAt, ForeignAssetMigratorPrecompile, ()>, ); diff --git a/runtime/moonbeam/src/precompiles.rs b/runtime/moonbeam/src/precompiles.rs index 21062733f4..355e905975 100644 --- a/runtime/moonbeam/src/precompiles.rs +++ b/runtime/moonbeam/src/precompiles.rs @@ -277,7 +277,11 @@ type MoonbeamPrecompilesAt = ( PrecompileAt< AddressU64<2074>, PalletXcmPrecompile, - (CallableByContract, CallableByPrecompile), + ( + CallableByContract, + CallableByPrecompile, + SubcallWithMaxNesting<1>, + ), >, ); diff --git a/runtime/moonriver/src/precompiles.rs b/runtime/moonriver/src/precompiles.rs index 801cf6e346..662c429801 100644 --- a/runtime/moonriver/src/precompiles.rs +++ b/runtime/moonriver/src/precompiles.rs @@ -271,7 +271,11 @@ type MoonriverPrecompilesAt = ( PrecompileAt< AddressU64<2074>, PalletXcmPrecompile, - (CallableByContract, CallableByPrecompile), + ( + CallableByContract, + CallableByPrecompile, + SubcallWithMaxNesting<1>, + ), >, ); diff --git a/test/helpers/assets.ts b/test/helpers/assets.ts index 9cb3389cfc..9a11cb7724 100644 --- a/test/helpers/assets.ts +++ b/test/helpers/assets.ts @@ -479,20 +479,23 @@ export async function registerAndFundAsset( context: any, asset: TestAsset, amount: bigint, - address: `0x${string}` + address: `0x${string}`, + addToWeightTrader = true ) { - const { registeredAssetId } = await registerForeignAsset( + const result = await registerForeignAsset( context, BigInt(asset.id), asset.location, asset.metadata ); - await addAssetToWeightTrader(asset.location, asset.relativePrice || 0n, context); + if (addToWeightTrader) { + await addAssetToWeightTrader(asset.location, asset.relativePrice || 0n, context); + } await mockAssetBalance(context, amount, BigInt(asset.id), alith, address); - return registeredAssetId; + return result; } // Mock balance for old foreign assets diff --git a/test/suites/dev/moonbase/test-precompile/test-precompile-pallet-xcm-2.ts b/test/suites/dev/moonbase/test-precompile/test-precompile-pallet-xcm-2.ts new file mode 100644 index 0000000000..298870d041 --- /dev/null +++ b/test/suites/dev/moonbase/test-precompile/test-precompile-pallet-xcm-2.ts @@ -0,0 +1,423 @@ +import "@moonbeam-network/api-augment"; +import { + beforeAll, + describeSuite, + fetchCompiledContract, + expect, + customDevRpcRequest, +} from "@moonwall/cli"; +import { + ALITH_ADDRESS, + BALTATHAR_ADDRESS, + alith, + baltathar, + createEthersTransaction, + PRECOMPILE_NATIVE_ERC20_ADDRESS, +} from "@moonwall/util"; +import { encodeFunctionData, erc20Abi } from "viem"; +import { + expectEVMResult, + PARA_1000_SOURCE_LOCATION, + mockHrmpChannelExistanceTx, + ARBITRARY_ASSET_ID, + mockAssetBalance, + registerForeignAsset, + relayAssetMetadata, + RELAY_SOURCE_LOCATION_V4, + registerAndFundAsset, +} from "../../../../helpers"; +import type { AssetMetadata } from "../../../../helpers"; +import { ethers } from "ethers"; + +const PRECOMPILE_PALLET_XCM_ADDRESS: `0x${string}` = "0x000000000000000000000000000000000000081A"; + +export const para1000AssetMetadata: AssetMetadata = { + name: "PARA", + symbol: "PARA", + decimals: 12n, + isFrozen: false, +}; + +describeSuite({ + id: "D012901", + title: "Precompiles - PalletXcm: Native fee", + foundationMethods: "dev", + testCases: ({ context, it }) => { + let foreignRelayAssetContract: ethers.Contract; + let foreignParaAssetContract: ethers.Contract; + + const destinationPara = 1000; + const amountToSend = 100n; + + beforeAll(async () => { + const balance = 200000000000000n; + + // Register the asset + const { registeredAssetId: relayAssetId, contractAddress: relayAssetAddress } = + await registerAndFundAsset( + context, + { + id: ARBITRARY_ASSET_ID, + location: RELAY_SOURCE_LOCATION_V4, + metadata: relayAssetMetadata, + relativePrice: 1_000_000_000_000_000_000n, + }, + balance, + ALITH_ADDRESS, + false + ); + + console.log("Foreign Relay asset address: ", relayAssetAddress); + console.log("Foreign Relay asset id: ", relayAssetId); + + foreignRelayAssetContract = new ethers.Contract( + relayAssetAddress, + erc20Abi, + context.ethers() + ); + + // Register the asset + const { registeredAssetId: paraAssetId, contractAddress: paraAssetAddress } = + await registerAndFundAsset( + context, + { + id: ARBITRARY_ASSET_ID + 1n, + location: PARA_1000_SOURCE_LOCATION, + metadata: para1000AssetMetadata, + relativePrice: 1_000_000_000_000_000_000n, + }, + balance, + ALITH_ADDRESS + ); + + console.log("Foreign Para asset address: ", paraAssetAddress); + console.log("Foreign Para asset id: ", paraAssetId); + + foreignParaAssetContract = new ethers.Contract(paraAssetAddress, erc20Abi, context.ethers()); + + // Change the sudo key so that we avoid nonce issues. + const sudoKeyTx = context.polkadotJs().tx.sudo.setKey(baltathar.address); + await context.createBlock(await sudoKeyTx.signAsync(alith), { allowFailures: false }); + }); + + it({ + id: "T01", + title: "transferAssetsLocation: allows to pay fees with native asset", + test: async function () { + const { abi: xcmInterface } = fetchCompiledContract("XCM"); + const assetBalanceBefore = await foreignRelayAssetContract.balanceOf(ALITH_ADDRESS); + + const dest: [number, any[]] = [1, []]; + + const destinationAddress = + "0101010101010101010101010101010101010101010101010101010101010101"; + const destinationNetworkId = "00"; + const beneficiary: [number, any[]] = [ + 0, + // junction: AccountId32 enum (01) + the 32 byte account + Any network selector(00) + ["0x01" + destinationAddress + destinationNetworkId], + ]; + + const x1_pallet_instance_enum_selector = "0x04"; + const x1_instance = "03"; + + // This multilocation represents our native token + const nativeAssetLocation = [ + // zero parents + 0, + // X1(PalletInstance) + // PalletInstance: Selector (04) + balances pallet instance 1 byte (03) + [x1_pallet_instance_enum_selector + x1_instance], + ]; + + const nonFeeAssetLocation: [number, any[]] = [1, []]; + const assetLocationInfo = [ + [nonFeeAssetLocation, amountToSend], + [nativeAssetLocation, 100n], + ]; + + const rawTxn = await createEthersTransaction(context, { + to: PRECOMPILE_PALLET_XCM_ADDRESS, + data: encodeFunctionData({ + abi: xcmInterface, + args: [dest, beneficiary, assetLocationInfo, 1], + functionName: "transferAssetsLocation", + }), + gasLimit: 500_000n, + }); + + const result = await context.createBlock(rawTxn); + expectEVMResult(result.result!.events, "Succeed"); + + const assetBalanceAfter = await foreignRelayAssetContract.balanceOf(ALITH_ADDRESS); + expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); + }, + }); + + it({ + id: "T02", + title: "transferAssetsToPara20: allows to pay fees with native asset", + test: async function () { + const { abi: xcmInterface } = fetchCompiledContract("XCM"); + const assetBalanceBefore = await foreignParaAssetContract.balanceOf(ALITH_ADDRESS); + + const paraId = destinationPara; + + // Assets must be sorted, so we put the native one first as it has a lower "parents" field. + const assetAddressInfo = [ + [PRECOMPILE_NATIVE_ERC20_ADDRESS, amountToSend], + [await foreignParaAssetContract.getAddress(), amountToSend], + ]; + + const mockHrmp1000Tx = context + .polkadotJs() + .tx.sudo.sudo(mockHrmpChannelExistanceTx(context, destinationPara, 1000, 102400, 102400)); + + const alithNonce = ( + await context.polkadotJs().query.system.account(alith.address) + ).nonce.toNumber(); + const rawTxn = await createEthersTransaction(context, { + to: PRECOMPILE_PALLET_XCM_ADDRESS, + data: encodeFunctionData({ + abi: xcmInterface, + args: [paraId, BALTATHAR_ADDRESS, assetAddressInfo, 0], + functionName: "transferAssetsToPara20", + }), + gasLimit: 500_000n, + nonce: alithNonce, + }); + + // Insert the two txs in the same block. + await mockHrmp1000Tx.signAndSend(baltathar); + await customDevRpcRequest("eth_sendRawTransaction", [rawTxn]); + await context.createBlock(); + + const events = await context.polkadotJs().query.system.events(); + expectEVMResult(events, "Succeed"); + + const assetBalanceAfter = await foreignParaAssetContract.balanceOf(ALITH_ADDRESS); + expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); + }, + }); + + it({ + id: "T03", + title: "transferAssetsToPara32: allows to pay fees with native asset", + test: async function () { + const { abi: xcmInterface } = fetchCompiledContract("XCM"); + const assetBalanceBefore = await foreignParaAssetContract.balanceOf(ALITH_ADDRESS); + + const paraId = destinationPara; + + // Assets must be sorted, so we put the native one first as it has a lower "parents" field. + const assetAddressInfo = [ + [PRECOMPILE_NATIVE_ERC20_ADDRESS, amountToSend], + [await foreignParaAssetContract.getAddress(), amountToSend], + ]; + + const mockHrmp1000Tx = context + .polkadotJs() + .tx.sudo.sudo(mockHrmpChannelExistanceTx(context, destinationPara, 1000, 102400, 102400)); + + // 32 bytes beneficiary + const beneficiaryAddress = "01010101010101010101010101010101"; + + const alithNonce = ( + await context.polkadotJs().query.system.account(alith.address) + ).nonce.toNumber(); + const rawTxn = await createEthersTransaction(context, { + to: PRECOMPILE_PALLET_XCM_ADDRESS, + data: encodeFunctionData({ + abi: xcmInterface, + args: [paraId, beneficiaryAddress, assetAddressInfo, 0], + functionName: "transferAssetsToPara32", + }), + gasLimit: 500_000n, + nonce: alithNonce, + }); + + // Insert the two txs in the same block. + // First one with baltathar as sudo. + await mockHrmp1000Tx.signAndSend(baltathar); + await customDevRpcRequest("eth_sendRawTransaction", [rawTxn]); + await context.createBlock(); + + const events = await context.polkadotJs().query.system.events(); + expectEVMResult(events, "Succeed"); + + const assetBalanceAfter = await foreignParaAssetContract.balanceOf(ALITH_ADDRESS); + expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); + }, + }); + + it({ + id: "T04", + title: "transferAssetsToRelay: allows to pay fees with native asset", + test: async function () { + const { abi: xcmInterface } = fetchCompiledContract("XCM"); + const assetBalanceBefore = await foreignRelayAssetContract.balanceOf(ALITH_ADDRESS); + + // Assets must be sorted, so we put the native one first as it has a lower "parents" field. + const assetAddressInfo = [ + [PRECOMPILE_NATIVE_ERC20_ADDRESS, amountToSend], + [await foreignRelayAssetContract.getAddress(), amountToSend], + ]; + + const mockHrmp1000Tx = context + .polkadotJs() + .tx.sudo.sudo(mockHrmpChannelExistanceTx(context, destinationPara, 1000, 102400, 102400)); + + // 32 bytes beneficiary + const beneficiaryAddress = "01010101010101010101010101010101"; + + const alithNonce = ( + await context.polkadotJs().query.system.account(alith.address) + ).nonce.toNumber(); + const rawTxn = await createEthersTransaction(context, { + to: PRECOMPILE_PALLET_XCM_ADDRESS, + data: encodeFunctionData({ + abi: xcmInterface, + args: [beneficiaryAddress, assetAddressInfo, 0], + functionName: "transferAssetsToRelay", + }), + gasLimit: 500_000n, + nonce: alithNonce, + }); + + // Insert the two txs in the same block. + // First one with baltathar as sudo. + await mockHrmp1000Tx.signAndSend(baltathar); + await customDevRpcRequest("eth_sendRawTransaction", [rawTxn]); + await context.createBlock(); + + const events = await context.polkadotJs().query.system.events(); + expectEVMResult(events, "Succeed"); + + const assetBalanceAfter = await foreignRelayAssetContract.balanceOf(ALITH_ADDRESS); + expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); + }, + }); + + it({ + id: "T05", + title: + "transferAssetsUsingTypeAndThenLocation (8425d893): allows to pay fees with native asset", + test: async function () { + const { abi: xcmInterface } = fetchCompiledContract("XCM"); + const assetBalanceBefore = await foreignRelayAssetContract.balanceOf(ALITH_ADDRESS); + + const dest: [number, any[]] = [1, []]; + const assetLocation: [number, any[]] = [1, []]; + + const x1_pallet_instance_enum_selector = "0x04"; + const x1_instance = "03"; + + const nativeAssetLocation = [ + // zero parents + 0, + // X1(PalletInstance) + // PalletInstance: Selector (04) + balances pallet instance 1 byte (03) + [x1_pallet_instance_enum_selector + x1_instance], + ]; + + const assetLocationInfo = [ + [nativeAssetLocation, amountToSend], + [assetLocation, amountToSend], + ]; + + // LocalReserve + const feesTransferType = 1; + + // DestinationReserve + const assetsTransferType = 2; + + const message = { + V3: [ + { + ClearOrigin: null, + }, + ], + }; + const xcmOnDest = context.polkadotJs().createType("XcmVersionedXcm", message); + + const rawTxn = await createEthersTransaction(context, { + to: PRECOMPILE_PALLET_XCM_ADDRESS, + data: encodeFunctionData({ + abi: xcmInterface, + args: [ + dest, + assetLocationInfo, + assetsTransferType, + 0n, + feesTransferType, + xcmOnDest.toHex(), + ], + functionName: "transferAssetsUsingTypeAndThenLocation", + }), + gasLimit: 500_000n, + }); + + const result = await context.createBlock(rawTxn); + expectEVMResult(result.result!.events, "Succeed"); + + const assetBalanceAfter = await foreignRelayAssetContract.balanceOf(ALITH_ADDRESS); + expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); + }, + }); + + it({ + id: "T06", + title: + "transferAssetsUsingTypeAndThenAddress (8425d893): allows to pay fees with native asset", + test: async function () { + const { abi: xcmInterface } = fetchCompiledContract("XCM"); + const assetBalanceBefore = await foreignRelayAssetContract.balanceOf(ALITH_ADDRESS); + + // Relay as destination + const dest: [number, any[]] = [1, []]; + const assetAddressInfo = [ + [PRECOMPILE_NATIVE_ERC20_ADDRESS, amountToSend], + [await foreignRelayAssetContract.getAddress(), amountToSend], + ]; + + // LocalReserve + const feesTransferType = 1; + + // DestinationReserve + const assetsTransferType = 2; + + const message = { + V3: [ + { + ClearOrigin: null, + }, + ], + }; + const xcmOnDest = context.polkadotJs().createType("XcmVersionedXcm", message); + + const rawTxn = await createEthersTransaction(context, { + to: PRECOMPILE_PALLET_XCM_ADDRESS, + data: encodeFunctionData({ + abi: xcmInterface, + args: [ + dest, + assetAddressInfo, + assetsTransferType, + 0n, + feesTransferType, + xcmOnDest.toHex(), + ], + functionName: "transferAssetsUsingTypeAndThenAddress", + }), + gasLimit: 500_000n, + }); + + const result = await context.createBlock(rawTxn); + expectEVMResult(result.result!.events, "Succeed"); + + const assetBalanceAfter = await foreignRelayAssetContract.balanceOf(ALITH_ADDRESS); + expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); + }, + }); + }, +}); diff --git a/test/suites/dev/moonbase/test-precompile/test-precompile-pallet-xcm.ts b/test/suites/dev/moonbase/test-precompile/test-precompile-pallet-xcm.ts index 2cd1fcb249..5ba20f6aab 100644 --- a/test/suites/dev/moonbase/test-precompile/test-precompile-pallet-xcm.ts +++ b/test/suites/dev/moonbase/test-precompile/test-precompile-pallet-xcm.ts @@ -1,12 +1,16 @@ import "@moonbeam-network/api-augment"; import { beforeAll, describeSuite, fetchCompiledContract, expect } from "@moonwall/cli"; -import { ALITH_ADDRESS, BALTATHAR_ADDRESS, alith, createEthersTransaction } from "@moonwall/util"; -import { u128 } from "@polkadot/types-codec"; +import { ALITH_ADDRESS, BALTATHAR_ADDRESS, createEthersTransaction } from "@moonwall/util"; import { numberToHex } from "@polkadot/util"; -import { PalletAssetsAssetAccount, PalletAssetsAssetDetails } from "@polkadot/types/lookup"; -import { encodeFunctionData } from "viem"; -import { expectEVMResult, mockOldAssetBalance } from "../../../../helpers"; - +import { encodeFunctionData, erc20Abi } from "viem"; +import { + expectEVMResult, + relayAssetMetadata, + ARBITRARY_ASSET_ID, + RELAY_SOURCE_LOCATION_V4, + registerAndFundAsset, +} from "../../../../helpers"; +import { ethers } from "ethers"; const PRECOMPILE_PALLET_XCM_ADDRESS: `0x${string}` = "0x000000000000000000000000000000000000081A"; describeSuite({ @@ -14,36 +18,30 @@ describeSuite({ title: "Precompiles - PalletXcm", foundationMethods: "dev", testCases: ({ context, it }) => { - let assetId: u128; - const ADDRESS_ERC20 = "0xFfFFfFff1FcaCBd218EDc0EbA20Fc2308C778080"; - const ASSET_ID = 42259045809535163221576417993425387648n; + let foreignAssetContract: ethers.Contract; const amountToSend = 100n; - const weight = { refTime: 5000000000, proofSize: 40000 }; beforeAll(async () => { - const balance = 200000000000000n; - const assetBalance: PalletAssetsAssetAccount = context - .polkadotJs() - .createType("PalletAssetsAssetAccount", { - balance: balance, - }); - assetId = context.polkadotJs().createType("u128", ASSET_ID); - - const assetDetails: PalletAssetsAssetDetails = context - .polkadotJs() - .createType("PalletAssetsAssetDetails", { - supply: balance, - }); + const someBalance = 100_000_000_000_000_000_000_000_000n; - await mockOldAssetBalance( + // Register the asset + const { registeredAssetId, contractAddress } = await registerAndFundAsset( context, - assetBalance, - assetDetails, - alith, - assetId, + { + id: ARBITRARY_ASSET_ID, + location: RELAY_SOURCE_LOCATION_V4, + metadata: relayAssetMetadata, + relativePrice: 1_000_000_000_000_000_000n, + }, + someBalance, ALITH_ADDRESS, - true + false ); + + console.log("contract address: ", contractAddress); + console.log("asset id: ", registeredAssetId); + + foreignAssetContract = new ethers.Contract(contractAddress, erc20Abi, context.ethers()); }); it({ @@ -51,11 +49,9 @@ describeSuite({ title: "allows to call transferAssetsLocation function", test: async function () { const { abi: xcmInterface } = fetchCompiledContract("XCM"); - const assetBalanceBefore = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceBefore = await foreignAssetContract.balanceOf(ALITH_ADDRESS); + + console.log("BALANCE BEFORE: ", assetBalanceBefore); const dest: [number, any[]] = [1, []]; @@ -84,11 +80,7 @@ describeSuite({ const result = await context.createBlock(rawTxn); expectEVMResult(result.result!.events, "Succeed"); - const assetBalanceAfter = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceAfter = await foreignAssetContract.balanceOf(ALITH_ADDRESS); expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); }, }); @@ -98,14 +90,10 @@ describeSuite({ title: "allows to call transferAssetsToPara20 function", test: async function () { const { abi: xcmInterface } = fetchCompiledContract("XCM"); - const assetBalanceBefore = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceBefore = await foreignAssetContract.balanceOf(ALITH_ADDRESS); const paraId = 1000n; - const assetAddressInfo = [[ADDRESS_ERC20, amountToSend]]; + const assetAddressInfo = [[await foreignAssetContract.getAddress(), amountToSend]]; const rawTxn = await createEthersTransaction(context, { to: PRECOMPILE_PALLET_XCM_ADDRESS, @@ -120,11 +108,7 @@ describeSuite({ const result = await context.createBlock(rawTxn); expectEVMResult(result.result!.events, "Succeed"); - const assetBalanceAfter = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceAfter = await foreignAssetContract.balanceOf(ALITH_ADDRESS); expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); }, }); @@ -134,14 +118,10 @@ describeSuite({ title: "allows to call transferAssetsToPara32 function", test: async function () { const { abi: xcmInterface } = fetchCompiledContract("XCM"); - const assetBalanceBefore = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceBefore = await foreignAssetContract.balanceOf(ALITH_ADDRESS); const paraId = 1000n; - const assetAddressInfo = [[ADDRESS_ERC20, amountToSend]]; + const assetAddressInfo = [[await foreignAssetContract.getAddress(), amountToSend]]; const beneficiaryAddress = "01010101010101010101010101010101"; const rawTxn = await createEthersTransaction(context, { @@ -157,11 +137,7 @@ describeSuite({ const result = await context.createBlock(rawTxn); expectEVMResult(result.result!.events, "Succeed"); - const assetBalanceAfter = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceAfter = await foreignAssetContract.balanceOf(ALITH_ADDRESS); expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); }, }); @@ -171,13 +147,9 @@ describeSuite({ title: "allows to call transferAssetsToRelay function", test: async function () { const { abi: xcmInterface } = fetchCompiledContract("XCM"); - const assetBalanceBefore = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceBefore = await foreignAssetContract.balanceOf(ALITH_ADDRESS); - const assetAddressInfo = [[ADDRESS_ERC20, amountToSend]]; + const assetAddressInfo = [[await foreignAssetContract.getAddress(), amountToSend]]; const beneficiaryAddress = "01010101010101010101010101010101"; const rawTxn = await createEthersTransaction(context, { @@ -193,11 +165,7 @@ describeSuite({ const result = await context.createBlock(rawTxn); expectEVMResult(result.result!.events, "Succeed"); - const assetBalanceAfter = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceAfter = await foreignAssetContract.balanceOf(ALITH_ADDRESS); expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); }, }); @@ -207,11 +175,7 @@ describeSuite({ title: "allows to call transferAssetsUsingTypeAndThenLocation::8425d893 selector", test: async function () { const { abi: xcmInterface } = fetchCompiledContract("XCM"); - const assetBalanceBefore = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceBefore = await foreignAssetContract.balanceOf(ALITH_ADDRESS); const dest: [number, any[]] = [1, []]; const assetLocation: [number, any[]] = [1, []]; @@ -249,11 +213,7 @@ describeSuite({ const result = await context.createBlock(rawTxn); expectEVMResult(result.result!.events, "Succeed"); - const assetBalanceAfter = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceAfter = await foreignAssetContract.balanceOf(ALITH_ADDRESS); expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); }, }); @@ -263,11 +223,7 @@ describeSuite({ title: "allows to call transferAssetsUsingTypeAndThenLocation::fc19376c selector", test: async function () { const { abi: xcmInterface } = fetchCompiledContract("XCM"); - const assetBalanceBefore = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceBefore = await foreignAssetContract.balanceOf(ALITH_ADDRESS); const paraIdInHex = numberToHex(2000, 32); const parachain_enum_selector = "0x00"; @@ -301,11 +257,7 @@ describeSuite({ const result = await context.createBlock(rawTxn); expectEVMResult(result.result!.events, "Succeed"); - const assetBalanceAfter = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceAfter = await foreignAssetContract.balanceOf(ALITH_ADDRESS); expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); }, }); @@ -315,15 +267,11 @@ describeSuite({ title: "allows to call transferAssetsUsingTypeAndThenAddress::998093ee selector", test: async function () { const { abi: xcmInterface } = fetchCompiledContract("XCM"); - const assetBalanceBefore = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceBefore = await foreignAssetContract.balanceOf(ALITH_ADDRESS); // Relay as destination const dest: [number, any[]] = [1, []]; - const assetAddressInfo = [[ADDRESS_ERC20, amountToSend]]; + const assetAddressInfo = [[await foreignAssetContract.getAddress(), amountToSend]]; // DestinationReserve const assetsAndFeesTransferType = 2; @@ -357,11 +305,7 @@ describeSuite({ const result = await context.createBlock(rawTxn); expectEVMResult(result.result!.events, "Succeed"); - const assetBalanceAfter = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceAfter = await foreignAssetContract.balanceOf(ALITH_ADDRESS); expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); }, }); @@ -371,18 +315,14 @@ describeSuite({ title: "allows to call transferAssetsUsingTypeAndThenAddress::aaecfc62 selector", test: async function () { const { abi: xcmInterface } = fetchCompiledContract("XCM"); - const assetBalanceBefore = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceBefore = await foreignAssetContract.balanceOf(ALITH_ADDRESS); const paraIdInHex = numberToHex(2000, 32); const parachain_enum_selector = "0x00"; // This represents X2(Parent, Parachain(2000)) const dest: [number, any[]] = [1, [parachain_enum_selector + paraIdInHex.slice(2)]]; - const assetAddressInfo = [[ADDRESS_ERC20, amountToSend]]; + const assetAddressInfo = [[await foreignAssetContract.getAddress(), amountToSend]]; const remoteReserve: [number, any[]] = [1, []]; const message = { @@ -407,11 +347,7 @@ describeSuite({ const result = await context.createBlock(rawTxn); expectEVMResult(result.result!.events, "Succeed"); - const assetBalanceAfter = ( - await context.polkadotJs().query.assets.account(assetId.toU8a(), ALITH_ADDRESS) - ) - .unwrap() - .balance.toBigInt(); + const assetBalanceAfter = await foreignAssetContract.balanceOf(ALITH_ADDRESS); expect(assetBalanceAfter).to.equal(assetBalanceBefore - amountToSend); }, });