git.delta.rocks / unique-network / refs/commits / 1b19b1f3b608

difftreelog

test untrusted reserve locations

Daniel Shiposha2023-04-12parent: #abe0498.patch.diff
in: master

4 files changed

modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -421,18 +421,13 @@
     return capture;
   }
 
-  makeXcmProgramWithdrawDeposit(beneficiary: Uint8Array, amount: bigint | string) {
+  makeXcmProgramWithdrawDeposit(beneficiary: Uint8Array, id: any, amount: bigint | string) {
     return {
       V2: [
         {
           WithdrawAsset: [
             {
-              id: {
-                Concrete: {
-                  parents: 0,
-                  interior: 'Here',
-                },
-              },
+              id,
               fun: {
                 Fungible: amount,
               },
@@ -442,12 +437,54 @@
         {
           BuyExecution: {
             fees: {
-              id: {
-                Concrete: {
-                  parents: 0,
-                  interior: 'Here',
+              id,
+              fun: {
+                Fungible: amount,
+              },
+            },
+            weightLimit: 'Unlimited'
+          },
+        },
+        {
+          DepositAsset: {
+            assets: {
+              Wild: 'All'
+            },
+            maxAssets: 1,
+            beneficiary: {
+              parents: 0,
+              interior: {
+                X1: {
+                  AccountId32: {
+                    network: 'Any',
+                    id: beneficiary
+                  },
                 },
               },
+            },
+          },
+        },
+      ],
+    };
+  }
+
+  makeXcmProgramReserveAssetDeposited(beneficiary: Uint8Array, id: any, amount: bigint | string) {
+    return {
+      V2: [
+        {
+          ReserveAssetDeposited: [
+            {
+              id,
+              fun: {
+                Fungible: amount,
+              },
+            },
+          ],
+        },
+        {
+          BuyExecution: {
+            fees: {
+              id,
               fun: {
                 Fungible: amount,
               },
@@ -472,7 +509,7 @@
                 },
               },
             },
-          }
+          },
         },
       ],
     };
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -3021,6 +3021,18 @@
 
     await this.teleportAssets(signer, destination, beneficiary, assets, feeAssetItem);
   }
+
+  async send(signer: IKeyringPair, destination: any, message: any) {
+    await this.helper.executeExtrinsic(
+      signer,
+      `api.tx.${this.palletName}.send`,
+      [
+        destination,
+        message,
+      ],
+      true,
+    ); 
+  }
 }
 
 class XTokensGroup<T extends ChainHelperBase> extends HelperGroup<T> {
@@ -3284,6 +3296,7 @@
   assetRegistry: AcalaAssetRegistryGroup;
   xTokens: XTokensGroup<AcalaHelper>;
   tokens: TokensGroup<AcalaHelper>;
+  xcm: XcmGroup<AcalaHelper>;
 
   constructor(logger?: ILogger, options: {[key: string]: any} = {}) {
     super(logger, options.helperBase ?? AcalaHelper);
@@ -3292,6 +3305,7 @@
     this.assetRegistry = new AcalaAssetRegistryGroup(this);
     this.xTokens = new XTokensGroup(this);
     this.tokens = new TokensGroup(this);
+    this.xcm = new XcmGroup(this, 'polkadotXcm');
   }
 
   getSudo<T extends AcalaHelper>() {
modifiedtests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth
--- a/tests/src/xcm/xcmQuartz.test.ts
+++ b/tests/src/xcm/xcmQuartz.test.ts
@@ -663,19 +663,20 @@
       },
     };
 
-    const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, moreThanKaruraHas);
+    const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 0,
+          interior: 'Here',
+        },
+      },
+      moreThanKaruraHas,
+    );
 
     // Try to trick Quartz
     await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
-      await helper.getSudo().executeExtrinsic(
-        alice,
-        'api.tx.polkadotXcm.send',
-        [
-          quartzMultilocation,
-          maliciousXcmProgram,
-        ],
-        true,
-      );
+      await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);
     });
 
     const maxWaitBlocks = 3;
