difftreelog
test untrusted reserve locations
in: master
4 files changed
tests/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 @@
},
},
},
- }
+ },
},
],
};
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth3022 await this.teleportAssets(signer, destination, beneficiary, assets, feeAssetItem);3022 await this.teleportAssets(signer, destination, beneficiary, assets, feeAssetItem);3023 }3023 }30243025 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}302530373026class 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>;328733003288 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 }329633103297 getSudo<T extends AcalaHelper>() {3311 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);
+ });
+
});