git.delta.rocks / unique-network / refs/commits / e85b045d6752

difftreelog

Tests up

Maksandre2022-08-30parent: #4ebb3c6.patch.diff
in: master
Some tests are red because of not implemented logic

2 files changed

modifiedtests/src/app-promotion.test.tsdiffbeforeafterboth
44 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 address
48 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);
7575
76 // TODO add helpers to assert bigints. Check balance close to 1076 // TODO add helpers to assert bigints. Check balance close to 100
77 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
8181
82 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);
9393
94 // Can't stake full balance because Alice needs to pay some fee94 // Can't stake full balance because Alice needs to pay some fee
95 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);
9797
98 // 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 locked
99 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;
110110
111 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);
127127
128 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 });
133133
134 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);
140140
141 // staked: [10, 20, 30]; unstaked: 0141 // staked: [100, 200, 300]; unstaked: 0
142 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 stakes
150 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]);
157
158 // Can unstake one stake totally and one more partially
159 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]);
166
167 // Can totally unstake 2 stakes in one tx
168 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 });
177159
178 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 all
183 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 helper
187169
188 // 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);
193171
194 // can't unstake more than have with nonce // TODO not sure we need this assertion172 // can't unstake if there are only pendingUnstakes
195 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);
176
199 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 });
205182
206 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 });
215193
216 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 block
200 // wait it
201 // check balance returned
202 expect.fail('Not implemented');
203 });
204 });
205
206 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);
209
210 await Promise.all(stakers.map(staker => helper.staking.stake(staker, 100n * nominal)));
211 await Promise.all(stakers.map(staker => helper.staking.unstake(staker)));
221212
222 // 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 });
226219
227 // TODO will return balance to "available" state after the period of unstaking is finished, and subtract it from "pendingUnstake
228 // TODO for different accounts in one block is possible220 // TODO for different accounts in one block is possible
229});221});
230222
366 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 });
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
2005 * @param label extra label for log2005 * @param label extra label for log
2006 * @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