@@ -701,18 +702,19 @@
 
     // But Karura still can send the correct amount
     const validTransferAmount = karuraBalance / 2n;
-    const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);
+    const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 0,
+          interior: 'Here',
+        },
+      },
+      validTransferAmount,
+    );
 
     await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
-      await helper.getSudo().executeExtrinsic(
-        alice,
-        'api.tx.polkadotXcm.send',
-        [
-          quartzMultilocation,
-          validXcmProgram,
-        ],
-        true,
-      );
+      await helper.getSudo().xcm.send(alice, quartzMultilocation, validXcmProgram);
     });
 
     await helper.wait.newBlocks(maxWaitBlocks);
@@ -720,6 +722,62 @@
     targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
     expect(targetAccountBalance).to.be.equal(validTransferAmount);
   });
+
+  itSub('Should not accept reserve transfer of QTZ from Karura', async ({helper}) => {
+    const testAmount = 10_000n * (10n ** QTZ_DECIMALS);
+    const [targetAccount] = await helper.arrange.createAccounts([0n], alice);
+
+    const quartzMultilocation = {
+      V1: {
+        parents: 1,
+        interior: {
+          X1: {
+            Parachain: QUARTZ_CHAIN,
+          },
+        },
+      },
+    };
+
+    const maliciousXcmProgram = helper.arrange.makeXcmProgramReserveAssetDeposited(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 1,
+          interior: {
+            X1: {
+              Parachain: QUARTZ_CHAIN,
+            },
+          },
+        },
+      },
+      testAmount,
+    );
+
+    await usingKaruraPlaygrounds(karuraUrl, async (helper) => {
+      await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);
+    });
+
+    const maxWaitBlocks = 3;
+
+    const xcmpQueueFailEvent = await helper.wait.eventOutcome<XcmV2TraitsError>(
+      maxWaitBlocks,
+      'xcmpQueue',
+      'Fail',
+    );
+
+    expect(
+      xcmpQueueFailEvent != null,
+      `'xcmpQueue.FailEvent' event is expected`,
+    ).to.be.true;
+
+    expect(
+      xcmpQueueFailEvent!.isUntrustedReserveLocation,
+      `The XCM error should be 'isUntrustedReserveLocation'`,
+    ).to.be.true;
+
+    const accountBalance = await helper.balance.getSubstrate(targetAccount.address);
+    expect(accountBalance).to.be.equal(0n);
+  });
 });
 
 // These tests are relevant only when
@@ -1142,6 +1200,10 @@
   itSub.skip('Moonriver can send only up to its balance', async ({helper}) => {
     throw Error("Not yet implemented");
   });
+
+  itSub.skip('Should not accept reserve transfer of QTZ from Moonriver', async ({helper}) => {
+    throw Error("Not yet implemented");
+  });
 });
 
 describeXCM('[XCM] Integration test: Exchanging tokens with Shiden', () => {
@@ -1375,19 +1437,20 @@
       },
     };
 
-    const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, moreThanShidenHas);
+    const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 0,
+          interior: 'Here',
+        },
+      },
+      moreThanShidenHas,
+    );
 
     // Try to trick Quartz
     await usingShidenPlaygrounds(shidenUrl, async (helper) => {
-      await helper.getSudo().executeExtrinsic(
-        alice,
-        'api.tx.polkadotXcm.send',
-        [
-          quartzMultilocation,
-          maliciousXcmProgram,
-        ],
-        true,
-      );
+      await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);
     });
 
     const maxWaitBlocks = 3;
@@ -1413,18 +1476,19 @@
 
     // But Shiden still can send the correct amount
     const validTransferAmount = shidenBalance / 2n;
