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
3022 await this.teleportAssets(signer, destination, beneficiary, assets, feeAssetItem);3022 await this.teleportAssets(signer, destination, beneficiary, assets, feeAssetItem);
3023 }3023 }
3024
3025 async send(signer: IKeyringPair, destination: any, message: any) {
3026 await this.helper.executeExtrinsic(
3027 signer,
3028 `api.tx.${this.palletName}.send`,
3029 [
3030 destination,
3031 message,
3032 ],
3033 true,
3034 );
3035 }
3024}3036}
30253037
3026class XTokensGroup<T extends ChainHelperBase> extends HelperGroup<T> {3038class XTokensGroup<T extends ChainHelperBase> extends HelperGroup<T> {
3284 assetRegistry: AcalaAssetRegistryGroup;3296 assetRegistry: AcalaAssetRegistryGroup;
3285 xTokens: XTokensGroup<AcalaHelper>;3297 xTokens: XTokensGroup<AcalaHelper>;
3286 tokens: TokensGroup<AcalaHelper>;3298 tokens: TokensGroup<AcalaHelper>;
3299 xcm: XcmGroup<AcalaHelper>;
32873300
3288 constructor(logger?: ILogger, options: {[key: string]: any} = {}) {3301 constructor(logger?: ILogger, options: {[key: string]: any} = {}) {
3289 super(logger, options.helperBase ?? AcalaHelper);3302 super(logger, options.helperBase ?? AcalaHelper);
3292 this.assetRegistry = new AcalaAssetRegistryGroup(this);3305 this.assetRegistry = new AcalaAssetRegistryGroup(this);
3293 this.xTokens = new XTokensGroup(this);3306 this.xTokens = new XTokensGroup(this);
3294 this.tokens = new TokensGroup(this);3307 this.tokens = new TokensGroup(this);
3308 this.xcm = new XcmGroup(this, 'polkadotXcm');
3295 }3309 }
32963310
3297 getSudo<T extends AcalaHelper>() {3311 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
--- a/tests/src/xcm/xcmUnique.test.ts
+++ b/tests/src/xcm/xcmUnique.test.ts
@@ -665,19 +665,20 @@
       },
     };
 
-    const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, moreThanAcalaHas);
+    const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 0,
+          interior: 'Here',
+        },
+      },
+      moreThanAcalaHas,
+    );
 
     // Try to trick Unique
     await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
-      await helper.getSudo().executeExtrinsic(
-        alice,
-        'api.tx.polkadotXcm.send',
-        [
-          uniqueMultilocation,
-          maliciousXcmProgram,
-        ],
-        true,
-      );
+      await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
     });
 
     const maxWaitBlocks = 3;
@@ -703,18 +704,19 @@
 
     // But Acala still can send the correct amount
     const validTransferAmount = acalaBalance / 2n;
-    const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);
+    const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 0,
+          interior: 'Here',
+        },
+      },
+      validTransferAmount,
+    );
 
     await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
-      await helper.getSudo().executeExtrinsic(
-        alice,
-        'api.tx.polkadotXcm.send',
-        [
-          uniqueMultilocation,
-          validXcmProgram,
-        ],
-        true,
-      );
+      await helper.getSudo().xcm.send(alice, uniqueMultilocation, validXcmProgram);
     });
 
     await helper.wait.newBlocks(maxWaitBlocks);
@@ -722,6 +724,62 @@
     targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
     expect(targetAccountBalance).to.be.equal(validTransferAmount);
   });
+
+  itSub('Should not accept reserve transfer of UNQ from Acala', async ({helper}) => {
+    const testAmount = 10_000n * (10n ** UNQ_DECIMALS);
+    const [targetAccount] = await helper.arrange.createAccounts([0n], alice);
+
+    const uniqueMultilocation = {
+      V1: {
+        parents: 1,
+        interior: {
+          X1: {
+            Parachain: UNIQUE_CHAIN,
+          },
+        },
+      },
+    };
+
+    const maliciousXcmProgram = helper.arrange.makeXcmProgramReserveAssetDeposited(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 1,
+          interior: {
+            X1: {
+              Parachain: UNIQUE_CHAIN,
+            },
+          },
+        },
+      },
+      testAmount,
+    );
+
+    await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
+      await helper.getSudo().xcm.send(alice, uniqueMultilocation, 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
@@ -1145,6 +1203,10 @@
   itSub.skip('Moonbeam can send only up to its balance', async ({helper}) => {
     throw Error("Not yet implemented");
   });
+
+  itSub.skip('Should not accept reserve transfer of UNQ from Moonbeam', async ({helper}) => {
+    throw Error("Not yet implemented");
+  });
 });
 
 describeXCM('[XCM] Integration test: Exchanging tokens with Astar', () => {
@@ -1356,63 +1418,7 @@
     console.log(`UNQ Balance on Unique after XCM is: ${balanceUNQ}`);
     expect(balanceUNQ).to.eq(balanceAfterUniqueToAstarXCM + unqFromAstarTransfered);
   });
