difftreelog
Merge branch 'feature/app-staking' of https://github.com/UniqueNetwork/unique-chain into feature/app-staking
in: master
1 file changed
tests/src/app-promotion.test.tsdiffbeforeafterboth33const expect = chai.expect;33const expect = chai.expect;343435let alice: IKeyringPair;35let alice: IKeyringPair;36let bob: IKeyringPair;37let palletAdmin: IKeyringPair;36let palletAdmin: IKeyringPair;38let nominal: bigint;37let nominal: bigint;39let promotionStartBlock: number | null = null;38let promotionStartBlock: number | null = null;40const palletAddress = calculatePalleteAddress('appstake');39const palletAddress = calculatePalleteAddress('appstake');40let accounts: IKeyringPair[] = [];414142before(async function () {42before(async function () {43 await usingPlaygrounds(async (helper, privateKeyWrapper) => {43 await usingPlaygrounds(async (helper, privateKeyWrapper) => {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');47 palletAdmin = privateKeyWrapper('//Charlie'); // TODO use custom address46 palletAdmin = privateKeyWrapper('//Charlie'); // TODO use custom address48 await helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})));47 await helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})));49 nominal = helper.balance.getOneTokenNominal();48 nominal = helper.balance.getOneTokenNominal();53 promotionStartBlock = (await helper.api!.query.parachainSystem.lastRelayChainBlockNumber()).toNumber();52 promotionStartBlock = (await helper.api!.query.parachainSystem.lastRelayChainBlockNumber()).toNumber();54 }53 }55 await helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.startAppPromotion(promotionStartBlock!)));54 await helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.startAppPromotion(promotionStartBlock!)));55 accounts = await helper.arrange.createCrowd(100, 1000n, alice); // create accounts-pool to speed up tests56 });56 });57});57});585865describe('app-promotions.stake extrinsic', () => {65describe('app-promotions.stake extrinsic', () => {66 it('should "lock" staking balance, add it to "staked" map, and increase "totalStaked" amount', async () => {66 it('should "lock" staking balance, 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 [staker, recepient] = [accounts.pop()!, accounts.pop()!];69 const [staker, recepient] = await helper.arrange.createAccounts([400n, 0n], alice);69 const totalStakedBefore = await helper.staking.getTotalStaked();707071 // Minimum stake amount is 100:71 // Minimum stake amount is 100:72 await expect(helper.staking.stake(staker, 100n * 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, 100n * nominal);73 await helper.staking.stake(staker, 100n * nominal);747475 // Staker balance is: miscFrozen: 100, feeFrozen: 100, reserved: 0n...75 // Staker balance is: miscFrozen: 100, feeFrozen: 100, reserved: 0n...76 // ...so he can not transfer 30076 // ...so he can not transfer 90077 expect (await helper.balance.getSubstrateFull(staker.address)).to.contain({miscFrozen: 100n * nominal, feeFrozen: 100n * nominal, reserved: 0n});77 expect (await helper.balance.getSubstrateFull(staker.address)).to.contain({miscFrozen: 100n * nominal, feeFrozen: 100n * nominal, reserved: 0n});78 await expect(helper.balance.transferToSubstrate(staker, recepient.address, 300n * nominal)).to.be.rejected;78 await expect(helper.balance.transferToSubstrate(staker, recepient.address, 900n * nominal)).to.be.rejected;79 79 80 // 100 -> 24 locked 100; staked 0; 24 => locked 100 staked 10081 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(100n * nominal);80 expect(await helper.staking.getTotalStakingLocked({Substrate: staker.address})).to.be.equal(100n * nominal);82 // TODO should be 083 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(100n * nominal);81 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(100n * nominal);84 expect(await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(399n);82 expect(await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(999n);85 // it is potentially flaky test. Promotion can credited some tokens. Maybe we need to use closeTo? 83 // it is potentially flaky test. Promotion can credited some tokens. Maybe we need to use closeTo? 86 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore + 100n * nominal); // total tokens amount staked in app-promotion increased 84 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore + 100n * nominal); // total tokens amount staked in app-promotion increased 878593 });91 });94 });92 });95 9394 it('should allow to stake with nonce', async () => {95 await usingPlaygrounds(async (helper) => {96 const staker = accounts.pop()!;97 const transactions = [];98 for (let nonce = 0; nonce < 9; nonce++) {99 transactions.push(helper.signTransaction(staker, helper.api?.tx.promotion.stake(100n * nominal), 'Staker stakes with nonce', {nonce}));100 }101 await Promise.allSettled(transactions);102103 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(900n * nominal);104 });105 });106 96 it('should reject transaction if stake amount is more than total free balance minus frozen', async () => {107 it('should reject transaction if stake amount is more than total free balance minus frozen', async () => {97 await usingPlaygrounds(async helper => { 108 await usingPlaygrounds(async helper => { 98 const [staker] = await helper.arrange.createAccounts([300n], alice);109 const staker = accounts.pop()!;99110100 // Can't stake full balance because Alice needs to pay some fee111 // Can't stake full balance because Alice needs to pay some fee101 await expect(helper.staking.stake(staker, 300n * nominal)).to.be.eventually.rejected;112 await expect(helper.staking.stake(staker, 1000n * nominal)).to.be.eventually.rejected;102 await helper.staking.stake(staker, 150n * nominal);113 await helper.staking.stake(staker, 500n * nominal);103114104 // Can't stake 150 tkn because Alice has Less than 150 free - frozen tokens;115 // Can't stake 500 tkn because Alice has Less than 500 transferable;105 await expect(helper.staking.stake(staker, 150n * nominal)).to.be.eventually.rejected; 116 await expect(helper.staking.stake(staker, 500n * nominal)).to.be.eventually.rejected; 106 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(150n * nominal);117 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(500n * nominal);107 });118 });108 });119 });109 120 110 it('for different accounts in one block is possible', async () => {121 it('for different accounts in one block is possible', async () => {111 await usingPlaygrounds(async helper => {122 await usingPlaygrounds(async helper => {112 const crowd = await helper.arrange.createAccounts([1000n, 1000n, 1000n, 1000n], alice);123 const crowd = [accounts.pop()!, accounts.pop()!, accounts.pop()!, accounts.pop()!];113 124 114 const crowdStartsToStake = crowd.map(user => helper.staking.stake(user, 100n * nominal));125 const crowdStartsToStake = crowd.map(user => helper.staking.stake(user, 100n * nominal));115 await expect(Promise.all(crowdStartsToStake)).to.be.eventually.fulfilled;126 await expect(Promise.all(crowdStartsToStake)).to.be.eventually.fulfilled;119 });130 });120 });131 });132133 it('should allow to create maximum 10 stakes for account', async () => {134135 });121});136});122137123describe('unstake balance extrinsic', () => { 138describe('unstake balance extrinsic', () => { 124 it('should change balance state to "reserved", add it to "pendingUnstake" map, and subtract it from totalStaked', async () => {139 it('should change balance state from "frozen" to "reserved", add it to "pendingUnstake" map, and subtract it from totalStaked', async () => {125 await usingPlaygrounds(async helper => {140 await usingPlaygrounds(async helper => {126 const totalStakedBefore = await helper.staking.getTotalStaked();141 const [staker, recepient] = [accounts.pop()!, accounts.pop()!];127 const [staker, recepient] = await helper.arrange.createAccounts([600n, 0n], alice);142 const totalStakedBefore = await helper.staking.getTotalStaked();128 await helper.staking.stake(staker, 500n * nominal);143 await helper.staking.stake(staker, 900n * nominal);129 await helper.staking.unstake(staker);144 await helper.staking.unstake(staker);130145131 // balance state still146 // Right after unstake balance is reserved132133 // Stakers balance now: {free: <100n, reserved: 500n, miscFrozen: 0, feeFrozen: 0};134 // Staker can not transfer 147 // Staker can not transfer 135 // TODO expect(await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 500n * nominal, miscFrozen: 0n, feeFrozen: 0n});148 expect(await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 900n * nominal, miscFrozen: 0n, feeFrozen: 0n});136 await expect(helper.balance.transferToSubstrate(staker, recepient.address, 100n * nominal)).to.be.rejected;149 await expect(helper.balance.transferToSubstrate(staker, recepient.address, 100n * nominal)).to.be.rejected;137138 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(500n * nominal);150 expect(await helper.staking.getPendingUnstake({Substrate: staker.address})).to.be.equal(900n * nominal);139 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(0n);151 expect(await helper.staking.getTotalStaked({Substrate: staker.address})).to.be.equal(0n);140 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore);152 expect(await helper.staking.getTotalStaked()).to.be.equal(totalStakedBefore);141 });153 });142 });154 });143155144 it('should unlock balance after unlocking period ends and subtract it from "pendingUnstake"', async () => {156 it('should unlock balance after unlocking period ends and subtract it from "pendingUnstake"', async () => {145 await usingPlaygrounds(async (helper) => {157 await usingPlaygrounds(async (helper) => {146 const [staker] = await helper.arrange.createAccounts([1000n], alice);158 const staker = accounts.pop()!;147 await helper.staking.stake(staker, 100n * nominal);159 await helper.staking.stake(staker, 100n * nominal);148 await helper.staking.unstake(staker);160 await helper.staking.unstake(staker);149 await waitForRelayBlock(helper.api!, 20);150161151 // Wait for unstaking period. Balance now free ~1000; reserved, frozen, miscFrozeb: 0n162 // Wait for unstaking period. Balance now free ~1000; reserved, frozen, miscFrozeb: 0n152 await waitForRelayBlock(helper.api!, 20);163 await waitForRelayBlock(helper.api!, 20);153 expect(await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 0n * nominal, miscFrozen: 0n, feeFrozen: 0n});164 expect(await helper.balance.getSubstrateFull(staker.address)).to.deep.contain({reserved: 0n * nominal, miscFrozen: 0n, feeFrozen: 0n});154 expect(await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(999n);165 expect(await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(999n);166167 // staker can transfer:168 await helper.balance.transferToSubstrate(staker, alice.address, 998n * nominal);169 expect(await helper.balance.getSubstrate(staker.address) / nominal).to.be.equal(1n);155 });170 });156 });171 });157172158 it('should successfully unstake multiple stakes', async () => {173 it('should successfully unstake multiple stakes', async () => {159 await usingPlaygrounds(async helper => {174 await usingPlaygrounds(async helper => {160 const [staker] = await helper.arrange.createAccounts([1000n], alice);175 const staker = accounts.pop()!;161 await helper.staking.stake(staker, 100n * nominal);176 await helper.staking.stake(staker, 100n * nominal);162 await helper.staking.stake(staker, 200n * nominal);177 await helper.staking.stake(staker, 200n * nominal);163 await helper.staking.stake(staker, 300n * nominal);178 await helper.staking.stake(staker, 300n * nominal);188203189 it('should not have any effects if no active stakes', async () => {204 it('should not have any effects if no active stakes', async () => {190 await usingPlaygrounds(async (helper) => {205 await usingPlaygrounds(async (helper) => {191 const [staker] = await helper.arrange.createAccounts([1000n], alice);206 const staker = accounts.pop()!;192 207 193 // unstake has no effect if no stakes at all208 // unstake has no effect if no stakes at all194 await helper.staking.unstake(staker);209 await helper.staking.unstake(staker);211226212 it('should keep different unlocking block for each unlocking stake', async () => {227 it('should keep different unlocking block for each unlocking stake', async () => {213 await usingPlaygrounds(async (helper) => {228 await usingPlaygrounds(async (helper) => {214 const [staker] = await helper.arrange.createAccounts([1000n], alice);229 const staker = accounts.pop()!;215 await helper.staking.stake(staker, 100n * nominal);230 await helper.staking.stake(staker, 100n * nominal);216 await helper.staking.unstake(staker);231 await helper.staking.unstake(staker);217 await helper.staking.stake(staker, 120n * nominal);232 await helper.staking.stake(staker, 120n * nominal);226241227 it('should be possible for different accounts in one block', async () => {242 it('should be possible for different accounts in one block', async () => {228 await usingPlaygrounds(async (helper) => {243 await usingPlaygrounds(async (helper) => {229 const stakers = await helper.arrange.createAccounts([200n, 200n, 200n, 200n, 200n], alice);244 const stakers = [accounts.pop()!, accounts.pop()!, accounts.pop()!, accounts.pop()!, accounts.pop()!];230245231 await Promise.all(stakers.map(staker => helper.staking.stake(staker, 100n * nominal)));246 await Promise.all(stakers.map(staker => helper.staking.stake(staker, 100n * nominal)));232 await Promise.all(stakers.map(staker => helper.staking.unstake(staker)));247 await Promise.all(stakers.map(staker => helper.staking.unstake(staker)));244describe('Admin adress', () => {259describe('Admin adress', () => {245 it('can be set by sudo only', async () => {260 it('can be set by sudo only', async () => {246 await usingPlaygrounds(async (helper) => {261 await usingPlaygrounds(async (helper) => {262 const nonAdmin = accounts.pop()!;247 // Bob can not set admin not from himself nor as a sudo263 // nonAdmin can not set admin not from himself nor as a sudo248 await expect(helper.signTransaction(bob, helper.api!.tx.promotion.setAdminAddress({Substrate: bob.address}))).to.be.eventually.rejected;264 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.promotion.setAdminAddress({Substrate: nonAdmin.address}))).to.be.eventually.rejected;249 await expect(helper.signTransaction(bob, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: bob.address})))).to.be.eventually.rejected;265 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: nonAdmin.address})))).to.be.eventually.rejected;250266251 // Alice can267 // Alice can252 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.eventually.fulfilled;268 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.eventually.fulfilled;257 // We are not going to set an eth address as a sponsor,273 // We are not going to set an eth address as a sponsor,258 // but we do want to check, it doesn't break anything;274 // but we do want to check, it doesn't break anything;259 await usingPlaygrounds(async (helper) => {275 await usingPlaygrounds(async (helper) => {260 const [charlie] = await helper.arrange.createAccounts([10n], alice);276 const account = accounts.pop()!;261 const ethCharlie = helper.address.substrateToEth(charlie.address); 277 const ethAccount = helper.address.substrateToEth(account.address); 262 // Alice sets Ethereum address as a sudo. Then Substrate address back...278 // Alice sets Ethereum address as a sudo. Then Substrate address back...263 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Ethereum: ethCharlie})))).to.be.eventually.fulfilled;279 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Ethereum: ethAccount})))).to.be.eventually.fulfilled;264 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.eventually.fulfilled;280 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.eventually.fulfilled;265 281 266 // ...It doesn't break anything;282 // ...It doesn't break anything;267 const collection = await helper.nft.mintCollection(charlie, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});283 const collection = await helper.nft.mintCollection(account, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});268 await expect(helper.signTransaction(charlie, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;284 await expect(helper.signTransaction(account, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;269 });285 });270 });286 });271287272 it('can be reassigned', async () => {288 it('can be reassigned', async () => {273 await usingPlaygrounds(async (helper) => {289 await usingPlaygrounds(async (helper) => {274 const [oldAdmin, newAdmin, collectionOwner] = await helper.arrange.createAccounts([10n, 10n, 10n], alice);290 const [oldAdmin, newAdmin, collectionOwner] = [accounts.pop()!, accounts.pop()!, accounts.pop()!];275 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});291 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});276 292 277 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress(normalizeAccountId(oldAdmin))))).to.be.eventually.fulfilled;293 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress(normalizeAccountId(oldAdmin))))).to.be.eventually.fulfilled;293309294 it('should actually sponsor transactions', async () => {310 it('should actually sponsor transactions', async () => {295 await usingPlaygrounds(async (helper) => {311 await usingPlaygrounds(async (helper) => {296 const [collectionOwner, tokenSender, receiver] = await helper.arrange.createAccounts([10n, 10n, 0n], alice);312 const [collectionOwner, tokenSender, receiver] = [accounts.pop()!, accounts.pop()!, accounts.pop()!];297 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'Name', description: 'Description', tokenPrefix: 'Prefix', limits: {sponsorTransferTimeout: 0}});313 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'Name', description: 'Description', tokenPrefix: 'Prefix', limits: {sponsorTransferTimeout: 0}});298 const token = await collection.mintToken(collectionOwner, {Substrate: tokenSender.address});314 const token = await collection.mintToken(collectionOwner, {Substrate: tokenSender.address});299 await helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId));315 await helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId));303 expect (await token.getOwner()).to.be.deep.equal({Substrate: receiver.address});319 expect (await token.getOwner()).to.be.deep.equal({Substrate: receiver.address});304 const palletBalanceAfter = await helper.balance.getSubstrate(palletAddress);320 const palletBalanceAfter = await helper.balance.getSubstrate(palletAddress);305321306 // senders balance the same322 // senders balance the same, transaction has sponsored307 expect (await helper.balance.getSubstrate(tokenSender.address)).to.be.equal(10n * nominal);323 expect (await helper.balance.getSubstrate(tokenSender.address)).to.be.equal(1000n * nominal);308 expect (palletBalanceBefore > palletBalanceAfter).to.be.true;324 expect (palletBalanceBefore > palletBalanceAfter).to.be.true;309 });325 });310 });326 });311327312 it('can not be set by non admin', async () => {328 it('can not be set by non admin', async () => {313 await usingPlaygrounds(async (helper) => {329 await usingPlaygrounds(async (helper) => {314 const [collectionOwner, nonAdmin] = await helper.arrange.createAccounts([10n, 10n], alice);330 const [collectionOwner, nonAdmin] = [accounts.pop()!, accounts.pop()!];315331316 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});332 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});317 333 322338323 it('should set pallet address as confirmed admin', async () => {339 it('should set pallet address as confirmed admin', async () => {324 await usingPlaygrounds(async (helper) => {340 await usingPlaygrounds(async (helper) => {325 const [collectionOwner, oldSponsor] = await helper.arrange.createAccounts([20n, 20n], alice);341 const [collectionOwner, oldSponsor] = [accounts.pop()!, accounts.pop()!];326 342 327 // Can set sponsoring for collection without sponsor343 // Can set sponsoring for collection without sponsor328 const collectionWithoutSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'No-sponsor', description: 'New Collection', tokenPrefix: 'Promotion'});344 const collectionWithoutSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'No-sponsor', description: 'New Collection', tokenPrefix: 'Promotion'});345361346 it('can be overwritten by collection owner', async () => { 362 it('can be overwritten by collection owner', async () => { 347 await usingPlaygrounds(async (helper) => {363 await usingPlaygrounds(async (helper) => {348 const [collectionOwner, newSponsor] = await helper.arrange.createAccounts([20n, 0n], alice);364 const [collectionOwner, newSponsor] = [accounts.pop()!, accounts.pop()!];349 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});365 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});350 const collectionId = collection.collectionId;366 const collectionId = collection.collectionId;351 367 374 390 375 it('should reject transaction if collection doesn\'t exist', async () => {391 it('should reject transaction if collection doesn\'t exist', async () => {376 await usingPlaygrounds(async (helper) => {392 await usingPlaygrounds(async (helper) => {377 const [collectionOwner] = await helper.arrange.createAccounts([10n], alice);393 const collectionOwner = accounts.pop()!;378 394 379 // collection has never existed395 // collection has never existed380 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(999999999))).to.be.eventually.rejected;396 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(999999999))).to.be.eventually.rejected;390describe('app-promotion stopSponsoringCollection', () => {406describe('app-promotion stopSponsoringCollection', () => {391 it('can not be called by non-admin', async () => { 407 it('can not be called by non-admin', async () => { 392 await usingPlaygrounds(async (helper) => {408 await usingPlaygrounds(async (helper) => {393 const [collectionOwner, nonAdmin] = await helper.arrange.createAccounts([10n, 10n], alice);409 const [collectionOwner, nonAdmin] = [accounts.pop()!, accounts.pop()!];394 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});410 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});395 411 396 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;412 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;402418403 it('should set sponsoring as disabled', async () => {419 it('should set sponsoring as disabled', async () => {404 await usingPlaygrounds(async (helper) => {420 await usingPlaygrounds(async (helper) => {405 const [collectionOwner, recepient] = await helper.arrange.createAccounts([10n, 0n], alice);421 const [collectionOwner, recepient] = [accounts.pop()!, accounts.pop()!];406 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', limits: {sponsorTransferTimeout: 0}});422 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', limits: {sponsorTransferTimeout: 0}});407 const token = await collection.mintToken(collectionOwner, {Substrate: collectionOwner.address});423 const token = await collection.mintToken(collectionOwner, {Substrate: collectionOwner.address});408 424 421437422 it('should not affect collection which is not sponsored by pallete', async () => {438 it('should not affect collection which is not sponsored by pallete', async () => {423 await usingPlaygrounds(async (helper) => {439 await usingPlaygrounds(async (helper) => {424 const [collectionOwner] = await helper.arrange.createAccounts([10n, 10n], alice);440 const collectionOwner = accounts.pop()!;425 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: collectionOwner.address});441 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: collectionOwner.address});426 await collection.confirmSponsorship(collectionOwner);442 await collection.confirmSponsorship(collectionOwner);427 443 433449434 it('should reject transaction if collection does not exist', async () => { 450 it('should reject transaction if collection does not exist', async () => { 435 await usingPlaygrounds(async (helper) => {451 await usingPlaygrounds(async (helper) => {436 const [collectionOwner] = await helper.arrange.createAccounts([10n], alice);452 const collectionOwner = accounts.pop()!;437 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});453 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});438 454 439 await collection.burn(collectionOwner);455 await collection.burn(collectionOwner);515531516 itWeb3('can not be set by non admin', async ({api, web3, privateKeyWrapper}) => {532 itWeb3('can not be set by non admin', async ({api, web3, privateKeyWrapper}) => {517 await usingPlaygrounds(async (helper) => { 533 await usingPlaygrounds(async (helper) => { 518 const [nonAdmin] = await helper.arrange.createAccounts([50n], alice);534 const nonAdmin = accounts.pop()!;519 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();535 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();520 const flipper = await deployFlipper(web3, contractOwner);536 const flipper = await deployFlipper(web3, contractOwner);521 const contractMethods = contractHelpers(web3, contractOwner);537 const contractMethods = contractHelpers(web3, contractOwner);595611596 itWeb3('can not be called by non-admin', async ({api, web3, privateKeyWrapper}) => {612 itWeb3('can not be called by non-admin', async ({api, web3, privateKeyWrapper}) => {597 await usingPlaygrounds(async (helper) => { 613 await usingPlaygrounds(async (helper) => { 598 const [nonAdmin] = await helper.arrange.createAccounts([10n], alice);614 const nonAdmin = accounts.pop()!;599 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();615 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();600 const flipper = await deployFlipper(web3, contractOwner);616 const flipper = await deployFlipper(web3, contractOwner);601617606622607 itWeb3('should not affect a contract which is not sponsored by pallete', async ({api, web3, privateKeyWrapper}) => {623 itWeb3('should not affect a contract which is not sponsored by pallete', async ({api, web3, privateKeyWrapper}) => {608 await usingPlaygrounds(async (helper) => { 624 await usingPlaygrounds(async (helper) => { 609 const [nonAdmin] = await helper.arrange.createAccounts([10n], alice);625 const nonAdmin = accounts.pop()!;610 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();626 const contractOwner = (await createEthAccountWithBalance(api, web3, privateKeyWrapper)).toLowerCase();611 const flipper = await deployFlipper(web3, contractOwner);627 const flipper = await deployFlipper(web3, contractOwner);612 const contractHelper = contractHelpers(web3, contractOwner);628 const contractHelper = contractHelpers(web3, contractOwner);620describe('app-promotion rewards', () => {636describe('app-promotion rewards', () => {621 it('can not be called by non admin', async () => {637 it('can not be called by non admin', async () => {622 await usingPlaygrounds(async (helper) => {638 await usingPlaygrounds(async (helper) => {623 const [nonAdmin] = await helper.arrange.createAccounts([10n], alice);639 const nonAdmin = accounts.pop()!;624 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.promotion.payoutStakers(50))).to.be.rejected;640 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.promotion.payoutStakers(50))).to.be.rejected;625 });641 });626 });642 });627643628 it('should credit 0.05% for staking period', async () => { 644 it('should credit 0.05% for staking period', async () => { 629 // TODO flaky test645 // TODO flaky test630 await usingPlaygrounds(async helper => {646 await usingPlaygrounds(async helper => {631 const [staker] = await helper.arrange.createAccounts([5000n], alice);647 const staker = accounts.pop()!;632 648 633 await helper.staking.stake(staker, 100n * nominal);649 await helper.staking.stake(staker, 100n * nominal);634 await helper.staking.stake(staker, 200n * nominal);650 await helper.staking.stake(staker, 200n * nominal);642658643 it('shoud be paid for more than one period if payments was missed', async () => {659 it('shoud be paid for more than one period if payments was missed', async () => {644 await usingPlaygrounds(async (helper) => {660 await usingPlaygrounds(async (helper) => {645 const [staker] = await helper.arrange.createAccounts([400n], alice);661 const staker = accounts.pop()!;646662647 await helper.staking.stake(staker, 100n * nominal);663 await helper.staking.stake(staker, 100n * nominal);648 await helper.staking.stake(staker, 200n * nominal);664 await helper.staking.stake(staker, 200n * nominal);663 it('should not be credited for unstaked (reserved) balance', async () => {679 it('should not be credited for unstaked (reserved) balance', async () => {664 expect.fail('Test not implemented');680 expect.fail('Test not implemented');665 await usingPlaygrounds(async helper => {681 await usingPlaygrounds(async helper => {666 const staker = await helper.arrange.createAccounts([1000n], alice);682 const staker = accounts.pop()!;667 });683 });668 });684 });669 685 670 it('should bring compound interest', async () => {686 it('should bring compound interest', async () => {671 // TODO flaky test687 // TODO flaky test672 await usingPlaygrounds(async helper => {688 await usingPlaygrounds(async helper => {673 const [staker] = await helper.arrange.createAccounts([800n], alice);689 const staker = accounts.pop()!;674 690 675 await helper.staking.stake(staker, 100n * nominal);691 await helper.staking.stake(staker, 100n * nominal);676 await helper.staking.stake(staker, 200n * nominal);692 await helper.staking.stake(staker, 200n * nominal);