difftreelog
test other chains can spend only up to balance
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
@@ -420,6 +420,63 @@
return capture;
}
+
+ makeXcmProgramWithdrawDeposit(beneficiary: Uint8Array, amount: bigint | string) {
+ return {
+ V2: [
+ {
+ WithdrawAsset: [
+ {
+ id: {
+ Concrete: {
+ parents: 0,
+ interior: 'Here',
+ },
+ },
+ fun: {
+ Fungible: amount,
+ },
+ },
+ ],
+ },
+ {
+ BuyExecution: {
+ fees: {
+ id: {
+ Concrete: {
+ parents: 0,
+ interior: 'Here',
+ },
+ },
+ fun: {
+ Fungible: amount,
+ },
+ },
+ weightLimit: 'Unlimited'
+ },
+ },
+ {
+ DepositAsset: {
+ assets: {
+ Wild: 'All'
+ },
+ maxAssets: 1,
+ beneficiary: {
+ parents: 0,
+ interior: {
+ X1: {
+ AccountId32: {
+ network: 'Any',
+ id: beneficiary
+ },
+ },
+ },
+ },
+ }
+ },
+ ],
+ };
+ }
}
class MoonbeamAccountGroup {
tests/src/util/playgrounds/unique.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -2446,6 +2446,10 @@
return this.ethBalanceGroup.getEthereum(address);
}
+ async setBalanceSubstrate(signer: TSigner, address: TSubstrateAccount, amount: bigint | string, reservedAmount: bigint | string = 0n) {
+ await this.helper.executeExtrinsic(signer, 'api.tx.balances.setBalance', [address, amount, reservedAmount], true);
+ }
+
/**
* Transfer tokens to substrate address
* @param signer keyring of signer
tests/src/xcm/xcmQuartz.test.tsdiffbeforeafterboth643 expect(qtzFees == 0n).to.be.true;643 expect(qtzFees == 0n).to.be.true;644 });644 });645646 itSub('Karura can send only up to its balance', async ({helper}) => {647 // set Karura's sovereign account's balance648 const karuraBalance = 10000n * (10n ** QTZ_DECIMALS);649 const karuraSovereignAccount = helper.address.paraSiblingSovereignAccount(KARURA_CHAIN);650 await helper.getSudo().balance.setBalanceSubstrate(alice, karuraSovereignAccount, karuraBalance);651652 const moreThanKaruraHas = karuraBalance * 2n;653654 let targetAccountBalance = 0n;655 const [targetAccount] = await helper.arrange.createAccounts([targetAccountBalance], alice);656657 const quartzMultilocation = {658 V1: {659 parents: 1,660 interior: {661 X1: {Parachain: QUARTZ_CHAIN},662 },663 },664 };665666 const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, moreThanKaruraHas);667668 // Try to trick Quartz669 await usingKaruraPlaygrounds(karuraUrl, async (helper) => {670 await helper.getSudo().executeExtrinsic(671 alice,672 'api.tx.polkadotXcm.send',673 [674 quartzMultilocation,675 maliciousXcmProgram,676 ],677 true,678 );679 });680681 const maxWaitBlocks = 3;682683 const xcmpQueueFailEvent = await helper.wait.eventOutcome<XcmV2TraitsError>(684 maxWaitBlocks,685 'xcmpQueue',686 'Fail',687 );688689 expect(690 xcmpQueueFailEvent != null,691 `'xcmpQueue.FailEvent' event is expected`,692 ).to.be.true;693694 expect(695 xcmpQueueFailEvent!.isFailedToTransactAsset,696 `The XCM error should be 'FailedToTransactAsset'`,697 ).to.be.true;698699 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);700 expect(targetAccountBalance).to.be.equal(0n);701702 // But Karura still can send the correct amount703 const validTransferAmount = karuraBalance / 2n;704 const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);705706 await usingKaruraPlaygrounds(karuraUrl, async (helper) => {707 await helper.getSudo().executeExtrinsic(708 alice,709 'api.tx.polkadotXcm.send',710 [711 quartzMultilocation,712 validXcmProgram,713 ],714 true,715 );716 });717718 await helper.wait.newBlocks(maxWaitBlocks);719720 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);721 expect(targetAccountBalance).to.be.equal(validTransferAmount);722 });645});723});646724647// These tests are relevant only when725// These tests are relevant only when1061 expect(qtzFees == 0n).to.be.true;1139 expect(qtzFees == 0n).to.be.true;1062 });1140 });11411142 itSub.skip('Moonriver can send only up to its balance', async ({helper}) => {1143 throw Error("Not yet implemented");1144 });1063});1145});106411461065describeXCM('[XCM] Integration test: Exchanging tokens with Shiden', () => {1147describeXCM('[XCM] Integration test: Exchanging tokens with Shiden', () => {1273 expect(balanceQTZ).to.eq(balanceAfterQuartzToShidenXCM + qtzFromShidenTransfered);1355 expect(balanceQTZ).to.eq(balanceAfterQuartzToShidenXCM + qtzFromShidenTransfered);1274 });1356 });13571358 itSub('Shiden can send only up to its balance', async ({helper}) => {1359 // set Shiden's sovereign account's balance1360 const shidenBalance = 10000n * (10n ** QTZ_DECIMALS);1361 const shidenSovereignAccount = helper.address.paraSiblingSovereignAccount(SHIDEN_CHAIN);1362 await helper.getSudo().balance.setBalanceSubstrate(alice, shidenSovereignAccount, shidenBalance);13631364 const moreThanShidenHas = shidenBalance * 2n;13651366 let targetAccountBalance = 0n;1367 const [targetAccount] = await helper.arrange.createAccounts([targetAccountBalance], alice);13681369 const quartzMultilocation = {1370 V1: {1371 parents: 1,1372 interior: {1373 X1: {Parachain: QUARTZ_CHAIN},1374 },1375 },1376 };13771378 const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, moreThanShidenHas);13791380 // Try to trick Quartz1381 await usingShidenPlaygrounds(shidenUrl, async (helper) => {1382 await helper.getSudo().executeExtrinsic(1383 alice,1384 'api.tx.polkadotXcm.send',1385 [1386 quartzMultilocation,1387 maliciousXcmProgram,1388 ],1389 true,1390 );1391 });13921393 const maxWaitBlocks = 3;13941395 const xcmpQueueFailEvent = await helper.wait.eventOutcome<XcmV2TraitsError>(1396 maxWaitBlocks,1397 'xcmpQueue',1398 'Fail',1399 );14001401 expect(1402 xcmpQueueFailEvent != null,1403 `'xcmpQueue.FailEvent' event is expected`,1404 ).to.be.true;14051406 expect(1407 xcmpQueueFailEvent!.isFailedToTransactAsset,1408 `The XCM error should be 'FailedToTransactAsset'`,1409 ).to.be.true;14101411 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);1412 expect(targetAccountBalance).to.be.equal(0n);14131414 // But Shiden still can send the correct amount1415 const validTransferAmount = shidenBalance / 2n;1416 const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);14171418 await usingShidenPlaygrounds(shidenUrl, async (helper) => {1419 await helper.getSudo().executeExtrinsic(1420 alice,1421 'api.tx.polkadotXcm.send',1422 [1423 quartzMultilocation,1424 validXcmProgram,1425 ],1426 true,1427 );1428 });14291430 await helper.wait.newBlocks(maxWaitBlocks);14311432 targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);1433 expect(targetAccountBalance).to.be.equal(validTransferAmount);1434 });1275});1435});12761436tests/src/xcm/xcmUnique.test.tsdiffbeforeafterboth--- a/tests/src/xcm/xcmUnique.test.ts
+++ b/tests/src/xcm/xcmUnique.test.ts
@@ -644,6 +644,84 @@
console.log('[Acala -> Unique] transaction fees on Unique: %s UNQ', helper.util.bigIntToDecimals(unqFees));
expect(unqFees == 0n).to.be.true;
});
+
+ itSub('Acala can send only up to its balance', async ({helper}) => {
+ // set Acala's sovereign account's balance
+ const acalaBalance = 10000n * (10n ** UNQ_DECIMALS);
+ const acalaSovereignAccount = helper.address.paraSiblingSovereignAccount(ACALA_CHAIN);
+ await helper.getSudo().balance.setBalanceSubstrate(alice, acalaSovereignAccount, acalaBalance);
+
+ const moreThanAcalaHas = acalaBalance * 2n;
+
+ let targetAccountBalance = 0n;
+ const [targetAccount] = await helper.arrange.createAccounts([targetAccountBalance], alice);
+
+ const uniqueMultilocation = {
+ V1: {
+ parents: 1,
+ interior: {
+ X1: {Parachain: UNIQUE_CHAIN},
+ },
+ },
+ };
+
+ const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, moreThanAcalaHas);
+
+ // Try to trick Unique
+ await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
+ await helper.getSudo().executeExtrinsic(
+ alice,
+ 'api.tx.polkadotXcm.send',
+ [
+ uniqueMultilocation,
+ maliciousXcmProgram,
+ ],
+ true,
+ );
+ });
+
+ 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!.isFailedToTransactAsset,
+ `The XCM error should be 'FailedToTransactAsset'`,
+ ).to.be.true;
+
+ targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
+ expect(targetAccountBalance).to.be.equal(0n);
+
+ // But Acala still can send the correct amount
+ const validTransferAmount = acalaBalance / 2n;
+ const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);
+
+ await usingAcalaPlaygrounds(acalaUrl, async (helper) => {
+ await helper.getSudo().executeExtrinsic(
+ alice,
+ 'api.tx.polkadotXcm.send',
+ [
+ uniqueMultilocation,
+ validXcmProgram,
+ ],
+ true,
+ );
+ });
+
+ await helper.wait.newBlocks(maxWaitBlocks);
+
+ targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
+ expect(targetAccountBalance).to.be.equal(validTransferAmount);
+ });
});
// These tests are relevant only when
@@ -1063,6 +1141,10 @@
console.log('[Moonbeam -> Unique] transaction fees on Unique: %s UNQ', helper.util.bigIntToDecimals(unqFees));
expect(unqFees == 0n).to.be.true;
});
+
+ itSub.skip('Moonbeam can send only up to its balance', async ({helper}) => {
+ throw Error("Not yet implemented");
+ });
});
describeXCM('[XCM] Integration test: Exchanging tokens with Astar', () => {
@@ -1330,4 +1412,82 @@
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);
+ const astarSovereignAccount = helper.address.paraSiblingSovereignAccount(ASTAR_CHAIN);
+ await helper.getSudo().balance.setBalanceSubstrate(alice, astarSovereignAccount, astarBalance);
+
+ const moreThanShidenHas = astarBalance * 2n;
+
+ let targetAccountBalance = 0n;
+ const [targetAccount] = await helper.arrange.createAccounts([targetAccountBalance], alice);
+
+ const uniqueMultilocation = {
+ V1: {
+ parents: 1,
+ interior: {
+ X1: {Parachain: UNIQUE_CHAIN},
+ },
+ },
+ };
+
+ const maliciousXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, moreThanShidenHas);
+
+ // Try to trick Unique
+ await usingAstarPlaygrounds(astarUrl, async (helper) => {
+ await helper.getSudo().executeExtrinsic(
+ alice,
+ 'api.tx.polkadotXcm.send',
+ [
+ uniqueMultilocation,
+ maliciousXcmProgram,
+ ],
+ true,
+ );
+ });
+
+ 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!.isFailedToTransactAsset,
+ `The XCM error should be 'FailedToTransactAsset'`,
+ ).to.be.true;
+
+ targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
+ expect(targetAccountBalance).to.be.equal(0n);
+
+ // But Astar still can send the correct amount
+ const validTransferAmount = astarBalance / 2n;
+ const validXcmProgram = helper.arrange.makeXcmProgramWithdrawDeposit(targetAccount.addressRaw, validTransferAmount);
+
+ await usingAstarPlaygrounds(astarUrl, async (helper) => {
+ await helper.getSudo().executeExtrinsic(
+ alice,
+ 'api.tx.polkadotXcm.send',
+ [
+ uniqueMultilocation,
+ validXcmProgram,
+ ],
+ true,
+ );
+ });
+
+ await helper.wait.newBlocks(maxWaitBlocks);
+
+ targetAccountBalance = await helper.balance.getSubstrate(targetAccount.address);
+ expect(targetAccountBalance).to.be.equal(validTransferAmount);
+ });
});