-
-  itSub.skip('Should not accept limitedReserveTransfer of UNQ from ASTAR', async ({helper}) => {
-    await usingAstarPlaygrounds(astarUrl, async (helper) => {
-      const destination = {
-        V1: {
-          parents: 1,
-          interior: {
-            X1: {
-              Parachain: UNIQUE_CHAIN,
-            },
-          },
-        },
-      };
-
-      const beneficiary = {
-        V1: {
-          parents: 0,
-          interior: {
-            X1: {
-              AccountId32: {
-                network: 'Any',
-                id: randomAccount.addressRaw,
-              },
-            },
-          },
-        },
-      };
 
-      const assets = {
-        V1: [
-          {
-            id: {
-              Concrete: {
-                parents: 1,
-                interior: {
-                  X1: {
-                    Parachain: UNIQUE_CHAIN,
-                  },
-                },
-              },
-            },
-            fun: {
-              Fungible: unqFromAstarTransfered,
-            },
-          },
-        ],
-      };
-
-      // Initial balance is 1 ASTAR
-      expect(await helper.balance.getSubstrate(randomAccount.address)).to.eq(astarInitialBalance);
-
-      const feeAssetItem = 0;
-      // TODO: expect rejected:
-      await helper.xcm.limitedReserveTransferAssets(randomAccount, destination, beneficiary, assets, feeAssetItem, 'Unlimited');
-    });
-  });
-
   itSub('Astar can send only up to its balance', async ({helper}) => {
     // set Astar's sovereign account's balance
     const astarBalance = 10000n * (10n ** UNQ_DECIMALS);
@@ -1433,19 +1439,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 Unique
     await usingAstarPlaygrounds(astarUrl, async (helper) => {
-      await helper.getSudo().executeExtrinsic(
-        alice,
-        'api.tx.polkadotXcm.send',
-        [
-          uniqueMultilocation,
-          maliciousXcmProgram,
-        ],
-        true,
-      );
+      await helper.getSudo().xcm.send(alice, uniqueMultilocation, maliciousXcmProgram);
     });
 
     const maxWaitBlocks = 3;
@@ -1471,18 +1478,19 @@
 
     // But Astar still can send the correct amount
     const validTransferAmount = astarBalance / 2n;
-    const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);
+    const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 0,
+          interior: 'Here',
+        },
+      },
+      validTransferAmount,
+    );
 
     await usingAstarPlaygrounds(astarUrl, async (helper) => {
-      await helper.getSudo().executeExtrinsic(
-        alice,
-        'api.tx.polkadotXcm.send',
-        [
-          uniqueMultilocation,
-          validXcmProgram,
-        ],
-        true,
-      );
+      await helper.getSudo().xcm.send(alice, uniqueMultilocation, validXcmProgram);
     });
 
     await helper.wait.newBlocks(maxWaitBlocks);
@@ -1490,4 +1498,61 @@
     targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
     expect(targetAccountBalance).to.be.equal(validTransferAmount);
   });
+
+  itSub('Should not accept reserve transfer of UNQ from Astar', async ({helper}) => {
+    const testAmount = 10_000n * (10n ** UNQ_DECIMALS);
+    const [targetAccount] = await helper.arrange.createAccounts([0n], alice);
+
+    const uniqueMultilocation = {
+      V1: {
+        parents: 1,
+        interior: {
+          X1: {
+            Parachain: UNIQUE_CHAIN,
+          },
+        },
+      },
+    };
+
+    const maliciousXcmProgram = helper.arrange.makeXcmProgramReserveAssetDeposited(
+      targetAccount.addressRaw,
+      {
+        Concrete: {
+          parents: 1,
+          interior: {
+            X1: {
+              Parachain: UNIQUE_CHAIN,
+            },
+          },
+        },
+      },
+      testAmount,
+    );
+
+    await usingAstarPlaygrounds(astarUrl, async (helper) => {
+      await helper.getSudo().xcm.send(alice, uniqueMultilocation, 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);
+  });
+
 });