difftreelog
Use itEth
in: master
2 files changed
tests/src/app-promotion.test.tsdiffbeforeafterboth272728import {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;343538const 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 relay41const UNLOCKING_PERIOD = 10n; // 20 blocks of parachain42const UNLOCKING_PERIOD = 10n; // 10 blocks of parachain42const rewardAvailableInBlock = (stakedInBlock: bigint) => (stakedInBlock - stakedInBlock % LOCKING_PERIOD) + (LOCKING_PERIOD * 2n);43const rewardAvailableInBlock = (stakedInBlock: bigint) => (stakedInBlock - stakedInBlock % LOCKING_PERIOD) + (LOCKING_PERIOD * 2n);434444const 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();656666 // 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);697070 // 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 90072 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);979898 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');99100100 // After unstake can stake again101 // After unstake can stake again101 await helper.staking.unstake(staker);102 await helper.staking.unstake(staker);107 const staker = accounts.pop()!;108 const staker = accounts.pop()!;108109109 // Can't stake full balance because Alice needs to pay some fee110 // Can't stake full balance because Alice needs to pay some fee110 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);112113113 // 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;123124124 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 reserved141 // 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 sudo249 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;251252252 // Alice can253 // Alice can253 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 });269270270 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});281282309310310 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 });315316318 319 319 // Can set sponsoring for collection without sponsor320 // Can set sponsoring for collection without sponsor320 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});323324324 // Can set sponsoring for collection with unconfirmed sponsor325 // Can set sponsoring for collection with unconfirmed sponsor325 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});329330330 // Can set sponsoring for collection with confirmed sponsor331 // Can set sponsoring for collection with confirmed sponsor331 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 });336337339 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 owner345 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});357358358 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 existed366 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 burned368 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);370371371 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});374375381 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 });389390409 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});426427429 await beforeEach(this);430 await beforeEach(this);430 });431 });431432432 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);437434 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);437438 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 });449448450 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);453452 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);455456 await expect(contractMethods.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;457455458 // Contract is self sponsored456 // Contract is self sponsored459 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 });464462465 // set promotion sponsoring463 // set promotion sponsoring466 await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));464 await helper.executeExtrinsic(palletAdmin, 'api.tx.appPromotion.sponsorContract', [flipper.options.address], true);467465468 // new sponsor is pallet address466 // new sponsor is pallet address469 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 });478475479 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);484480485 // contract sponsored by pallet481 // contract sponsored by pallet486 await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));482 await helper.executeExtrinsic(palletAdmin, 'api.tx.appPromotion.sponsorContract', [flipper.options.address], true);487483488 // owner sets self sponsoring484 // owner sets self sponsoring489 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;490486491 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 });500495501 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);507501508 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;509503510 // nonAdmin calls sponsorContract504 // nonAdmin calls sponsorContract511 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');512506513 // 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 });520521 itWeb3('should be rejected for non-contract address', async ({api, web3, privateKeyWrapper}) => {522 await usingPlaygrounds(async (helper) => {523524 });525 });526 });513 });527514528 itWeb3('should actually sponsor transactions', async ({api, web3, privateKeyWrapper}) => {515 itEth('should actually sponsor transactions', async ({helper}) => {529 await usingPlaygrounds(async (helper) => { 516 // Contract caller530 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 flipper521 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 tx534 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);537529530 // Set promotion to the Flipper538 await helper.signTransaction(palletAdmin, api.tx.appPromotion.sponsorContract(flipper.options.address));531 await helper.signTransaction(palletAdmin, helper.api!.tx.appPromotion.sponsorContract(flipper.options.address));532533 // Caller calls Flipper539 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;541536537 // The contracts and caller balances have not changed542 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);544545 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;542543 // The pallet balance has decreased547 });544 const palletBalanceAfter = await helper.balance.getSubstrate(palletAddress);545 expect(palletBalanceAfter < palletBalanceBefore).to.be.true;548 });546 });549});547});550548553 await beforeEach(this);551 await beforeEach(this);554 });552 });555553556 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);560563 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);566564567 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 });572570579 // caller payed for call577 // caller payed for call580 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 });584581585 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);590586591 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 });595592596 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;603599604 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});608603tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth199 `);199 `);200 }200 }201202 async deployFlipper(signer: string): Promise<Contract> {203 return await this.helper.ethContract.deployByCode(signer, 'Flipper', `204 contract Flipper {205 bool value = false;206 function flip() public {207 value = !value;208 }209 function getValue() public view returns (bool) {210 return value;211 }212 }213 `);214 }201}215} 202 216 203