difftreelog
Tests up
in: master
Some tests are red because of not implemented logic
2 files changed
tests/src/app-promotion.test.tsdiffbeforeafterboth44 if (!getModuleNames(helper.api!).includes(Pallets.AppPromotion)) this.skip();44 if (!getModuleNames(helper.api!).includes(Pallets.AppPromotion)) this.skip();45 alice = privateKeyWrapper('//Alice');45 alice = privateKeyWrapper('//Alice');46 bob = privateKeyWrapper('//Bob');46 bob = privateKeyWrapper('//Bob');47 palletAdmin = privateKeyWrapper('//Charlie');47 palletAdmin = privateKeyWrapper('//Charlie'); // TODO use custom address48 await helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})));48 await helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})));49 nominal = helper.balance.getOneTokenNominal();49 nominal = helper.balance.getOneTokenNominal();50 await helper.balance.transferToSubstrate(alice, palletAdmin.address, 1000n * nominal);50 await helper.balance.transferToSubstrate(alice, palletAdmin.address, 1000n * nominal);66 it('should change balance state to "locked", add it to "staked" map, and increase "totalStaked" amount', async () => {66 it('should change balance state to "locked", add it to "staked" map, and increase "totalStaked" amount', async () => {67 await usingPlaygrounds(async (helper) => {67 await usingPlaygrounds(async (helper) => {68 const totalStakedBefore = await helper.staking.getTotalStaked();68 const totalStakedBefore = await helper.staking.getTotalStaked();69 const [staker] = await helper.arrange.creteAccounts([10n], alice);69 const [staker] = await helper.arrange.creteAccounts([400n], alice);70 70 71 // Minimum stake amount is 1:71 // Minimum stake amount is 100:72 await expect(helper.staking.stake(staker, nominal - 1n)).to.be.eventually.rejected;72 await expect(helper.staking.stake(staker, 100n * nominal - 1n)).to.be.eventually.rejected;73 await helper.staking.stake(staker, nominal);73 await helper.staking.stake(staker, 100n * nominal);74 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(nominal);74 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(100n * nominal);757576 // TODO add helpers to assert bigints. Check balance close to 1076 // TODO add helpers to assert bigints. Check balance close to 10077 expect(await helper.balance.getSubstrate(staker.address) - 9n * nominal >= (nominal / 2n)).to.be.true;77 expect(await helper.balance.getSubstrate(staker.address) - 99n * nominal >= (nominal / 2n)).to.be.true;78 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(nominal);78 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(100n * nominal);79 // it is potentially flaky test. Promotion can credited some tokens. Maybe we need to use closeTo? 79 // it is potentially flaky test. Promotion can credited some tokens. Maybe we need to use closeTo? 80 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore + nominal); // total tokens amount staked in app-promotion increased 80 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore + 100n * nominal); // total tokens amount staked in app-promotion increased 818182 await helper.staking.stake(staker, 2n * nominal);82 await helper.staking.stake(staker, 200n * nominal);83 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(3n * nominal);83 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(300n * nominal);84 84 85 const stakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map((x) => x[1]);85 const stakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map((x) => x[1]);86 expect(stakedPerBlock).to.be.deep.equal([nominal, 2n * nominal]);86 expect(stakedPerBlock).to.be.deep.equal([100n * nominal, 200n * nominal]);87 });87 });88 });88 });89 89 90 it('should reject transaction if stake amount is more than total free balance', async () => {90 it('should reject transaction if stake amount is more than total free balance', async () => {91 await usingPlaygrounds(async helper => { 91 await usingPlaygrounds(async helper => { 92 const [staker] = await helper.arrange.creteAccounts([10n], alice);92 const [staker] = await helper.arrange.creteAccounts([300n], alice);939394 // Can't stake full balance because Alice needs to pay some fee94 // Can't stake full balance because Alice needs to pay some fee95 await expect(helper.staking.stake(staker, 10n * nominal)).to.be.eventually.rejected;95 await expect(helper.staking.stake(staker, 300n * nominal)).to.be.eventually.rejected;96 await helper.staking.stake(staker, 7n * nominal);96 await helper.staking.stake(staker, 150n * nominal);979798 // Can't stake 4 tkn because Alice has ~3 free tkn, and 7 locked98 // Can't stake 4 tkn because Alice has ~3 free tkn, and 7 locked99 await expect(helper.staking.stake(staker, 4n * nominal)).to.be.eventually.rejected; 99 await expect(helper.staking.stake(staker, 150n * nominal)).to.be.eventually.rejected; 100 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(7n * nominal);100 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(150n * nominal);101 });101 });102 });102 });103 103 104 it('for different accounts in one block is possible', async () => {104 it('for different accounts in one block is possible', async () => {105 await usingPlaygrounds(async helper => {105 await usingPlaygrounds(async helper => {106 const crowd = await helper.arrange.creteAccounts([10n, 10n, 10n, 10n], alice);106 const crowd = await helper.arrange.creteAccounts([1000n, 1000n, 1000n, 1000n], alice);107 107 108 const crowdStartsToStake = crowd.map(user => helper.staking.stake(user, nominal));108 const crowdStartsToStake = crowd.map(user => helper.staking.stake(user, 100n * nominal));109 await expect(Promise.all(crowdStartsToStake)).to.be.eventually.fulfilled;109 await expect(Promise.all(crowdStartsToStake)).to.be.eventually.fulfilled;110110111 const crowdStakes = await Promise.all(crowd.map(address => helper.staking.getTotalStaked({Substrate: address.address})));111 const crowdStakes = await Promise.all(crowd.map(address => helper.staking.getTotalStaked({Substrate: address.address})));112 expect(crowdStakes).to.deep.equal([nominal, nominal, nominal, nominal]);112 expect(crowdStakes).to.deep.equal([100n * nominal, 100n * nominal, 100n * nominal, 100n * nominal]);113 });113 });114 });114 });115 // TODO it('Staker stakes 5 times in one block with nonce');115 // TODO it('Staker stakes 5 times in one block with nonce');121 it('should change balance state to "reserved", add it to "pendingUnstake" map, and subtract it from totalStaked', async () => {121 it('should change balance state to "reserved", add it to "pendingUnstake" map, and subtract it from totalStaked', async () => {122 await usingPlaygrounds(async helper => {122 await usingPlaygrounds(async helper => {123 const totalStakedBefore = await helper.staking.getTotalStaked();123 const totalStakedBefore = await helper.staking.getTotalStaked();124 const [staker] = await helper.arrange.creteAccounts([10n], alice);124 const [staker] = await helper.arrange.creteAccounts([1000n], alice);125 await helper.staking.stake(staker, 5n * nominal);125 await helper.staking.stake(staker, 500n * nominal);126 await helper.staking.unstake(staker, 3n * nominal);126 await helper.staking.unstake(staker);127127128 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(3n * nominal);128 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(500n * nominal);129 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(2n * nominal);129 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(0n);130 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore + 2n * nominal);130 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore);131 });131 });132 });132 });133133134 it('should remove from the "staked" map starting from the oldest entry', async () => {134 it('should remove multiple stakes', async () => {135 await usingPlaygrounds(async helper => {135 await usingPlaygrounds(async helper => {136 const [staker] = await helper.arrange.creteAccounts([100n], alice);136 const [staker] = await helper.arrange.creteAccounts([1000n], alice);137 await helper.staking.stake(staker, 10n * nominal);137 await helper.staking.stake(staker, 100n * nominal);138 await helper.staking.stake(staker, 20n * nominal);138 await helper.staking.stake(staker, 200n * nominal);139 await helper.staking.stake(staker, 30n * nominal);139 await helper.staking.stake(staker, 300n * nominal);140140141 // staked: [10, 20, 30]; unstaked: 0141 // staked: [100, 200, 300]; unstaked: 0142 let pendingUnstake = await helper.staking.getPendingUnstake({Substrate: staker.address});142 let pendingUnstake = await helper.staking.getPendingUnstake({Substrate: staker.address});143 let unstakedPerBlock = (await helper.staking.getPendingUnstakePerBlock({Substrate: staker.address})).map(stake => stake[1]);143 let unstakedPerBlock = (await helper.staking.getPendingUnstakePerBlock({Substrate: staker.address})).map(stake => stake[1]);144 let stakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(stake => stake[1]);144 let stakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(stake => stake[1]);145 expect(pendingUnstake).to.be.deep.equal(0n);145 expect(pendingUnstake).to.be.deep.equal(0n);146 expect(unstakedPerBlock).to.be.deep.equal([]);146 expect(unstakedPerBlock).to.be.deep.equal([]);147 expect(stakedPerBlock).to.be.deep.equal([10n * nominal, 20n * nominal, 30n * nominal]);147 expect(stakedPerBlock).to.be.deep.equal([100n * nominal, 200n * nominal, 300n * nominal]);148 148 149 // Can unstake the part of a stake149 // Can unstake multiple stakes150 await helper.staking.unstake(staker, 5n * nominal);150 await helper.staking.unstake(staker);151 pendingUnstake = await helper.staking.getPendingUnstake({Substrate: staker.address});151 pendingUnstake = await helper.staking.getPendingUnstake({Substrate: staker.address});152 unstakedPerBlock = (await helper.staking.getPendingUnstakePerBlock({Substrate: staker.address})).map(stake => stake[1]);152 unstakedPerBlock = (await helper.staking.getPendingUnstakePerBlock({Substrate: staker.address})).map(stake => stake[1]);153 stakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(stake => stake[1]);153 stakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(stake => stake[1]);154 expect(pendingUnstake).to.be.equal(5n * nominal);154 expect(pendingUnstake).to.be.equal(600n * nominal);155 expect(stakedPerBlock).to.be.deep.equal([5n * nominal, 20n * nominal, 30n * nominal]);155 expect(stakedPerBlock).to.be.deep.equal([]);156 expect(unstakedPerBlock).to.be.deep.equal([5n * nominal]);156 expect(unstakedPerBlock).to.be.deep.equal([600n * nominal]);157158 // Can unstake one stake totally and one more partially159 await helper.staking.unstake(staker, 10n * nominal);160 pendingUnstake = await helper.staking.getPendingUnstake({Substrate: staker.address});161 unstakedPerBlock = (await helper.staking.getPendingUnstakePerBlock({Substrate: staker.address})).map(stake => stake[1]);162 stakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(stake => stake[1]);163 expect(pendingUnstake).to.be.equal(15n * nominal);164 expect(stakedPerBlock).to.be.deep.equal([15n * nominal, 30n * nominal]);165 expect(unstakedPerBlock).to.deep.equal([5n * nominal, 10n * nominal]);166167 // Can totally unstake 2 stakes in one tx168 await helper.staking.unstake(staker, 45n * nominal);169 pendingUnstake = await helper.staking.getPendingUnstake({Substrate: staker.address});170 unstakedPerBlock = (await helper.staking.getPendingUnstakePerBlock({Substrate: staker.address})).map(stake => stake[1]);171 stakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(stake => stake[1]);172 expect(pendingUnstake).to.be.equal(60n * nominal);173 expect(stakedPerBlock).to.deep.equal([]);174 expect(unstakedPerBlock).to.deep.equal([5n * nominal, 10n * nominal, 45n * nominal]);175 });157 });176 });158 });177159178 it('should reject transaction if unstake amount is greater than staked', async () => {160 it('should not have any effects if no active stakes', async () => {179 await usingPlaygrounds(async (helper) => {161 await usingPlaygrounds(async (helper) => {180 const [staker] = await helper.arrange.creteAccounts([10n], alice);162 const [staker] = await helper.arrange.creteAccounts([1000n], alice);181 163 182 // can't unstsake more than one stake amount164 // unstake has no effect if no stakes at all183 await helper.staking.stake(staker, 1n * nominal);184 await expect(helper.staking.unstake(staker, 1n * nominal + 1n)).to.be.eventually.rejected;165 await helper.staking.unstake(staker);185 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(0n);166 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(0n);186 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(1n * nominal);167 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(0n);168 expect(await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(999n); // TODO bigint closeTo helper187169188 // can't unstsake more than two stakes amount170 // TODO stake() unstake() waitUnstaked() unstake();189 await helper.staking.stake(staker, 1n * nominal);190 await expect(helper.staking.unstake(staker, 2n * nominal + 1n)).to.be.eventually.rejected;191 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(0n);192 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(2n * nominal);193171194 // can't unstake more than have with nonce // TODO not sure we need this assertion172 // can't unstake if there are only pendingUnstakes195 const nonce1 = await helper.chain.getNonce(staker.address);173 await helper.staking.stake(staker, 100n * nominal);196 const nonce2 = nonce1 + 1;197 const unstakeMoreThanHaveWithNonce = Promise.all([174 await helper.staking.unstake(staker);198 helper.signTransaction(staker, helper.constructApiCall('api.tx.promotion.unstake', [1n * nominal]), 'unstaking 1', {nonce: nonce1}),175 await helper.staking.unstake(staker);176199 helper.signTransaction(staker, helper.constructApiCall('api.tx.promotion.unstake', [1n * nominal + 1n]), 'unstaking 1+', {nonce: nonce2}),177 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(100n * nominal);200 ]);201 await expect(unstakeMoreThanHaveWithNonce).to.be.rejected;178 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(100n * nominal);202 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(1n * nominal);179 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(0n);203 });180 });204 });181 });205182206 it('should allow to unstake even smallest unit', async () => {183 it('should keep different unlocking block for each unlocking stake', async () => {207 await usingPlaygrounds(async (helper) => {184 await usingPlaygrounds(async (helper) => {208 const [staker] = await helper.arrange.creteAccounts([10n], alice);185 const [staker] = await helper.arrange.creteAccounts([1000n], alice);209 await helper.staking.stake(staker, nominal);186 await helper.staking.stake(staker, 100n * nominal);210 // unstake .000...001 is possible187 await helper.staking.unstake(staker);211 await helper.staking.unstake(staker, 1n);188 await helper.staking.stake(staker, 100n * nominal);212 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(1n);189 await helper.staking.unstake(staker);190 expect.fail('Not implemented');213 });191 });214 });192 });215193216 it('should work fine if stake amount is smallest unit', async () => {194 it('should unlock balance after unlocking period ends and subtract it from "pendingUnstake"', async () => {217 await usingPlaygrounds(async (helper) => {195 await usingPlaygrounds(async (helper) => {218 const [staker] = await helper.arrange.creteAccounts([10n], alice);196 const [staker] = await helper.arrange.creteAccounts([1000n], alice);219 await helper.staking.stake(staker, nominal);197 await helper.staking.stake(staker, 100n * nominal);220 await helper.staking.unstake(staker, nominal - 1n);198 await helper.staking.unstake(staker);199 // get unstake from block200 // wait it201 // check balance returned202 expect.fail('Not implemented');203 });204 });205206 it('should be possible for different accounts in one block', async () => {207 await usingPlaygrounds(async (helper) => {208 const stakers = await helper.arrange.creteAccounts([200n, 200n, 200n, 200n, 200n], alice);209210 await Promise.all(stakers.map(staker => helper.staking.stake(staker, 100n * nominal)));211 await Promise.all(stakers.map(staker => helper.staking.unstake(staker)));221212222 // Everything fine, blockchain alive213 await Promise.all(stakers.map(async (staker) => {223 await helper.nft.mintCollection(staker, {name: 'name', description: 'description', tokenPrefix: 'prefix'});214 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(100n * nominal);215 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(0n);216 }));224 });217 });225 });218 });226219227 // TODO will return balance to "available" state after the period of unstaking is finished, and subtract it from "pendingUnstake228 // TODO for different accounts in one block is possible220 // TODO for different accounts in one block is possible229});221});230222366 358 367 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;359 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;368 360 369 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collection.collectionId))).to.be.eventually.rejected;361 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.promotion.stopSponsoringCollection(collection.collectionId))).to.be.eventually.rejected;370 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});362 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});371 });363 });372 });364 });377 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'});378 370 379 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;371 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;380 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collection.collectionId))).to.be.eventually.fulfilled;372 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsoringCollection(collection.collectionId))).to.be.eventually.fulfilled;381 373 382 expect((await collection.getData())?.raw.sponsorship).to.be.equal('Disabled');374 expect((await collection.getData())?.raw.sponsorship).to.be.equal('Disabled');383 });375 });389 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: collectionOwner.address});381 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: collectionOwner.address});390 await collection.confirmSponsorship(collectionOwner);382 await collection.confirmSponsorship(collectionOwner);391 383 392 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collection.collectionId))).to.be.eventually.rejected;384 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsoringCollection(collection.collectionId))).to.be.eventually.rejected;393 385 394 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: collectionOwner.address});386 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: collectionOwner.address});395 });387 });401 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});393 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});402 394 403 await collection.burn(collectionOwner);395 await collection.burn(collectionOwner);404 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collection.collectionId))).to.be.eventually.rejected;396 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsoringCollection(collection.collectionId))).to.be.eventually.rejected;405 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(999999999))).to.be.eventually.rejected;397 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsoringCollection(999999999))).to.be.eventually.rejected;406 });398 });407 });399 });408});400});577describe('app-promotion rewards', () => {569describe('app-promotion rewards', () => {578 it('should credit 0.05% for staking period', async () => { 570 it('should credit 0.05% for staking period', async () => { 579 await usingPlaygrounds(async helper => {571 await usingPlaygrounds(async helper => {580 const [staker] = await helper.arrange.creteAccounts([50n], alice);572 const [staker] = await helper.arrange.creteAccounts([5000n], alice);581 573 582 await helper.staking.stake(staker, 1n * nominal);574 await helper.staking.stake(staker, 100n * nominal);583 await helper.staking.stake(staker, 2n * nominal);575 await helper.staking.stake(staker, 200n * nominal);584 await waitForRelayBlock(helper.api!, 36);576 await waitForRelayBlock(helper.api!, 55);577 await helper.signTransaction(palletAdmin, helper.api!.tx.promotion.payoutStakers(50));585 578 586 const totalStakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(s => s[1]);579 const totalStakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(s => s[1]);587 expect(totalStakedPerBlock).to.be.deep.equal([calculateIncome(nominal, 10n), calculateIncome(2n * nominal, 10n)]);580 expect(totalStakedPerBlock).to.be.deep.equal([calculateIncome(100n * nominal, 10n), calculateIncome(200n * nominal, 10n)]);588 });581 });589 });582 });590 583 596 589 597 it('should bring compound interest', async () => {590 it('should bring compound interest', async () => {598 await usingPlaygrounds(async helper => {591 await usingPlaygrounds(async helper => {599 const [staker] = await helper.arrange.creteAccounts([80n], alice);592 const [staker] = await helper.arrange.creteAccounts([800n], alice);600 593 601 await helper.staking.stake(staker, 10n * nominal);594 await helper.staking.stake(staker, 100n * nominal);602 await helper.staking.stake(staker, 20n * nominal);595 await helper.staking.stake(staker, 200n * nominal);603 await helper.staking.stake(staker, 30n * nominal);596 await helper.staking.stake(staker, 300n * nominal);604 597 605 await waitForRelayBlock(helper.api!, 34);598 await waitForRelayBlock(helper.api!, 34);599 await helper.signTransaction(palletAdmin, helper.api!.tx.promotion.payoutStakers(50));606 let totalStakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(s => s[1]);600 let totalStakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(s => s[1]);607 expect(totalStakedPerBlock).to.deep.equal([calculateIncome(10n * nominal, 10n), calculateIncome(20n * nominal, 10n), calculateIncome(30n * nominal, 10n)]);601 expect(totalStakedPerBlock).to.deep.equal([calculateIncome(100n * nominal, 10n), calculateIncome(200n * nominal, 10n), calculateIncome(300n * nominal, 10n)]);608 602 609 await waitForRelayBlock(helper.api!, 20);603 await waitForRelayBlock(helper.api!, 20);604 await helper.signTransaction(palletAdmin, helper.api!.tx.promotion.payoutStakers(50));610 totalStakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(s => s[1]);605 totalStakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(s => s[1]);611 expect(totalStakedPerBlock).to.deep.equal([calculateIncome(10n * nominal, 10n, 2), calculateIncome(20n * nominal, 10n, 2), calculateIncome(30n * nominal, 10n, 2)]); 606 expect(totalStakedPerBlock).to.deep.equal([calculateIncome(10n * nominal, 10n, 2), calculateIncome(20n * nominal, 10n, 2), calculateIncome(30n * nominal, 10n, 2)]); 612 });607 });tests/src/util/playgrounds/unique.tsdiffbeforeafterboth2005 * @param label extra label for log2005 * @param label extra label for log2006 * @returns 2006 * @returns 2007 */2007 */2008 async unstake(signer: TSigner, amountToUnstake: bigint, label?: string): Promise<boolean> {2008 async unstake(signer: TSigner, label?: string): Promise<boolean> {2009 if(typeof label === 'undefined') label = `${signer.address} amount: ${amountToUnstake}`;2009 if(typeof label === 'undefined') label = `${signer.address}`;2010 const unstakeResult = await this.helper.executeExtrinsic(2010 const unstakeResult = await this.helper.executeExtrinsic(2011 signer,2011 signer,2012 'api.tx.promotion.unstake', [amountToUnstake],2012 'api.tx.promotion.unstake', [],2013 true, `unstake failed for ${label}`,2013 true, `unstake failed for ${label}`,2014 );2014 );2015 // TODO extract info from unstakeResult2015 // TODO extract info from unstakeResult