git.delta.rocks / unique-network / refs/commits / 61fc26e2c8d2

difftreelog

test(xcm qtz) added `XcmTestHelper`

PraetorP2023-09-28parent: #dc6f0e2.patch.diff
in: master

5 files changed

modifiedtests/package.jsondiffbeforeafterboth
116 "testXcmUnique": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/xcmUnique.test.ts",116 "testXcmUnique": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/xcmUnique.test.ts",
117 "testFullXcmUnique": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/*Unique.test.ts",117 "testFullXcmUnique": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/*Unique.test.ts",
118 "testXcmQuartz": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/xcmQuartz.test.ts",118 "testXcmQuartz": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/xcmQuartz.test.ts",
119 "testLowLevelXcmQuartz": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/lowLevelXcmQuartz.test.ts",
120 "testFullXcmQuartz": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/*Quartz.test.ts",
119 "testXcmOpal": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/xcmOpal.test.ts",121 "testXcmOpal": "RUN_XCM_TESTS=1 yarn _test ./**/xcm/xcmOpal.test.ts",
120 "testXcmTransferAcala": "yarn _test ./**/xcm/xcmTransferAcala.test.ts acalaId=2000 uniqueId=5000",122 "testXcmTransferAcala": "yarn _test ./**/xcm/xcmTransferAcala.test.ts acalaId=2000 uniqueId=5000",
121 "testXcmTransferStatemine": "yarn _test ./**/xcm/xcmTransferStatemine.test.ts statemineId=1000 uniqueId=5000",123 "testXcmTransferStatemine": "yarn _test ./**/xcm/xcmTransferStatemine.test.ts statemineId=1000 uniqueId=5000",
addedtests/src/xcm/lowLevelXcmQuartz.test.tsdiffbeforeafterboth

no changes