-    const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);
+    const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 0,
+          interior: 'Here',
+        },
+      },
+      validTransferAmount,
+    );
 
     await usingShidenPlaygrounds(shidenUrl, async (helper) => {
-      await helper.getSudo().executeExtrinsic(
-        alice,
-        'api.tx.polkadotXcm.send',
-        [
-          quartzMultilocation,
-          validXcmProgram,
-        ],
-        true,
-      );
+      await helper.getSudo().xcm.send(alice, quartzMultilocation, validXcmProgram);
     });
 
     await helper.wait.newBlocks(maxWaitBlocks);
@@ -1432,4 +1496,60 @@
     targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
     expect(targetAccountBalance).to.be.equal(validTransferAmount);
   });
+
+  itSub('Should not accept reserve transfer of QTZ from Shiden', async ({helper}) => {
+    const testAmount = 10_000n * (10n ** QTZ_DECIMALS);
+    const [targetAccount] = await helper.arrange.createAccounts([0n], alice);
+
+    const quartzMultilocation = {
+      V1: {
+        parents: 1,
+        interior: {
+          X1: {
+            Parachain: QUARTZ_CHAIN,
+          },
+        },
+      },
+    };
+
+    const maliciousXcmProgram = helper.arrange.makeXcmProgramReserveAssetDeposited(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 1,
+          interior: {
+            X1: {
+              Parachain: QUARTZ_CHAIN,
+            },
+          },
+        },
+      },
+      testAmount,
+    );
+
+    await usingShidenPlaygrounds(shidenUrl, async (helper) => {
+      await helper.getSudo().xcm.send(alice, quartzMultilocation, maliciousXcmProgram);
+    });
+
+    const maxWaitBlocks = 3;
+
+    const xcmpQueueFailEvent = await helper.wait.eventOutcome<XcmV2TraitsError>(
+      maxWaitBlocks,
+      'xcmpQueue',
+      'Fail',
+    );
+
+    expect(
+      xcmpQueueFailEvent != null,
+      `'xcmpQueue.FailEvent' event is expected`,
+    ).to.be.true;
+
+    expect(
+      xcmpQueueFailEvent!.isUntrustedReserveLocation,
+      `The XCM error should be 'isUntrustedReserveLocation'`,
+    ).to.be.true;
+
+    const accountBalance = await helper.balance.getSubstrate(targetAccount.address);
+    expect(accountBalance).to.be.equal(0n);
+  });
 });
