git.delta.rocks / unique-network / refs/commits / 7586abb798e7

difftreelog

Use itEth

Max Andreev2022-09-15parent: #0c093d5.patch.diff
in: master

2 files changed

modifiedtests/src/app-promotion.test.tsdiffbeforeafterboth
2727
28import {encodeAddress} from '@polkadot/util-crypto';28import {encodeAddress} from '@polkadot/util-crypto';
29import {stringToU8a} from '@polkadot/util';29import {stringToU8a} from '@polkadot/util';
30import {SponsoringMode, contractHelpers, createEthAccountWithBalance, deployFlipper, itWeb3, transferBalanceToEth} from './eth/util/helpers';30import {SponsoringMode} from './eth/util/helpers';
31import {DevUniqueHelper} from './util/playgrounds/unique.dev';31import {DevUniqueHelper} from './util/playgrounds/unique.dev';
32import {itEth} from './eth/util/playgrounds';
32chai.use(chaiAsPromised);33chai.use(chaiAsPromised);
33const expect = chai.expect;34const expect = chai.expect;
3435
38const palletAddress = calculatePalleteAddress('appstake');39const palletAddress = calculatePalleteAddress('appstake');
39let accounts: IKeyringPair[] = [];40let accounts: IKeyringPair[] = [];
40const LOCKING_PERIOD = 20n; // 20 blocks of relay41const LOCKING_PERIOD = 20n; // 20 blocks of relay
41const UNLOCKING_PERIOD = 10n; // 20 blocks of parachain42const UNLOCKING_PERIOD = 10n; // 10 blocks of parachain
42const rewardAvailableInBlock = (stakedInBlock: bigint) => (stakedInBlock - stakedInBlock % LOCKING_PERIOD) + (LOCKING_PERIOD * 2n);43const rewardAvailableInBlock = (stakedInBlock: bigint) => (stakedInBlock - stakedInBlock % LOCKING_PERIOD) + (LOCKING_PERIOD * 2n);
4344
44const beforeEach = async (context: Mocha.Context) => {45const beforeEach = async (context: Mocha.Context) => {
64 const totalStakedBefore = await helper.staking.getTotalStaked();65 const totalStakedBefore = await helper.staking.getTotalStaked();
6566
66 // Minimum stake amount is 100:67 // Minimum stake amount is 100:
67 await expect(helper.staking.stake(staker, 100n * nominal - 1n)).to.be.eventually.rejected;68 await expect(helper.staking.stake(staker, 100n * nominal - 1n)).to.be.rejected;
68 await helper.staking.stake(staker, 100n * nominal);69 await helper.staking.stake(staker, 100n * nominal);
6970
70 // Staker balance is: miscFrozen: 100, feeFrozen: 100, reserved: 0n...71 // Staker balance is: miscFrozen: 100, feeFrozen: 100, reserved: 0n...
71 // ...so he can not transfer 90072 // ...so he can not transfer 900
72 expect (await helper.balance.getSubstrateFull(staker.address)).to.contain({miscFrozen: 100n * nominal, feeFrozen: 100n * nominal, reserved: 0n});73 expect (await helper.balance.getSubstrateFull(staker.address)).to.contain({miscFrozen: 100n * nominal, feeFrozen: 100n * nominal, reserved: 0n});
73 await expect(helper.balance.transferToSubstrate(staker, recepient.address, 900n * nominal)).to.be.rejected;74 await expect(helper.balance.transferToSubstrate(staker, recepient.address, 900n * nominal)).to.be.rejectedWith('balances.LiquidityRestrictions');
74 75
75 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(100n * nominal);76 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(100n * nominal);
76 expect(await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(999n);77 expect(await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(999n);
95 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(1000n * nominal);96 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(1000n * nominal);
96 expect(await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).to.have.length(10);97 expect(await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).to.have.length(10);
9798
98 await expect(helper.staking.stake(staker, 100n * nominal)).to.be.rejected;99 await expect(helper.staking.stake(staker, 100n * nominal)).to.be.rejectedWith('appPromotion.NoPermission');
99100
100 // After unstake can stake again101 // After unstake can stake again
101 await helper.staking.unstake(staker);102 await helper.staking.unstake(staker);
107 const staker = accounts.pop()!;108 const staker = accounts.pop()!;
108109
109 // Can't stake full balance because Alice needs to pay some fee110 // Can't stake full balance because Alice needs to pay some fee
110 await expect(helper.staking.stake(staker, 1000n * nominal)).to.be.eventually.rejected;111 await expect(helper.staking.stake(staker, 1000n * nominal)).to.be.rejected;
111 await helper.staking.stake(staker, 500n * nominal);112 await helper.staking.stake(staker, 500n * nominal);
112113
113 // Can't stake 500 tkn because Alice has Less than 500 transferable;114 // Can't stake 500 tkn because Alice has Less than 500 transferable;
114 await expect(helper.staking.stake(staker, 500n * nominal)).to.be.eventually.rejected; 115 await expect(helper.staking.stake(staker, 500n * nominal)).to.be.rejectedWith('balances.LiquidityRestrictions');
115 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(500n * nominal);116 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(500n * nominal);
116 });117 });
117 118
118 itSub('for different accounts in one block is possible', async ({helper}) => {119 itSub('for different accounts in one block is possible', async ({helper}) => {
119 const crowd = [accounts.pop()!, accounts.pop()!, accounts.pop()!, accounts.pop()!];120 const crowd = [accounts.pop()!, accounts.pop()!, accounts.pop()!, accounts.pop()!];
120 121
121 const crowdStartsToStake = crowd.map(user => helper.staking.stake(user, 100n * nominal));122 const crowdStartsToStake = crowd.map(user => helper.staking.stake(user, 100n * nominal));
122 await expect(Promise.all(crowdStartsToStake)).to.be.eventually.fulfilled;123 await expect(Promise.all(crowdStartsToStake)).to.be.fulfilled;
123124
124 const crowdStakes = await Promise.all(crowd.map(address => helper.staking.getTotalStaked({Substrate: address.address})));125 const crowdStakes = await Promise.all(crowd.map(address => helper.staking.getTotalStaked({Substrate: address.address})));
125 expect(crowdStakes).to.deep.equal([100n * nominal, 100n * nominal, 100n * nominal, 100n * nominal]);126 expect(crowdStakes).to.deep.equal([100n * nominal, 100n * nominal, 100n * nominal, 100n * nominal]);
140 // Right after unstake balance is reserved141 // Right after unstake balance is reserved
141 // Staker can not transfer 142 // Staker can not transfer
142 expect(await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 900n * nominal, miscFrozen: 0n, feeFrozen: 0n});143 expect(await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 900n * nominal, miscFrozen: 0n, feeFrozen: 0n});
143 await expect(helper.balance.transferToSubstrate(staker, recepient.address, 100n * nominal)).to.be.rejected;144 await expect(helper.balance.transferToSubstrate(staker, recepient.address, 100n * nominal)).to.be.rejectedWith('balances.InsufficientBalance');
144 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(900n * nominal);145 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(900n * nominal);
145 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(0n);146 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(0n);
146 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore);147 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore);
246 itSub('can be set by sudo only', async ({helper}) => {247 itSub('can be set by sudo only', async ({helper}) => {
247 const nonAdmin = accounts.pop()!;248 const nonAdmin = accounts.pop()!;
248 // nonAdmin can not set admin not from himself nor as a sudo249 // nonAdmin can not set admin not from himself nor as a sudo
249 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.appPromotion.setAdminAddress({Substrate: nonAdmin.address}))).to.be.eventually.rejected;250 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.appPromotion.setAdminAddress({Substrate: nonAdmin.address}))).to.be.rejected;
250 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress({Substrate: nonAdmin.address})))).to.be.eventually.rejected;251 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress({Substrate: nonAdmin.address})))).to.be.rejected;
251252
252 // Alice can253 // Alice can
253 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.eventually.fulfilled;254 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.fulfilled;
254 });255 });
255 256
256 itSub('can be any valid CrossAccountId', async ({helper}) => {257 itSub('can be any valid CrossAccountId', async ({helper}) => {
259 const account = accounts.pop()!;260 const account = accounts.pop()!;
260 const ethAccount = helper.address.substrateToEth(account.address); 261 const ethAccount = helper.address.substrateToEth(account.address);
261 // Alice sets Ethereum address as a sudo. Then Substrate address back...262 // Alice sets Ethereum address as a sudo. Then Substrate address back...
262 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress({Ethereum: ethAccount})))).to.be.eventually.fulfilled;263 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress({Ethereum: ethAccount})))).to.be.fulfilled;
263 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.eventually.fulfilled;264 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.fulfilled;
264 265
265 // ...It doesn't break anything;266 // ...It doesn't break anything;
266 const collection = await helper.nft.mintCollection(account, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});267 const collection = await helper.nft.mintCollection(account, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});
267 await expect(helper.signTransaction(account, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;268 await expect(helper.signTransaction(account, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.rejected;
268 });269 });
269270
270 itSub('can be reassigned', async ({helper}) => {271 itSub('can be reassigned', async ({helper}) => {
271 const [oldAdmin, newAdmin, collectionOwner] = [accounts.pop()!, accounts.pop()!, accounts.pop()!];272 const [oldAdmin, newAdmin, collectionOwner] = [accounts.pop()!, accounts.pop()!, accounts.pop()!];
272 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});273 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});
273 274
274 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress(normalizeAccountId(oldAdmin))))).to.be.eventually.fulfilled;275 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress(normalizeAccountId(oldAdmin))))).to.be.fulfilled;
275 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress(normalizeAccountId(newAdmin))))).to.be.eventually.fulfilled;276 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.appPromotion.setAdminAddress(normalizeAccountId(newAdmin))))).to.be.fulfilled;
276 await expect(helper.signTransaction(oldAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;277 await expect(helper.signTransaction(oldAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.rejected;
277 278
278 await expect(helper.signTransaction(newAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;279 await expect(helper.signTransaction(newAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.fulfilled;
279 });280 });
280});281});
281282
309310
310 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});311 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});
311 312
312 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;313 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.rejected;
313 expect((await collection.getData())?.raw.sponsorship).to.equal('Disabled');314 expect((await collection.getData())?.raw.sponsorship).to.equal('Disabled');
314 });315 });
315316
318 319
319 // Can set sponsoring for collection without sponsor320 // Can set sponsoring for collection without sponsor
320 const collectionWithoutSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'No-sponsor', description: 'New Collection', tokenPrefix: 'Promotion'});321 const collectionWithoutSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'No-sponsor', description: 'New Collection', tokenPrefix: 'Promotion'});
321 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionWithoutSponsor.collectionId))).to.be.eventually.fulfilled;322 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionWithoutSponsor.collectionId))).to.be.fulfilled;
322 expect((await collectionWithoutSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});323 expect((await collectionWithoutSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});
323324
324 // Can set sponsoring for collection with unconfirmed sponsor325 // Can set sponsoring for collection with unconfirmed sponsor
325 const collectionWithUnconfirmedSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'Unconfirmed', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: oldSponsor.address});326 const collectionWithUnconfirmedSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'Unconfirmed', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: oldSponsor.address});
326 expect((await collectionWithUnconfirmedSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Unconfirmed: oldSponsor.address});327 expect((await collectionWithUnconfirmedSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Unconfirmed: oldSponsor.address});
327 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionWithUnconfirmedSponsor.collectionId))).to.be.eventually.fulfilled;328 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionWithUnconfirmedSponsor.collectionId))).to.be.fulfilled;
328 expect((await collectionWithUnconfirmedSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});329 expect((await collectionWithUnconfirmedSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});
329330
330 // Can set sponsoring for collection with confirmed sponsor331 // Can set sponsoring for collection with confirmed sponsor
331 const collectionWithConfirmedSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'Confirmed', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: oldSponsor.address});332 const collectionWithConfirmedSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'Confirmed', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: oldSponsor.address});
332 await collectionWithConfirmedSponsor.confirmSponsorship(oldSponsor);333 await collectionWithConfirmedSponsor.confirmSponsorship(oldSponsor);
333 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionWithConfirmedSponsor.collectionId))).to.be.eventually.fulfilled;334 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionWithConfirmedSponsor.collectionId))).to.be.fulfilled;
334 expect((await collectionWithConfirmedSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});335 expect((await collectionWithConfirmedSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});
335 });336 });
336337
339 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});340 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});
340 const collectionId = collection.collectionId;341 const collectionId = collection.collectionId;
341 342
342 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;343 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionId))).to.be.fulfilled;
343 344
344 // Collection limits still can be changed by the owner345 // Collection limits still can be changed by the owner
345 expect(await collection.setLimits(collectionOwner, {sponsorTransferTimeout: 0})).to.be.true;346 expect(await collection.setLimits(collectionOwner, {sponsorTransferTimeout: 0})).to.be.true;
355 const limits = {ownerCanDestroy: true, ownerCanTransfer: true, sponsorTransferTimeout: 0};356 const limits = {ownerCanDestroy: true, ownerCanTransfer: true, sponsorTransferTimeout: 0};
356 const collectionWithLimits = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', limits});357 const collectionWithLimits = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', limits});
357358
358 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionWithLimits.collectionId))).to.be.eventually.fulfilled;359 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collectionWithLimits.collectionId))).to.be.fulfilled;
359 expect((await collectionWithLimits.getData())?.raw.limits).to.be.deep.contain(limits);360 expect((await collectionWithLimits.getData())?.raw.limits).to.be.deep.contain(limits);
360 });361 });
361 362
362 itSub('should reject transaction if collection doesn\'t exist', async ({helper}) => {363 itSub('should reject transaction if collection doesn\'t exist', async ({helper}) => {
363 const collectionOwner = accounts.pop()!;364 const collectionOwner = accounts.pop()!;
364 365
365 // collection has never existed366 // collection has never existed
366 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(999999999))).to.be.eventually.rejected;367 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(999999999))).to.be.rejected;
367 // collection has been burned368 // collection has been burned
368 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});369 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});
369 await collection.burn(collectionOwner);370 await collection.burn(collectionOwner);
370371
371 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;372 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.rejected;
372 });373 });
373});374});
374375
381 const [collectionOwner, nonAdmin] = [accounts.pop()!, accounts.pop()!];382 const [collectionOwner, nonAdmin] = [accounts.pop()!, accounts.pop()!];
382 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});383 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});
383 384
384 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;385 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorCollection(collection.collectionId))).to.be.fulfilled;
385 386
386 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.appPromotion.stopSponsoringCollection(collection.collectionId))).to.be.eventually.rejected;387 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.appPromotion.stopSponsoringCollection(collection.collectionId))).to.be.rejected;
387 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});388 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});
388 });389 });
389390
409 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: collectionOwner.address});410 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: collectionOwner.address});
410 await collection.confirmSponsorship(collectionOwner);411 await collection.confirmSponsorship(collectionOwner);
411 412
412 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.stopSponsoringCollection(collection.collectionId))).to.be.eventually.rejected;413 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.stopSponsoringCollection(collection.collectionId))).to.be.rejected;
413 414
414 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: collectionOwner.address});415 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: collectionOwner.address});
415 });416 });
419 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});420 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});
420 421
421 await collection.burn(collectionOwner);422 await collection.burn(collectionOwner);
422 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.stopSponsoringCollection(collection.collectionId))).to.be.eventually.rejected;423 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.stopSponsoringCollection(collection.collectionId))).to.be.rejected;
423 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.stopSponsoringCollection(999999999))).to.be.eventually.rejected;424 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.stopSponsoringCollection(999999999))).to.be.rejected;
424 });425 });
425});426});
426427
429 await beforeEach(this);430 await beforeEach(this);
430 });431 });
431432
432 itWeb3('should set palletes address as a sponsor', async ({api, web3, privateKeyWrapper}) => {433 itEth('should set palletes address as a sponsor', async ({helper}) => {
433 await usingPlaygrounds(async (helper) => {434 const contractOwner = (await helper.eth.createAccountWithBalance(alice, 1000n)).toLowerCase();
435 const flipper = await helper.eth.deployFlipper(contractOwner); // await deployFlipper(web3, contractOwner);
436 const contractHelper = helper.ethNativeContract.contractHelpers(contractOwner);
437
434 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();438 await helper.executeExtrinsic(palletAdmin, 'api.tx.appPromotion.sponsorContract', [flipper.options.address]);
435 const flipper = await deployFlipper(web3, contractOwner);439
436 const contractMethods = contractHelpers(web3, contractOwner);
437
438 await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));
439
440 expect(await contractMethods.methods.hasSponsor(flipper.options.address).call()).to.be.true; 440 expect(await contractHelper.methods.hasSponsor(flipper.options.address).call()).to.be.true;
441 expect((await api.query.evmContractHelpers.owner(flipper.options.address)).toJSON()).to.be.equal(contractOwner); 441 expect((await helper.api!.query.evmContractHelpers.owner(flipper.options.address)).toJSON()).to.be.equal(contractOwner);
442 expect((await api.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({442 expect((await helper.api!.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({
443 confirmed: {443 confirmed: {
444 substrate: palletAddress,444 substrate: palletAddress,
445 },445 },
446 });446 });
447 });
448 });447 });
449448
450 itWeb3('should overwrite sponsoring mode and existed sponsor', async ({api, web3, privateKeyWrapper}) => {449 itEth('should overwrite sponsoring mode and existed sponsor', async ({helper}) => {
451 await usingPlaygrounds(async (helper) => {450 const contractOwner = (await helper.eth.createAccountWithBalance(alice, 1000n)).toLowerCase();
451 const flipper = await helper.eth.deployFlipper(contractOwner); // await deployFlipper(web3, contractOwner);
452 const contractHelper = helper.ethNativeContract.contractHelpers(contractOwner);
453
452 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();454 await expect(contractHelper.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.fulfilled;
453 const flipper = await deployFlipper(web3, contractOwner);
454 const contractMethods = contractHelpers(web3, contractOwner);
455
456 await expect(contractMethods.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;
457455
458 // Contract is self sponsored456 // Contract is self sponsored
459 expect((await api.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.be.deep.equal({457 expect((await helper.api!.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.be.deep.equal({
460 confirmed: {458 confirmed: {
461 ethereum: flipper.options.address.toLowerCase(),459 ethereum: flipper.options.address.toLowerCase(),
462 },460 },
463 });461 });
464462
465 // set promotion sponsoring463 // set promotion sponsoring
466 await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));464 await helper.executeExtrinsic(palletAdmin, 'api.tx.appPromotion.sponsorContract', [flipper.options.address], true);
467465
468 // new sponsor is pallet address466 // new sponsor is pallet address
469 expect(await contractMethods.methods.hasSponsor(flipper.options.address).call()).to.be.true; 467 expect(await contractHelper.methods.hasSponsor(flipper.options.address).call()).to.be.true;
470 expect((await api.query.evmContractHelpers.owner(flipper.options.address)).toJSON()).to.be.equal(contractOwner); 468 expect((await helper.api!.query.evmContractHelpers.owner(flipper.options.address)).toJSON()).to.be.equal(contractOwner);
471 expect((await api.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({469 expect((await helper.api!.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({
472 confirmed: {470 confirmed: {
473 substrate: palletAddress,471 substrate: palletAddress,
474 },472 },
475 });473 });
476 });
477 });474 });
478475
479 itWeb3('can be overwritten by contract owner', async ({api, web3, privateKeyWrapper}) => {476 itEth('can be overwritten by contract owner', async ({helper}) => {
480 await usingPlaygrounds(async (helper) => { 477 const contractOwner = (await helper.eth.createAccountWithBalance(alice, 1000n)).toLowerCase();
481 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();478 const flipper = await helper.eth.deployFlipper(contractOwner); // await deployFlipper(web3, contractOwner);
482 const flipper = await deployFlipper(web3, contractOwner);479 const contractHelper = helper.ethNativeContract.contractHelpers(contractOwner);
483 const contractMethods = contractHelpers(web3, contractOwner);
484480
485 // contract sponsored by pallet481 // contract sponsored by pallet
486 await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));482 await helper.executeExtrinsic(palletAdmin, 'api.tx.appPromotion.sponsorContract', [flipper.options.address], true);
487483
488 // owner sets self sponsoring484 // owner sets self sponsoring
489 await expect(contractMethods.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;485 await expect(contractHelper.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;
490486
491 expect(await contractMethods.methods.hasSponsor(flipper.options.address).call()).to.be.true; 487 expect(await contractHelper.methods.hasSponsor(flipper.options.address).call()).to.be.true;
492 expect((await api.query.evmContractHelpers.owner(flipper.options.address)).toJSON()).to.be.equal(contractOwner); 488 expect((await helper.api!.query.evmContractHelpers.owner(flipper.options.address)).toJSON()).to.be.equal(contractOwner);
493 expect((await api.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({489 expect((await helper.api!.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({
494 confirmed: {490 confirmed: {
495 ethereum: flipper.options.address.toLowerCase(),491 ethereum: flipper.options.address.toLowerCase(),
496 },492 },
497 });493 });
498 });
499 });494 });
500495
501 itWeb3('can not be set by non admin', async ({api, web3, privateKeyWrapper}) => {496 itEth('can not be set by non admin', async ({helper}) => {
502 await usingPlaygrounds(async (helper) => {
503 const nonAdmin = accounts.pop()!;497 const nonAdmin = accounts.pop()!;
504 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();498 const contractOwner = (await helper.eth.createAccountWithBalance(alice, 1000n)).toLowerCase();
505 const flipper = await deployFlipper(web3, contractOwner);499 const flipper = await helper.eth.deployFlipper(contractOwner); // await deployFlipper(web3, contractOwner);
506 const contractMethods = contractHelpers(web3, contractOwner);500 const contractHelper = helper.ethNativeContract.contractHelpers(contractOwner);
507501
508 await expect(contractMethods.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;502 await expect(contractHelper.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.fulfilled;
509503
510 // nonAdmin calls sponsorContract504 // nonAdmin calls sponsorContract
511 await expect(helper.signTransaction(nonAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address))).to.be.rejected;505 await expect(helper.executeExtrinsic(nonAdmin, 'api.tx.appPromotion.sponsorContract', [flipper.options.address], true)).to.be.rejectedWith('appPromotion.NoPermission');
512506
513 // contract still self-sponsored 507 // contract still self-sponsored
514 expect((await api.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({508 expect((await helper.api!.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({
515 confirmed: {509 confirmed: {
516 ethereum: flipper.options.address.toLowerCase(),510 ethereum: flipper.options.address.toLowerCase(),
517 },511 },
518 });512 });
519 });
520
521 itWeb3('should be rejected for non-contract address', async ({api, web3, privateKeyWrapper}) => {
522 await usingPlaygrounds(async (helper) => {
523
524 });
525 });
526 });513 });
527514
528 itWeb3('should actually sponsor transactions', async ({api, web3, privateKeyWrapper}) => {515 itEth('should actually sponsor transactions', async ({helper}) => {
529 await usingPlaygrounds(async (helper) => { 516 // Contract caller
530 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);517 const caller = await helper.eth.createAccountWithBalance(alice, 1000n);
531 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();518 const palletBalanceBefore = await helper.balance.getSubstrate(palletAddress);
532 const flipper = await deployFlipper(web3, contractOwner);519
533 const contractHelper = contractHelpers(web3, contractOwner);520 // Deploy flipper
521 const contractOwner = (await helper.eth.createAccountWithBalance(alice, 1000n)).toLowerCase();
522 const flipper = await helper.eth.deployFlipper(contractOwner); // await deployFlipper(web3, contractOwner);
523 const contractHelper = helper.ethNativeContract.contractHelpers(contractOwner);
524
525 // Owner sets to sponsor every tx
534 await contractHelper.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: contractOwner});526 await contractHelper.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: contractOwner});
535 await contractHelper.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: contractOwner});527 await contractHelper.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: contractOwner});
536 await transferBalanceToEth(api, alice, flipper.options.address, 1000n);528 await helper.eth.transferBalanceFromSubstrate(alice, flipper.options.address, 1000n); // transferBalanceToEth(api, alice, flipper.options.address, 1000n);
537529
530 // Set promotion to the Flipper
538 await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));531 await helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorContract(flipper.options.address));
532
533 // Caller calls Flipper
539 await flipper.methods.flip().send({from: caller});534 await flipper.methods.flip().send({from: caller});
540 expect(await flipper.methods.getValue().call()).to.be.true;535 expect(await flipper.methods.getValue().call()).to.be.true;
541536
537 // The contracts and caller balances have not changed
542 const callerBalance = await helper.balance.getEthereum(caller);538 const callerBalance = await helper.balance.getEthereum(caller);
543 const contractBalanceAfter = await helper.balance.getEthereum(flipper.options.address);539 const contractBalanceAfter = await helper.balance.getEthereum(flipper.options.address);
544
545 expect(callerBalance).to.be.equal(1000n * nominal);540 expect(callerBalance).to.be.equal(1000n * nominal);
546 expect(1000n * nominal > contractBalanceAfter).to.be.true;541 expect(1000n * nominal === contractBalanceAfter).to.be.true;
542
543 // The pallet balance has decreased
547 });544 const palletBalanceAfter = await helper.balance.getSubstrate(palletAddress);
545 expect(palletBalanceAfter < palletBalanceBefore).to.be.true;
548 });546 });
549});547});
550548
553 await beforeEach(this);551 await beforeEach(this);
554 });552 });
555553
556 itWeb3('should remove pallet address from contract sponsors', async ({api, web3, privateKeyWrapper}) => {554 itEth('should remove pallet address from contract sponsors', async ({helper}) => {
557 await usingPlaygrounds(async (helper) => { 555 const caller = await helper.eth.createAccountWithBalance(alice, 1000n);
556 const contractOwner = (await helper.eth.createAccountWithBalance(alice, 1000n)).toLowerCase();
557 const flipper = await helper.eth.deployFlipper(contractOwner);
558 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);558 await helper.eth.transferBalanceFromSubstrate(alice, flipper.options.address);
559 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();
560 const flipper = await deployFlipper(web3, contractOwner);
561 await transferBalanceToEth(api, alice, flipper.options.address);
562 const contractHelper = contractHelpers(web3, contractOwner);559 const contractHelper = helper.ethNativeContract.contractHelpers(contractOwner);
560
563 await contractHelper.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: contractOwner});561 await contractHelper.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: contractOwner});
564 await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));562 await helper.executeExtrinsic(palletAdmin, 'api.tx.appPromotion.sponsorContract', [flipper.options.address], true);
565 await helper.signTransaction(palletAdmin, api.tx.appPromotion.stopSponsoringContract(flipper.options.address));563 await helper.executeExtrinsic(palletAdmin, 'api.tx.appPromotion.stopSponsoringContract', [flipper.options.address], true);
566564
567 expect(await contractHelper.methods.hasSponsor(flipper.options.address).call()).to.be.false; 565 expect(await contractHelper.methods.hasSponsor(flipper.options.address).call()).to.be.false;
568 expect((await api.query.evmContractHelpers.owner(flipper.options.address)).toJSON()).to.be.equal(contractOwner); 566 expect((await helper.api!.query.evmContractHelpers.owner(flipper.options.address)).toJSON()).to.be.equal(contractOwner);
569 expect((await api.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({567 expect((await helper.api!.query.evmContractHelpers.sponsoring(flipper.options.address)).toJSON()).to.deep.equal({
570 disabled: null,568 disabled: null,
571 });569 });
572570
579 // caller payed for call577 // caller payed for call
580 expect(1000n * nominal > callerBalance).to.be.true;578 expect(1000n * nominal > callerBalance).to.be.true;
581 expect(contractBalanceAfter).to.be.equal(1000n * nominal);579 expect(contractBalanceAfter).to.be.equal(1000n * nominal);
582 });
583 });580 });
584581
585 itWeb3('can not be called by non-admin', async ({api, web3, privateKeyWrapper}) => {582 itEth('can not be called by non-admin', async ({helper}) => {
586 await usingPlaygrounds(async (helper) => {
587 const nonAdmin = accounts.pop()!;583 const nonAdmin = accounts.pop()!;
588 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();584 const contractOwner = (await helper.eth.createAccountWithBalance(alice, 1000n)).toLowerCase();
589 const flipper = await deployFlipper(web3, contractOwner);585 const flipper = await helper.eth.deployFlipper(contractOwner);
590586
591 await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));587 await helper.executeExtrinsic(palletAdmin, 'api.tx.appPromotion.sponsorContract', [flipper.options.address]);
592 await expect(helper.signTransaction(nonAdmin, api.tx.appPromotion.stopSponsoringContract(flipper.options.address))).to.be.rejected;588 const stopSponsoringResult = await helper.executeExtrinsic(nonAdmin, 'api.tx.appPromotion.stopSponsoringContract', [flipper.options.address]);
593 });589 expect(stopSponsoringResult.status).to.equal('Fail');
590 expect(stopSponsoringResult.moduleError).to.equal('appPromotion.NoPermission');
594 });591 });
595592
596 itWeb3('should not affect a contract which is not sponsored by pallete', async ({api, web3, privateKeyWrapper}) => {593 itEth('should not affect a contract which is not sponsored by pallete', async ({helper}) => {
597 await usingPlaygrounds(async (helper) => {
598 const nonAdmin = accounts.pop()!;594 const nonAdmin = accounts.pop()!;
599 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();595 const contractOwner = (await helper.eth.createAccountWithBalance(alice, 1000n)).toLowerCase();
600 const flipper = await deployFlipper(web3, contractOwner);596 const flipper = await helper.eth.deployFlipper(contractOwner);
601 const contractHelper = contractHelpers(web3, contractOwner);597 const contractHelper = helper.ethNativeContract.contractHelpers(contractOwner);
602 await expect(contractHelper.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;598 await expect(contractHelper.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.fulfilled;
603599
604 await expect(helper.signTransaction(nonAdmin, api.tx.appPromotion.stopSponsoringContract(flipper.options.address))).to.be.rejected;600 await expect(helper.executeExtrinsic(nonAdmin, 'api.tx.appPromotion.stopSponsoringContract', [flipper.options.address], true)).to.be.rejectedWith('appPromotion.NoPermission');
605 });
606 });601 });
607});602});
608603
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -198,8 +198,21 @@
     }
   `);
   }
-}
-  
+
+  async deployFlipper(signer: string): Promise<Contract> {
+    return await this.helper.ethContract.deployByCode(signer, 'Flipper', `
+    contract Flipper {
+      bool value = false;
+      function flip() public {
+        value = !value;
+      }
+      function getValue() public view returns (bool) {
+        return value;
+      }
+    }
+  `);
+  }
+}  
   
 class EthAddressGroup extends EthGroupBase {
   extractCollectionId(address: string): number {