difftreelog
test untrusted reserve locations
in: master
4 files changed
tests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth421 return capture;421 return capture;422 }422 }423423424 makeXcmProgramWithdrawDeposit(beneficiary: Uint8Array, amount: bigint | string) {424 makeXcmProgramWithdrawDeposit(beneficiary: Uint8Array, id: any, amount: bigint | string) {425 return {425 return {426 V2: [426 V2: [427 {427 {428 WithdrawAsset: [428 WithdrawAsset: [429 {429 {430 id: {430 id,431 Concrete: {432 parents: 0,433 interior: 'Here',434 },435 },436 fun: {431 fun: {437 Fungible: amount,432 Fungible: amount,438 },433 },442 {437 {443 BuyExecution: {438 BuyExecution: {444 fees: {439 fees: {445 id: {440 id,446 Concrete: {447 parents: 0,448 interior: 'Here',449 },450 },451 fun: {441 fun: {452 Fungible: amount,442 Fungible: amount,453 },443 },478 };468 };479 }469 }470471 makeXcmProgramReserveAssetDeposited(beneficiary: Uint8Array, id: any, amount: bigint | string) {472 return {473 V2: [474 {475 ReserveAssetDeposited: [476 {477 id,478 fun: {479 Fungible: amount,480 },481 },482 ],483 },484 {485 BuyExecution: {486 fees: {487 id,488 fun: {489 Fungible: amount,490 },491 },492 weightLimit: 'Unlimited'493 },494 },495 {496 DepositAsset: {497 assets: {498 Wild: 'All'499 },500 maxAssets: 1,501 beneficiary: {502 parents: 0,503 interior: {504 X1: {505 AccountId32: {506 network: 'Any',507 id: beneficiary508 },509 },510 },511 },512 },513 },514 ],515 };516 }480}517}481518482class MoonbeamAccountGroup {519class MoonbeamAccountGroup {tests/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>() {
tests/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);
+ });
});
tests/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);
+ });
+
});