modifiedtests/src/xcm/xcmUnique.test.tsdiffbeforeafterboth
667667
668 const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, moreThanAcalaHas);668 const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
669 targetAccount.addressRaw,
670 {
671 Concrete: {
672 parents: 0,
673 interior: 'Here',
674 },
675 },
676 moreThanAcalaHas,
677 );
669678
670 // Try to trick Unique679 // Try to trick Unique
671 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {680 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
672 await helper.getSudo().executeExtrinsic(681 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
673 alice,
674 'api.tx.polkadotXcm.send',
675 [
676 uniqueMultilocation,
677 maliciousXcmProgram,
678 ],
679 true,
680 );
681 });682 });
682683
705 const validTransferAmount = acalaBalance / 2n;706 const validTransferAmount = acalaBalance / 2n;
706 const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);707 const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
708 targetAccount.addressRaw,
709 {
710 Concrete: {
711 parents: 0,
712 interior: 'Here',
713 },
714 },
715 validTransferAmount,
716 );
707717
708 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {718 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
709 await helper.getSudo().executeExtrinsic(719 await helper.getSudo().xcm.send(alice, uniqueMultilocation, validXcmProgram);
710 alice,
711 'api.tx.polkadotXcm.send',
712 [
723 expect(targetAccountBalance).to.be.equal(validTransferAmount);725 expect(targetAccountBalance).to.be.equal(validTransferAmount);
724 });726 });
727
728 itSub('Should not accept reserve transfer of UNQ from Acala', async ({helper}) => {
729 const testAmount = 10_000n * (10n ** UNQ_DECIMALS);
730 const [targetAccount] = await helper.arrange.createAccounts([0n], alice);
731
732 const uniqueMultilocation = {
733 V1: {
734 parents: 1,
735 interior: {
736 X1: {
737 Parachain: UNIQUE_CHAIN,
738 },
739 },
740 },
741 };
742
743 const maliciousXcmProgram = helper.arrange.makeXcmProgramReserveAssetDeposited(
744 targetAccount.addressRaw,
745 {
746 Concrete: {
747 parents: 1,
748 interior: {
749 X1: {
750 Parachain: UNIQUE_CHAIN,
751 },
752 },
753 },
754 },
755 testAmount,
756 );
757
758 await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
759 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
760 });
761
762 const maxWaitBlocks = 3;
763
764 const xcmpQueueFailEvent = await helper.wait.eventOutcome<XcmV2TraitsError>(
765 maxWaitBlocks,
766 'xcmpQueue',
767 'Fail',
768 );
769
770 expect(
771 xcmpQueueFailEvent != null,
772 `'xcmpQueue.FailEvent' event is expected`,
773 ).to.be.true;
774
775 expect(
776 xcmpQueueFailEvent!.isUntrustedReserveLocation,
777 `The XCM error should be 'isUntrustedReserveLocation'`,
778 ).to.be.true;
779
780 const accountBalance = await helper.balance.getSubstrate(targetAccount.address);
781 expect(accountBalance).to.be.equal(0n);
782 });
725});783});
726784
727// These tests are relevant only when785// These tests are relevant only when
1146 throw Error("Not yet implemented");1204 throw Error("Not yet implemented");
1147 });1205 });
1206
1207 itSub.skip('Should not accept reserve transfer of UNQ from Moonbeam', async ({helper}) => {
1208 throw Error("Not yet implemented");
1209 });
1148});1210});
11491211
1150describeXCM('[XCM] Integration test: Exchanging tokens with Astar', () => {1212describeXCM('[XCM] Integration test: Exchanging tokens with Astar', () => {
1357 expect(balanceUNQ).to.eq(balanceAfterUniqueToAstarXCM + unqFromAstarTransfered);1419 expect(balanceUNQ).to.eq(balanceAfterUniqueToAstarXCM + unqFromAstarTransfered);
1358 });1420 });
1359
1360 itSub.skip('Should not accept limitedReserveTransfer of UNQ from ASTAR', async ({helper}) => {
1361 await usingAstarPlaygrounds(astarUrl, async (helper) => {
1362 const destination = {
1363 V1: {
1364 parents: 1,
1365 interior: {
1366 X1: {
1367 Parachain: UNIQUE_CHAIN,
1368 },
1369 },
1370 },
1371 };
1372
1373 const beneficiary = {
1374 V1: {
1375 parents: 0,
1376 interior: {
1377 X1: {
1378 AccountId32: {
1379 network: 'Any',
1380 id: randomAccount.addressRaw,
1381 },
1382 },
1383 },
1384 },
1385 };
1386
1387 const assets = {
1388 V1: [
1389 {
1390 id: {
1391 Concrete: {
1392 parents: 1,
1393 interior: {
1394 X1: {
1395 Parachain: UNIQUE_CHAIN,
1396 },
1397 },
1398 },
1399 },
1400 fun: {
1401 Fungible: unqFromAstarTransfered,
1402 },
1403 },
1404 ],
1405 };
1406
1407 // Initial balance is 1 ASTAR
1408 expect(await helper.balance.getSubstrate(randomAccount.address)).to.eq(astarInitialBalance);
1409
1410 const feeAssetItem = 0;
1411 // TODO: expect rejected:
1412 await helper.xcm.limitedReserveTransferAssets(randomAccount, destination, beneficiary, assets, feeAssetItem, 'Unlimited');
1413 });
1414 });
14151421
1416 itSub('Astar can send only up to its balance', async ({helper}) => {1422 itSub('Astar can send only up to its balance', async ({helper}) => {
1417 // set Astar's sovereign account's balance1423 // set Astar's sovereign account's balance
14351441
1436 const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, moreThanShidenHas);1442 const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
1443 targetAccount.addressRaw,
1444 {
1445 Concrete: {
1446 parents: 0,
1447 interior: 'Here',
1448 },
1449 },
1450 moreThanShidenHas,
1451 );
14371452
1438 // Try to trick Unique1453 // Try to trick Unique
1439 await usingAstarPlaygrounds(astarUrl, async (helper) => {1454 await usingAstarPlaygrounds(astarUrl, async (helper) => {
1440 await helper.getSudo().executeExtrinsic(1455 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
1441 alice,
1442 'api.tx.polkadotXcm.send',
1443 [
1444 uniqueMultilocation,
1445 maliciousXcmProgram,
1446 ],
1447 true,
1448 );
1449 });1456 });
14501457
1473 const validTransferAmount = astarBalance / 2n;1480 const validTransferAmount = astarBalance / 2n;
1474 const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);1481 const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
1482 targetAccount.addressRaw,
1483 {
1484 Concrete: {
1485 parents: 0,
1486 interior: 'Here',
1487 },
1488 },
1489 validTransferAmount,
1490 );
14751491
1476 await usingAstarPlaygrounds(astarUrl, async (helper) => {1492 await usingAstarPlaygrounds(astarUrl, async (helper) => {
1477 await helper.getSudo().executeExtrinsic(1493 await helper.getSudo().xcm.send(alice, uniqueMultilocation, validXcmProgram);
1478 alice,
1479 'api.tx.polkadotXcm.send',
1480 [
1481 uniqueMultilocation,
1482 validXcmProgram,
1483 ],
1484 true,
1485 );
1486 });1494 });
14871495
1491 expect(targetAccountBalance).to.be.equal(validTransferAmount);1499 expect(targetAccountBalance).to.be.equal(validTransferAmount);
1492 });1500 });
1501
1502 itSub('Should not accept reserve transfer of UNQ from Astar', async ({helper}) => {
1503 const testAmount = 10_000n * (10n ** UNQ_DECIMALS);
1504 const [targetAccount] = await helper.arrange.createAccounts([0n], alice);
1505
1506 const uniqueMultilocation = {
1507 V1: {
1508 parents: 1,
1509 interior: {
1510 X1: {
1511 Parachain: UNIQUE_CHAIN,
1512 },
1513 },
1514 },
1515 };
1516
1517 const maliciousXcmProgram = helper.arrange.makeXcmProgramReserveAssetDeposited(
1518 targetAccount.addressRaw,
1519 {
1520 Concrete: {
1521 parents: 1,
1522 interior: {
1523 X1: {
1524 Parachain: UNIQUE_CHAIN,
1525 },
1526 },
1527 },
1528 },
1529 testAmount,
1530 );
1531
1532 await usingAstarPlaygrounds(astarUrl, async (helper) => {
1533 await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
1534 });
1535
1536 const maxWaitBlocks = 3;
1537
1538 const xcmpQueueFailEvent = await helper.wait.eventOutcome<XcmV2TraitsError>(
1539 maxWaitBlocks,
1540 'xcmpQueue',
1541 'Fail',
1542 );
1543
1544 expect(
1545 xcmpQueueFailEvent != null,
1546 `'xcmpQueue.FailEvent' event is expected`,
1547 ).to.be.true;
1548
1549 expect(
1550 xcmpQueueFailEvent!.isUntrustedReserveLocation,
1551 `The XCM error should be 'isUntrustedReserveLocation'`,
1552 ).to.be.true;
1553
1554 const accountBalance = await helper.balance.getSubstrate(targetAccount.address);
1555 expect(accountBalance).to.be.equal(0n);
1556 });
1557
1493});1558});
14941559