modifiedtests/src/xcm/lowLevelXcmUnique.test.tsdiffbeforeafterboth
20import {Event} from '../util/playgrounds/unique.dev';20import {Event} from '../util/playgrounds/unique.dev';
21import {nToBigInt} from '@polkadot/util';21import {nToBigInt} from '@polkadot/util';
22import {hexToString} from '@polkadot/util';22import {hexToString} from '@polkadot/util';
23import {ASTAR_DECIMALS, NETWORKS, SAFE_XCM_VERSION, UNIQUE_CHAIN, UNQ_DECIMALS, acalaUrl, astarUrl, expectFailedToTransact, expectUntrustedReserveLocationFail, getDevPlayground, mapToChainId, mapToChainUrl, maxWaitBlocks, moonbeamUrl, polkadexUrl, uniqueAssetId, uniqueVersionedMultilocation} from './xcm.types';23import {ASTAR_DECIMALS, NETWORKS, SAFE_XCM_VERSION, UNIQUE_CHAIN, UNQ_DECIMALS, XcmTestHelper, acalaUrl, astarUrl, expectFailedToTransact, expectUntrustedReserveLocationFail, getDevPlayground, mapToChainId, mapToChainUrl, maxWaitBlocks, moonbeamUrl, polkadexUrl, uniqueAssetId, uniqueVersionedMultilocation} from './xcm.types';
2424
2525
26const TRANSFER_AMOUNT = 2000000_000_000_000_000_000_000n;26const TRANSFER_AMOUNT = 2000000_000_000_000_000_000_000n;
34let balanceUniqueTokenFinal: bigint;34let balanceUniqueTokenFinal: bigint;
35let unqFees: bigint;35let unqFees: bigint;
3636
37const testHelper = new XcmTestHelper('unique');
3738
38async function genericSendUnqTo(39async function genericSendUnqTo(
39 networkName: keyof typeof NETWORKS,40 networkName: keyof typeof NETWORKS,
434 });435 });
435436
436 itSub('Should connect and send UNQ to Polkadex', async () => {437 itSub('Should connect and send UNQ to Polkadex', async () => {
437 await genericSendUnqTo('polkadex', randomAccount);438 await testHelper.sendUnqTo('polkadex', randomAccount);
438 });439 });
439440
440441
441 itSub('Should connect to Polkadex and send UNQ back', async () => {442 itSub('Should connect to Polkadex and send UNQ back', async () => {
442 await genericSendUnqBack('polkadex', alice, randomAccount);443 await testHelper.sendUnqBack('polkadex', alice, randomAccount);
443 });444 });
444445
445 itSub('Polkadex can send only up to its balance', async () => {446 itSub('Polkadex can send only up to its balance', async () => {
446 await genericSendOnlyOwnedBalance('polkadex', alice);447 await testHelper.sendOnlyOwnedBalance('polkadex', alice);
447 });448 });
448449
449 itSub('Should not accept reserve transfer of UNQ from Polkadex', async () => {450 itSub('Should not accept reserve transfer of UNQ from Polkadex', async () => {
450 await genericReserveTransferUNQfrom('polkadex', alice);451 await testHelper.reserveTransferUNQfrom('polkadex', alice);
451 });452 });
452});453});
453454
574 });575 });
575576
576 itSub('Should connect and send UNQ to Moonbeam', async () => {577 itSub('Should connect and send UNQ to Moonbeam', async () => {
577 await genericSendUnqTo('moonbeam', randomAccountUnique, randomAccountMoonbeam);578 await testHelper.sendUnqTo('moonbeam', randomAccountUnique, randomAccountMoonbeam);
578 });579 });
579580
580 itSub('Should connect to Moonbeam and send UNQ back', async () => {581 itSub('Should connect to Moonbeam and send UNQ back', async () => {
581 await genericSendUnqBack('moonbeam', alice, randomAccountUnique);582 await testHelper.sendUnqBack('moonbeam', alice, randomAccountUnique);
582 });583 });
583584
584 itSub('Moonbeam can send only up to its balance', async () => {585 itSub('Moonbeam can send only up to its balance', async () => {
585 await genericSendOnlyOwnedBalance('moonbeam', alice);586 await testHelper.sendOnlyOwnedBalance('moonbeam', alice);
586 });587 });
587588
588 itSub('Should not accept reserve transfer of UNQ from Moonbeam', async () => {589 itSub('Should not accept reserve transfer of UNQ from Moonbeam', async () => {
589 await genericReserveTransferUNQfrom('moonbeam', alice);590 await testHelper.reserveTransferUNQfrom('moonbeam', alice);
590 });591 });
591});592});
592593
modifiedtests/src/xcm/xcm.types.tsdiffbeforeafterboth
1import {IKeyringPair} from '@polkadot/types/types';
1import {usingAcalaPlaygrounds, usingAstarPlaygrounds, usingMoonbeamPlaygrounds, usingPolkadexPlaygrounds} from '../util';2import {expect, usingAcalaPlaygrounds, usingAstarPlaygrounds, usingKaruraPlaygrounds, usingMoonbeamPlaygrounds, usingMoonriverPlaygrounds, usingPlaygrounds, usingPolkadexPlaygrounds, usingShidenPlaygrounds} from '../util';
2import {DevUniqueHelper, Event} from '../util/playgrounds/unique.dev';3import {DevUniqueHelper, Event} from '../util/playgrounds/unique.dev';
3import config from '../config';4import config from '../config';
45
9export const ASTAR_CHAIN = +(process.env.RELAY_ASTAR_ID || 2006);10export const ASTAR_CHAIN = +(process.env.RELAY_ASTAR_ID || 2006);
10export const POLKADEX_CHAIN = +(process.env.RELAY_POLKADEX_ID || 2040);11export const POLKADEX_CHAIN = +(process.env.RELAY_POLKADEX_ID || 2040);
12
13export const QUARTZ_CHAIN = +(process.env.RELAY_QUARTZ_ID || 2095);
14export const STATEMINE_CHAIN = +(process.env.RELAY_STATEMINE_ID || 1000);
15export const KARURA_CHAIN = +(process.env.RELAY_KARURA_ID || 2000);
16export const MOONRIVER_CHAIN = +(process.env.RELAY_MOONRIVER_ID || 2023);
17export const SHIDEN_CHAIN = +(process.env.RELAY_SHIDEN_ID || 2007);
18
19export const relayUrl = config.relayUrl;
20export const statemintUrl = config.statemintUrl;
21export const statemineUrl = config.statemineUrl;
1122
12export const acalaUrl = config.acalaUrl;23export const acalaUrl = config.acalaUrl;
13export const moonbeamUrl = config.moonbeamUrl;24export const moonbeamUrl = config.moonbeamUrl;
14export const astarUrl = config.astarUrl;25export const astarUrl = config.astarUrl;
15export const polkadexUrl = config.polkadexUrl;26export const polkadexUrl = config.polkadexUrl;
27
28export const karuraUrl = config.karuraUrl;
29export const moonriverUrl = config.moonriverUrl;
30export const shidenUrl = config.shidenUrl;
1631
17export const SAFE_XCM_VERSION = 3;32export const SAFE_XCM_VERSION = 3;
33
1834
19export const maxWaitBlocks = 6;35export const RELAY_DECIMALS = 12;
2036export const STATEMINE_DECIMALS = 12;
37export const KARURA_DECIMALS = 12;
38export const SHIDEN_DECIMALS = 18n;
39export const QTZ_DECIMALS = 18n;
2140
22export const ASTAR_DECIMALS = 18n;41export const ASTAR_DECIMALS = 18n;
23export const UNQ_DECIMALS = 18n;42export const UNQ_DECIMALS = 18n;
43
44export const maxWaitBlocks = 6;
2445
25export const uniqueMultilocation = {46export const uniqueMultilocation = {
26 parents: 1,47 parents: 1,
52 astar: usingAstarPlaygrounds,73 astar: usingAstarPlaygrounds,
53 polkadex: usingPolkadexPlaygrounds,74 polkadex: usingPolkadexPlaygrounds,
54 moonbeam: usingMoonbeamPlaygrounds,75 moonbeam: usingMoonbeamPlaygrounds,
76 moonriver: usingMoonriverPlaygrounds,
77 karura: usingKaruraPlaygrounds,
78 shiden: usingShidenPlaygrounds,
55} as const;79} as const;
80type NetworkNames = keyof typeof NETWORKS;
81
82type NativeRuntime = 'opal' | 'quartz' | 'unique';
5683
57export function mapToChainId(networkName: keyof typeof NETWORKS) {84export function mapToChainId(networkName: keyof typeof NETWORKS): number {
58 switch (networkName) {85 switch (networkName) {
59 case 'acala':86 case 'acala':
60 return ACALA_CHAIN;87 return ACALA_CHAIN;
64 return MOONBEAM_CHAIN;91 return MOONBEAM_CHAIN;
65 case 'polkadex':92 case 'polkadex':
66 return POLKADEX_CHAIN;93 return POLKADEX_CHAIN;
94 case 'moonriver':
95 return MOONRIVER_CHAIN;
96 case 'karura':
97 return KARURA_CHAIN;
98 case 'shiden':
99 return SHIDEN_CHAIN;
67 }100 }
68}101}
69102
70export function mapToChainUrl(networkName: keyof typeof NETWORKS): string {103export function mapToChainUrl(networkName: NetworkNames): string {
71 switch (networkName) {104 switch (networkName) {
72 case 'acala':105 case 'acala':
73 return acalaUrl;106 return acalaUrl;
77 return moonbeamUrl;110 return moonbeamUrl;
78 case 'polkadex':111 case 'polkadex':
79 return polkadexUrl;112 return polkadexUrl;
113 case 'moonriver':
114 return moonriverUrl;
115 case 'karura':
116 return karuraUrl;
117 case 'shiden':
118 return shidenUrl;
80 }119 }
81}120}
121
122export function getDevPlayground(name: NetworkNames) {
123 return NETWORKS[name];
124}
125
126export const TRANSFER_AMOUNT = 2000000_000_000_000_000_000_000n;
127const SENDER_BUDGET = 2n * TRANSFER_AMOUNT;
128const SENDBACK_AMOUNT = TRANSFER_AMOUNT / 2n;
129const STAYED_ON_TARGET_CHAIN = TRANSFER_AMOUNT - SENDBACK_AMOUNT;
130const TARGET_CHAIN_TOKEN_TRANSFER_AMOUNT = 100_000_000_000n;
82131
83export function getDevPlayground<T extends keyof typeof NETWORKS>(name: T) {132export class XcmTestHelper {
133 private _balanceUniqueTokenInit: bigint = 0n;
134 private _balanceUniqueTokenMiddle: bigint = 0n;
135 private _balanceUniqueTokenFinal: bigint = 0n;
136 private _unqFees: bigint = 0n;
137 private _nativeRuntime: NativeRuntime;
138
139 constructor(runtime: NativeRuntime) {
140 this._nativeRuntime = runtime;
141 }
142
143 private _getNativeId() {
144 switch (this._nativeRuntime) {
145 case 'opal':
146 // To-Do
147 return 10;
148 case 'quartz':
149 return QUARTZ_CHAIN;
150 case 'unique':
151 return UNIQUE_CHAIN;
152 }
153 }
154 private _isAddress20FormatFor(network: NetworkNames) {
155 switch (network) {
156 case 'moonbeam':
157 case 'moonriver':
158 return true;
159 default:
160 return false;
161 }
162 }
163
164 async sendUnqTo(
165 networkName: keyof typeof NETWORKS,
166 randomAccount: IKeyringPair,
167 randomAccountOnTargetChain = randomAccount,
168 ) {
169 const networkUrl = mapToChainUrl(networkName);
170 const targetPlayground = getDevPlayground(networkName);
171 await usingPlaygrounds(async (helper) => {
172 this._balanceUniqueTokenInit = await helper.balance.getSubstrate(randomAccount.address);
173 const destination = {
174 V2: {
175 parents: 1,
176 interior: {
177 X1: {
178 Parachain: mapToChainId(networkName),
179 },
180 },
181 },
182 };
183
184 const beneficiary = {
185 V2: {
186 parents: 0,
187 interior: {
188 X1: (
189 this._isAddress20FormatFor(networkName) ?
190 {
191 AccountKey20: {
192 network: 'Any',
193 key: randomAccountOnTargetChain.address,
194 },
195 }
196 :
197 {
198 AccountId32: {
199 network: 'Any',
200 id: randomAccountOnTargetChain.addressRaw,
201 },
202 }
203 ),
204 },
205 },
206 };
207
208 const assets = {
209 V2: [
210 {
211 id: {
212 Concrete: {
213 parents: 0,
214 interior: 'Here',
215 },
216 },
217 fun: {
218 Fungible: TRANSFER_AMOUNT,
219 },
220 },
221 ],
222 };
223 const feeAssetItem = 0;
224
225 await helper.xcm.limitedReserveTransferAssets(randomAccount, destination, beneficiary, assets, feeAssetItem, 'Unlimited');
226 const messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
227 this._balanceUniqueTokenMiddle = await helper.balance.getSubstrate(randomAccount.address);
228
229 this._unqFees = this._balanceUniqueTokenInit - this._balanceUniqueTokenMiddle - TRANSFER_AMOUNT;
230 console.log('[Unique -> %s] transaction fees on Unique: %s UNQ', networkName, helper.util.bigIntToDecimals(this._unqFees));
231 expect(this._unqFees > 0n, 'Negative fees UNQ, looks like nothing was transferred').to.be.true;
232
233 await targetPlayground(networkUrl, async (helper) => {
234 /*
235 Since only the parachain part of the Polkadex
236 infrastructure is launched (without their
237 solochain validators), processing incoming
238 assets will lead to an error.
239 This error indicates that the Polkadex chain
240 received a message from the Unique network,
241 since the hash is being checked to ensure
242 it matches what was sent.
243 */
244 if(networkName == 'polkadex') {
245 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Fail, event => event.messageHash == messageSent.messageHash);
246 } else {
247 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Success, event => event.messageHash == messageSent.messageHash);
248 }
249 });
250
251 });
252 }
253
254 async sendUnqBack(
255 networkName: keyof typeof NETWORKS,
256 sudoer: IKeyringPair,
257 randomAccountOnUnq: IKeyringPair,
258 ) {
259 const networkUrl = mapToChainUrl(networkName);
260
261 const targetPlayground = getDevPlayground(networkName);
262 await usingPlaygrounds(async (helper) => {
263
264 const xcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
265 randomAccountOnUnq.addressRaw,
266 {
267 Concrete: {
268 parents: 1,
269 interior: {
270 X1: {Parachain: this._getNativeId()},
271 },
272 },
273 },
274 SENDBACK_AMOUNT,
275 );
276
277 let xcmProgramSent: any;
278
279
280 await targetPlayground(networkUrl, async (helper) => {
281 if('getSudo' in helper) {
282 await helper.getSudo().xcm.send(sudoer, uniqueVersionedMultilocation, xcmProgram);
283 xcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
284 } else if('fastDemocracy' in helper) {
285 const xcmSend = helper.constructApiCall('api.tx.polkadotXcm.send', [uniqueVersionedMultilocation, xcmProgram]);
286 // Needed to bypass the call filter.
287 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
288 await helper.fastDemocracy.executeProposal(`sending ${networkName} -> Unique via XCM program`, batchCall);
289 xcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
290 }
291 });
292
293 await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.Success, event => event.messageHash == xcmProgramSent.messageHash);
294
295 this._balanceUniqueTokenFinal = await helper.balance.getSubstrate(randomAccountOnUnq.address);
296
297 expect(this._balanceUniqueTokenFinal).to.be.equal(this._balanceUniqueTokenInit - this._unqFees - STAYED_ON_TARGET_CHAIN);
298
299 });
300 }
301
302 async sendOnlyOwnedBalance(
303 networkName: keyof typeof NETWORKS,
304 sudoer: IKeyringPair,
305 ) {
306 const networkUrl = mapToChainUrl(networkName);
307 const targetPlayground = getDevPlayground(networkName);
308
309 const targetChainBalance = 10000n * (10n ** UNQ_DECIMALS);
310
311 await usingPlaygrounds(async (helper) => {
312 const targetChainSovereignAccount = helper.address.paraSiblingSovereignAccount(mapToChainId(networkName));
313 await helper.getSudo().balance.setBalanceSubstrate(sudoer, targetChainSovereignAccount, targetChainBalance);
314 const moreThanTargetChainHas = 2n * targetChainBalance;
315
316 const targetAccount = helper.arrange.createEmptyAccount();
317
318 const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
319 targetAccount.addressRaw,
320 {
321 Concrete: {
322 parents: 0,
323 interior: 'Here',
324 },
325 },
326 moreThanTargetChainHas,
327 );
328
329 let maliciousXcmProgramSent: any;
330
331
332 await targetPlayground(networkUrl, async (helper) => {
333 if('getSudo' in helper) {
334 await helper.getSudo().xcm.send(sudoer, uniqueVersionedMultilocation, maliciousXcmProgram);
335 maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
336 } else if('fastDemocracy' in helper) {
337 const xcmSend = helper.constructApiCall('api.tx.polkadotXcm.send', [uniqueVersionedMultilocation, maliciousXcmProgram]);
338 // Needed to bypass the call filter.
84 return NETWORKS[name];339 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
340 await helper.fastDemocracy.executeProposal(`sending ${networkName} -> Unique via XCM program`, batchCall);
341 maliciousXcmProgramSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
342 }
343 });
344
345 await expectFailedToTransact(helper, maliciousXcmProgramSent);
346
347 const targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
348 expect(targetAccountBalance).to.be.equal(0n);
349 });
85}350 }
351
352 async reserveTransferUNQfrom(netwokrName: keyof typeof NETWORKS, sudoer: IKeyringPair) {
353 const networkUrl = mapToChainUrl(netwokrName);
354 const targetPlayground = getDevPlayground(netwokrName);
355
356 await usingPlaygrounds(async (helper) => {
357 const testAmount = 10_000n * (10n ** UNQ_DECIMALS);
358 const targetAccount = helper.arrange.createEmptyAccount();
359
360 const maliciousXcmProgramFullId = helper.arrange.makeXcmProgramReserveAssetDeposited(
361 targetAccount.addressRaw,
362 {
363 Concrete: {
364 parents: 1,
365 interior: {
366 X1: {
367 Parachain: this._getNativeId(),
368 },
369 },
370 },
371 },
372 testAmount,
373 );
374
375 const maliciousXcmProgramHereId = helper.arrange.makeXcmProgramReserveAssetDeposited(
376 targetAccount.addressRaw,
377 {
378 Concrete: {
379 parents: 0,
380 interior: 'Here',
381 },
382 },
383 testAmount,
384 );
385
386 let maliciousXcmProgramFullIdSent: any;
387 let maliciousXcmProgramHereIdSent: any;
388 const maxWaitBlocks = 3;
389
390 // Try to trick Unique using full UNQ identification
391 await targetPlayground(networkUrl, async (helper) => {
392 if('getSudo' in helper) {
393 await helper.getSudo().xcm.send(sudoer, uniqueVersionedMultilocation, maliciousXcmProgramFullId);
394 maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
395 }
396 // Moonbeam case
397 else if('fastDemocracy' in helper) {
398 const xcmSend = helper.constructApiCall('api.tx.polkadotXcm.send', [uniqueVersionedMultilocation, maliciousXcmProgramFullId]);
399 // Needed to bypass the call filter.
400 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
401 await helper.fastDemocracy.executeProposal(`${netwokrName} try to act like a reserve location for UNQ using path asset identification`,batchCall);
402
403 maliciousXcmProgramFullIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
404 }
405 });
406
407
408 await expectUntrustedReserveLocationFail(helper, maliciousXcmProgramFullIdSent);
409
410 let accountBalance = await helper.balance.getSubstrate(targetAccount.address);
411 expect(accountBalance).to.be.equal(0n);
412
413 // Try to trick Unique using shortened UNQ identification
414 await targetPlayground(networkUrl, async (helper) => {
415 if('getSudo' in helper) {
416 await helper.getSudo().xcm.send(sudoer, uniqueVersionedMultilocation, maliciousXcmProgramHereId);
417 maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
418 }
419 else if('fastDemocracy' in helper) {
420 const xcmSend = helper.constructApiCall('api.tx.polkadotXcm.send', [uniqueVersionedMultilocation, maliciousXcmProgramHereId]);
421 // Needed to bypass the call filter.
422 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
423 await helper.fastDemocracy.executeProposal(`${netwokrName} try to act like a reserve location for UNQ using "here" asset identification`, batchCall);
424
425 maliciousXcmProgramHereIdSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
426 }
427 });
428
429 await expectUntrustedReserveLocationFail(helper, maliciousXcmProgramHereIdSent);
430
431 accountBalance = await helper.balance.getSubstrate(targetAccount.address);
432 expect(accountBalance).to.be.equal(0n);
433 });
434 }
435
436 async rejectNativeTokensFrom(networkName: keyof typeof NETWORKS, sudoerOnTargetChain: IKeyringPair) {
437 const networkUrl = mapToChainUrl(networkName);
438 const targetPlayground = getDevPlayground(networkName);
439 let messageSent: any;
440
441 await usingPlaygrounds(async (helper) => {
442 const maliciousXcmProgramFullId = helper.arrange.makeXcmProgramReserveAssetDeposited(
443 helper.arrange.createEmptyAccount().addressRaw,
444 {
445 Concrete: {
446 parents: 1,
447 interior: {
448 X1: {
449 Parachain: mapToChainId(networkName),
450 },
451 },
452 },
453 },
454 TARGET_CHAIN_TOKEN_TRANSFER_AMOUNT,
455 );
456 await targetPlayground(networkUrl, async (helper) => {
457 if('getSudo' in helper) {
458 await helper.getSudo().xcm.send(sudoerOnTargetChain, uniqueVersionedMultilocation, maliciousXcmProgramFullId);
459 messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
460 } else if('fastDemocracy' in helper) {
461 const xcmSend = helper.constructApiCall('api.tx.polkadotXcm.send', [uniqueVersionedMultilocation, maliciousXcmProgramFullId]);
462 // Needed to bypass the call filter.
463 const batchCall = helper.encodeApiCall('api.tx.utility.batch', [[xcmSend]]);
464 await helper.fastDemocracy.executeProposal(`${networkName} sending native tokens to the Unique via fast democracy`, batchCall);
465
466 messageSent = await helper.wait.expectEvent(maxWaitBlocks, Event.XcmpQueue.XcmpMessageSent);
467 }
468 });
469 await expectFailedToTransact(helper, messageSent);
470 });
471 }
472
473}
modifiedtests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';
18import config from '../config';
19import {itSub, expect, describeXCM, usingPlaygrounds, usingKaruraPlaygrounds, usingRelayPlaygrounds, usingMoonriverPlaygrounds, usingStateminePlaygrounds, usingShidenPlaygrounds} from '../util';18import {itSub, expect, describeXCM, usingPlaygrounds, usingKaruraPlaygrounds, usingRelayPlaygrounds, usingMoonriverPlaygrounds, usingStateminePlaygrounds, usingShidenPlaygrounds} from '../util';
20import {DevUniqueHelper, Event} from '../util/playgrounds/unique.dev';19import {DevUniqueHelper, Event} from '../util/playgrounds/unique.dev';
21
22const QUARTZ_CHAIN = +(process.env.RELAY_QUARTZ_ID || 2095);20import {STATEMINE_CHAIN, QUARTZ_CHAIN, KARURA_CHAIN, MOONRIVER_CHAIN, SHIDEN_CHAIN, STATEMINE_DECIMALS, KARURA_DECIMALS, QTZ_DECIMALS, RELAY_DECIMALS, SHIDEN_DECIMALS, karuraUrl, moonriverUrl, relayUrl, shidenUrl, statemineUrl} from './xcm.types';
23const STATEMINE_CHAIN = +(process.env.RELAY_STATEMINE_ID || 1000);21
24const KARURA_CHAIN = +(process.env.RELAY_KARURA_ID || 2000);22
25const MOONRIVER_CHAIN = +(process.env.RELAY_MOONRIVER_ID || 2023);
26const SHIDEN_CHAIN = +(process.env.RELAY_SHIDEN_ID || 2007);
2723
28const STATEMINE_PALLET_INSTANCE = 50;24const STATEMINE_PALLET_INSTANCE = 50;
29
30const relayUrl = config.relayUrl;
31const statemineUrl = config.statemineUrl;
32const karuraUrl = config.karuraUrl;
33const moonriverUrl = config.moonriverUrl;
34const shidenUrl = config.shidenUrl;
35
36const RELAY_DECIMALS = 12;
37const STATEMINE_DECIMALS = 12;
38const KARURA_DECIMALS = 12;
39const SHIDEN_DECIMALS = 18n;
40const QTZ_DECIMALS = 18n;
4125
42const TRANSFER_AMOUNT = 2000000000000000000000000n;26const TRANSFER_AMOUNT = 2000000000000000000000000n;
4327