difftreelog
Move old tests to playgrounds-helpers
in: master
1 file changed
tests/src/app-promotion.test.tsdiffbeforeafterboth36let palletAdmin: IKeyringPair;36let palletAdmin: IKeyringPair;37let nominal: bigint;37let nominal: bigint;38let promotionStartBlock: number | null = null;38let promotionStartBlock: number | null = null;39const palletAddress = calculatePalleteAddress('appstake');394040before(async function () {41before(async function () {41 await usingPlaygrounds(async (helper, privateKeyWrapper) => {42 await usingPlaygrounds(async (helper, privateKeyWrapper) => {42 if (!getModuleNames(helper.api!).includes(Pallets.AppPromotion)) this.skip();43 if (!getModuleNames(helper.api!).includes(Pallets.AppPromotion)) this.skip();43 alice = privateKeyWrapper('//Alice');44 alice = privateKeyWrapper('//Alice');44 bob = privateKeyWrapper('//Bob');45 bob = privateKeyWrapper('//Bob');45 palletAdmin = privateKeyWrapper('//palletAdmin');46 palletAdmin = privateKeyWrapper('//palletAdmin');46 await helper.balance.transferToSubstrate(alice, palletAdmin.address, 10n * helper.balance.getOneTokenNominal());47 nominal = helper.balance.getOneTokenNominal();47 nominal = helper.balance.getOneTokenNominal();48 await helper.balance.transferToSubstrate(alice, palletAdmin.address, 100n * nominal);49 await helper.balance.transferToSubstrate(alice, palletAddress, 100n * nominal);50 if (!promotionStartBlock) {51 promotionStartBlock = (await helper.api!.query.parachainSystem.lastRelayChainBlockNumber()).toNumber();52 }53 await helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.startAppPromotion(promotionStartBlock!)));48 });54 });49});55});505657after(async function () {58 await usingPlaygrounds(async (helper) => {59 await helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.stopAppPromotion()));60 });61});6251describe('app-promotions.stake extrinsic', () => {63describe('app-promotions.stake extrinsic', () => {52 it('will change balance state to "locked", add it to "staked" map, and increase "totalStaked" amount', async () => {64 it('should change balance state to "locked", add it to "staked" map, and increase "totalStaked" amount', async () => {53 await usingPlaygrounds(async (helper) => {65 await usingPlaygrounds(async (helper) => {54 const totalStakedBefore = await helper.staking.getTotalStaked();66 const totalStakedBefore = await helper.staking.getTotalStaked();55 const [staker] = await helper.arrange.creteAccounts([10n], alice);67 const [staker] = await helper.arrange.creteAccounts([10n], alice);73 });85 });74 });86 });75 87 76 it('will throws if stake amount is more than total free balance', async () => {88 it('should reject transaction if stake amount is more than total free balance', async () => {77 await usingPlaygrounds(async helper => { 89 await usingPlaygrounds(async helper => { 78 const [staker] = await helper.arrange.creteAccounts([10n], alice);90 const [staker] = await helper.arrange.creteAccounts([10n], alice);7991101 // TODO it('Staker stakes 5 times in one block with nonce');113 // TODO it('Staker stakes 5 times in one block with nonce');102 // TODO it('Staked balance appears as locked in the balance pallet');114 // TODO it('Staked balance appears as locked in the balance pallet');103 // TODO it('Alice stakes huge amount of tokens');115 // TODO it('Alice stakes huge amount of tokens');104 // TODO it('Can stake from ethereum account')105});116});106117107describe('unstake balance extrinsic', () => { 118describe('unstake balance extrinsic', () => { 108 it('will change balance state to "reserved", add it to "pendingUnstake" map, and subtract it from totalStaked', async () => {119 it('should change balance state to "reserved", add it to "pendingUnstake" map, and subtract it from totalStaked', async () => {109 await usingPlaygrounds(async helper => {120 await usingPlaygrounds(async helper => {110 const totalStakedBefore = await helper.staking.getTotalStaked();121 const totalStakedBefore = await helper.staking.getTotalStaked();111 const [staker] = await helper.arrange.creteAccounts([10n], alice);122 const [staker] = await helper.arrange.creteAccounts([10n], alice);118 });129 });119 });130 });120131121 it('will remove from the "staked" map starting from the oldest entry', async () => {132 it('should remove from the "staked" map starting from the oldest entry', async () => {122 await usingPlaygrounds(async helper => {133 await usingPlaygrounds(async helper => {123 const [staker] = await helper.arrange.creteAccounts([100n], alice);134 const [staker] = await helper.arrange.creteAccounts([100n], alice);124 await helper.staking.stake(staker, 10n * nominal);135 await helper.staking.stake(staker, 10n * nominal);239 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.eventually.fulfilled;250 await expect(helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address})))).to.be.eventually.fulfilled;240 251 241 // ...It doesn't break anything;252 // ...It doesn't break anything;242 console.log(await helper.balance.getSubstrate(charlie.address));243 console.log(await helper.balance.getSubstrate(palletAdmin.address));244 const collection = await helper.nft.mintCollection(charlie, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});253 const collection = await helper.nft.mintCollection(charlie, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});245 await expect(helper.signTransaction(charlie, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;254 await expect(helper.signTransaction(charlie, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;246 });255 });262271263describe('App-promotion collection sponsoring', () => {272describe('App-promotion collection sponsoring', () => {264 before(async function () {273 before(async function () {265 await usingPlaygrounds(async (helper, privateKeyWrapper) => {274 await usingPlaygrounds(async (helper) => {266 if (!getModuleNames(helper.api!).includes(Pallets.AppPromotion)) this.skip();275 const tx = helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress({Substrate: palletAdmin.address}));267 alice = privateKeyWrapper('//Alice');268 bob = privateKeyWrapper('//Bob');269 palletAdmin = privateKeyWrapper('//palletAdmin');270 await helper.balance.transferToSubstrate(alice, palletAdmin.address, 10n * helper.balance.getOneTokenNominal());271 await helper.balance.transferToSubstrate(alice, calculatePalleteAddress('appstake'), 10n * helper.balance.getOneTokenNominal());272 273 274 const tx = helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress(normalizeAccountId(palletAdmin)));275 await helper.signTransaction(alice, tx);276 await helper.signTransaction(alice, tx);276 277 // const txStart = helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.startAppPromotion(promotionStartBlock));278 // await helper.signTransaction(alice, txStart);279 280 nominal = helper.balance.getOneTokenNominal();281 });277 });282 });278 });283 279 284 it('can not be set by non admin', async () => {280 it('can not be set by non admin', async () => {285 286 287 // arrange: Charlie creates Punks288 // arrange: Sudo calls appPromotion.setAdminAddress(Alice)289290 // assert: Random calls appPromotion.sponsorCollection(Punks.id) throws /// Random account can not set sponsoring291 // assert: Alice calls appPromotion.sponsorCollection(Punks.id) success /// Admin account can set sponsoring292 293 await usingPlaygrounds(async (helper) => {281 await usingPlaygrounds(async (helper) => {294 const colletcion = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});282 const [collectionOwner, nonAdmin] = await helper.arrange.creteAccounts([10n, 10n], alice);283284 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});295 285 296 const collectionId = colletcion.collectionId;286 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;297 298 await expect(helper.signTransaction(bob, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.rejected;299 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;287 expect((await collection.getData())?.raw.sponsorship).to.equal('Disabled');300 });288 });301 302 });289 });303290304 it('will set pallet address as confirmed admin for collection without sponsor', async () => {291 it('should set pallet address as confirmed admin', async () => {305 // arrange: Charlie creates Punks306307 // act: Admin calls appPromotion.sponsorCollection(Punks.id)308309 // assert: query collectionById: Punks sponsoring is confirmed by PalleteAddress310 311 await usingPlaygrounds(async (helper) => {292 await usingPlaygrounds(async (helper) => {312 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});293 const [collectionOwner, oldSponsor] = await helper.arrange.creteAccounts([20n, 20n], alice);313 const collectionId = collection.collectionId;314315 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;316 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: calculatePalleteAddress('appstake')});317 });318 319 });320321 it('will set pallet address as confirmed admin for collection with unconfirmed sponsor', async () => {322 // arrange: Charlie creates Punks323 // arrange: Charlie calls setCollectionSponsor(Punks.Id, Dave) /// Dave is unconfirmed sponsor324325 // act: Admin calls appPromotion.sponsorCollection(Punks.id)326327 // assert: query collectionById: Punks sponsoring is confirmed by PalleteAddress328 329 await usingPlaygrounds(async (helper) => {330 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});331 await collection.setSponsor(alice, bob.address);332 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Unconfirmed: bob.address});333 294 334 const collectionId = collection.collectionId;295 // Can set sponsoring for collection without sponsor335 296 const collectionWithoutSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'No-sponsor', description: 'New Collection', tokenPrefix: 'Promotion'});336 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;297 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionWithoutSponsor.collectionId))).to.be.eventually.fulfilled;337 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: calculatePalleteAddress('appstake')});298 expect((await collectionWithoutSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});338 });339 340 });341299342 it('will set pallet address as confirmed admin for collection with confirmed sponsor', async () => {300 // Can set sponsoring for collection with unconfirmed sponsor343 // arrange: Charlie creates Punks301 const collectionWithUnconfirmedSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'Unconfirmed', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: oldSponsor.address});344 // arrange: setCollectionSponsor(Punks.Id, Dave)302 expect((await collectionWithUnconfirmedSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Unconfirmed: oldSponsor.address});345 // arrange: confirmSponsorship(Punks.Id, Dave) /// Dave is confirmed sponsor303 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionWithUnconfirmedSponsor.collectionId))).to.be.eventually.fulfilled;304 expect((await collectionWithUnconfirmedSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});346305347 // act: Admin calls appPromotion.sponsorCollection(Punks.id)306 // Can set sponsoring for collection with confirmed sponsor348349 // assert: query collectionById: Punks sponsoring is confirmed by PalleteAddress350 307 const collectionWithConfirmedSponsor = await helper.nft.mintCollection(collectionOwner, {name: 'Confirmed', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: oldSponsor.address});351 await usingPlaygrounds(async (helper) => {352 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});353 await collection.setSponsor(alice, bob.address);354 355 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Unconfirmed: bob.address});356 expect(await collection.confirmSponsorship(bob)).to.be.true;308 await collectionWithConfirmedSponsor.confirmSponsorship(oldSponsor);357 309 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionWithConfirmedSponsor.collectionId))).to.be.eventually.fulfilled;358 const collectionId = collection.collectionId;359 360 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;361 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: calculatePalleteAddress('appstake')});310 expect((await collectionWithConfirmedSponsor.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});362 });311 });363 });312 });364313365 it('can be overwritten by collection owner', async () => {314 it('can be overwritten by collection owner', async () => { 366 // arrange: Charlie creates Punks367 // arrange: appPromotion.sponsorCollection(Punks.Id) /// Sponsor of Punks is pallete368369 // act: Charlie calls unique.setCollectionLimits(limits) /// Charlie as owner can successfully change limits370 // assert: query collectionById(Punks.id) 1. sponsored by pallete, 2. limits has been changed371372 // act: Charlie calls setCollectionSponsor(Dave) /// Collection owner reasignes sponsoring373 // assert: query collectionById: Punks sponsoring is unconfirmed by Dave374 375 await usingPlaygrounds(async (helper) => {315 await usingPlaygrounds(async (helper) => {376 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});316 const [collectionOwner, newSponsor] = await helper.arrange.creteAccounts([20n, 0n], alice);317 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});377 const collectionId = collection.collectionId;318 const collectionId = collection.collectionId;378 319 379 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;320 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;380 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: calculatePalleteAddress('appstake')});381 321 382 expect(await collection.setLimits(alice, {sponsorTransferTimeout: 0})).to.be.true;322 // Collection limits still can be changed by the owner323 expect(await collection.setLimits(collectionOwner, {sponsorTransferTimeout: 0})).to.be.true;383 expect((await collection.getData())?.raw.limits.sponsorTransferTimeout).to.be.equal(0);324 expect((await collection.getData())?.raw.limits.sponsorTransferTimeout).to.be.equal(0);384 325 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});326327 // Collection sponsor can be changed too385 expect((await collection.setSponsor(alice, bob.address))).to.be.true;328 expect((await collection.setSponsor(collectionOwner, newSponsor.address))).to.be.true;386 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Unconfirmed: bob.address});329 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Unconfirmed: newSponsor.address});387 });330 });388 389 });331 });390 332 391 it('will keep collection limits set by the owner earlier', async () => {333 it('should not overwrite collection limits set by the owner earlier', async () => {392 // arrange: const limits = {...all possible collection limits}393 // arrange: Charlie creates Punks394 // arrange: Charlie calls unique.setCollectionLimits(limits) /// Owner sets all possible limits395396 // act: Admin calls appPromotion.sponsorCollection(Punks.id)397 // assert: query collectionById(Punks.id) returns limits398 399 await usingPlaygrounds(async (helper) => {334 await usingPlaygrounds(async (helper) => {400 335 const limits = {ownerCanDestroy: true, ownerCanTransfer: true, sponsorTransferTimeout: 0};401 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});336 const collectionWithLimits = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', limits});402 expect(await collection.setLimits(alice, {sponsorTransferTimeout: 0})).to.be.true;337403 const limits = (await collection.getData())?.raw.limits;404 338 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionWithLimits.collectionId))).to.be.eventually.fulfilled;405 const collectionId = collection.collectionId;406 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;407 expect((await collection.getData())?.raw.limits).to.be.deep.equal(limits);339 expect((await collectionWithLimits.getData())?.raw.limits).to.be.deep.contain(limits);408 });340 });409 410 });341 });411 342 412 it('will throw if collection doesn\'t exist', async () => {343 it('should reject transaction if collection doesn\'t exist', async () => {413 // assert: Admin calls appPromotion.sponsorCollection(999999999999999) throw 414 await usingPlaygrounds(async (helper) => {344 await usingPlaygrounds(async (helper) => {415 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(999999999))).to.be.eventually.rejected;345 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(999999999))).to.be.eventually.rejected;416 });346 });417 });347 });418348419 it('will throw if collection was burnt', async () => {349 it('should reject transaction if collection was burnt', async () => {420 // arrange: Charlie creates Punks421 // arrange: Charlie burns Punks422423 // assert: Admin calls appPromotion.sponsorCollection(Punks.id) throw424 425 await usingPlaygrounds(async (helper) => {350 await usingPlaygrounds(async (helper) => {426 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});351 const [collectionOwner] = await helper.arrange.creteAccounts([10n], alice);352 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});427 const collectionId = collection.collectionId;353 await collection.burn(collectionOwner);428 354429 expect((await collection.burn(alice))).to.be.true;430 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.rejected;355 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.rejected;431 });356 });432 433 });357 });434});358});435359436437describe('app-promotion stopSponsoringCollection', () => {360describe('app-promotion stopSponsoringCollection', () => {438 before(async function () {361 it('can not be called by non-admin', async () => { 439 await usingPlaygrounds(async (helper, privateKeyWrapper) => {440 if (!getModuleNames(helper.api!).includes(Pallets.AppPromotion)) this.skip();441 alice = privateKeyWrapper('//Alice');442 bob = privateKeyWrapper('//Bob');443 palletAdmin = privateKeyWrapper('//palletAdmin');444 await helper.balance.transferToSubstrate(alice, palletAdmin.address, 10n * helper.balance.getOneTokenNominal());445 await helper.balance.transferToSubstrate(alice, calculatePalleteAddress('appstake'), 10n * helper.balance.getOneTokenNominal());446 447 const tx = helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress(normalizeAccountId(palletAdmin)));448 await helper.signTransaction(alice, tx);449450 nominal = helper.balance.getOneTokenNominal();451 });452 });453 454 it('can not be called by non-admin', async () => {455 // arrange: Alice creates Punks456 // arrange: appPromotion.sponsorCollection(Punks.Id)457458 // assert: Random calls appPromotion.stopSponsoringCollection(Punks) throws459 // assert: query collectionById(Punks.id): sponsoring confirmed by PalleteAddress460 461 await usingPlaygrounds(async (helper) => {362 await usingPlaygrounds(async (helper) => {462 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});363 const [collectionOwner, nonAdmin] = await helper.arrange.creteAccounts([10n, 10n], alice);463 const collectionId = collection.collectionId;364 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});464 365 465 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;366 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;466 367 467 await expect(helper.signTransaction(bob, helper.api!.tx.promotion.stopSponsorignCollection(collectionId))).to.be.eventually.rejected;368 await expect(helper.signTransaction(nonAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collection.collectionId))).to.be.eventually.rejected;468 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: calculatePalleteAddress('appstake')});369 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: palletAddress});469 });370 });470 });371 });471372472 it('will set sponsoring as disabled', async () => {373 it('should set sponsoring as disabled', async () => {473 // arrange: Alice creates Punks474 // arrange: appPromotion.sponsorCollection(Punks.Id)475476 // act: Admin calls appPromotion.stopSponsoringCollection(Punks)477478 // assert: query collectionById(Punks.id): sponsoring unconfirmed479 480 await usingPlaygrounds(async (helper) => {374 await usingPlaygrounds(async (helper) => {481 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});375 const [collectionOwner] = await helper.arrange.creteAccounts([10n, 10n], alice);482 const collectionId = collection.collectionId;376 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});483 377 484 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collectionId))).to.be.eventually.fulfilled;378 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.sponsorCollection(collection.collectionId))).to.be.eventually.fulfilled;485 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collectionId))).to.be.eventually.fulfilled;379 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collection.collectionId))).to.be.eventually.fulfilled;486 380 487 expect((await collection.getData())?.raw.sponsorship).to.be.equal('Disabled');381 expect((await collection.getData())?.raw.sponsorship).to.be.equal('Disabled');488 });382 });489 });383 });490384491 it('will not affect collection which is not sponsored by pallete', async () => {385 it('should not affect collection which is not sponsored by pallete', async () => {492 // arrange: Alice creates Punks493 // arrange: Alice calls setCollectionSponsoring(Punks)494 // arrange: Alice calls confirmSponsorship(Punks)495496 // act: Admin calls appPromotion.stopSponsoringCollection(A)497 // assert: query collectionById(Punks): Sponsoring: {Confirmed: Alice} /// Alice still collection owner498 499 await usingPlaygrounds(async (helper) => {386 await usingPlaygrounds(async (helper) => {500 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});387 const [collectionOwner] = await helper.arrange.creteAccounts([10n, 10n], alice);501 const collectionId = collection.collectionId;388 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion', pendingSponsor: collectionOwner.address});502 expect(await collection.setSponsor(alice, alice.address)).to.be.true;503 expect(await collection.confirmSponsorship(alice)).to.be.true;389 await collection.confirmSponsorship(collectionOwner);504 390 505 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collectionId))).to.be.eventually.rejected;391 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collection.collectionId))).to.be.eventually.rejected;506 392 507 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: alice.address});393 expect((await collection.getData())?.raw.sponsorship).to.be.deep.equal({Confirmed: collectionOwner.address});508 });394 });509 510 });395 });511396512 it('will throw if collection does not exist', async () => {397 it('should reject transaction if collection does not exist', async () => { 513 // arrange: Alice creates Punks514 // arrange: Alice burns Punks515516 // assert: Admin calls appPromotion.stopSponsoringCollection(Punks.id) throws517 // assert: Admin calls appPromotion.stopSponsoringCollection(999999999999999) throw518 519 await usingPlaygrounds(async (helper) => {398 await usingPlaygrounds(async (helper) => {520 const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});399 const [collectionOwner] = await helper.arrange.creteAccounts([10n], alice);521 const collectionId = collection.collectionId;400 const collection = await helper.nft.mintCollection(collectionOwner, {name: 'New', description: 'New Collection', tokenPrefix: 'Promotion'});522 401 523 expect((await collection.burn(alice))).to.be.true;402 await collection.burn(collectionOwner);403 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collection.collectionId))).to.be.eventually.rejected;524 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(collectionId))).to.be.eventually.rejected;404 await expect(helper.signTransaction(palletAdmin, helper.api!.tx.promotion.stopSponsorignCollection(999999999))).to.be.eventually.rejected;525 });405 });526 });406 });527});407});593 bob = privateKeyWrapper('//Bob');473 bob = privateKeyWrapper('//Bob');594 palletAdmin = privateKeyWrapper('//palletAdmin');474 palletAdmin = privateKeyWrapper('//palletAdmin');595 await helper.balance.transferToSubstrate(alice, palletAdmin.address, 10n * helper.balance.getOneTokenNominal());475 await helper.balance.transferToSubstrate(alice, palletAdmin.address, 10n * helper.balance.getOneTokenNominal());596 await helper.balance.transferToSubstrate(alice, calculatePalleteAddress('appstake'), 10n * helper.balance.getOneTokenNominal());476 await helper.balance.transferToSubstrate(alice, palletAddress, 10n * helper.balance.getOneTokenNominal());597 477 598 const tx = helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress(normalizeAccountId(palletAdmin)));478 const tx = helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress(normalizeAccountId(palletAdmin)));599 await helper.signTransaction(alice, tx);479 await helper.signTransaction(alice, tx);641});521});642522643describe('app-promotion rewards', () => {523describe('app-promotion rewards', () => {644 const DAY = 7200n;524 it('should credit 0.05% for staking period', async () => { 645646 // TODO (load test. Can pay reward for 10000 addresses)647 648 649 before(async function () {650 await usingPlaygrounds(async (helper, privateKeyWrapper) => {651 if (!getModuleNames(helper.api!).includes(Pallets.AppPromotion)) this.skip();652 alice = privateKeyWrapper('//Alice');653 bob = privateKeyWrapper('//Bob');654 palletAdmin = privateKeyWrapper('//palletAdmin');655 if (promotionStartBlock == null) {656 promotionStartBlock = (await helper.api!.query.parachainSystem.lastRelayChainBlockNumber()).toNumber();657 }658 const tx = helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.setAdminAddress(normalizeAccountId(palletAdmin)));659 await helper.signTransaction(alice, tx);660 661 const txStart = helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.startAppPromotion(promotionStartBlock!));662 await helper.signTransaction(alice, txStart);663664 nominal = helper.balance.getOneTokenNominal();665 });666 });667668 after(async function () {669 await usingPlaygrounds(async (helper) => {670 await helper.signTransaction(alice, helper.api!.tx.sudo.sudo(helper.api!.tx.promotion.stopAppPromotion()));671 });672 });673 674 it('will credit 0.05% for staking period', async () => {675 // arrange: bob.stake(10000);676 // arrange: bob.stake(20000);677 // arrange: waitForRewards();678679 // assert: bob.staked to equal [10005, 20010]680 681 await usingPlaygrounds(async helper => {525 await usingPlaygrounds(async helper => {682 const staker = await createUser(50n * nominal);526 const [staker] = await helper.arrange.creteAccounts([50n], alice);683 await waitForRecalculationBlock(helper.api!);527 await waitForRecalculationBlock(helper.api!);684 528 685 await expect(helper.signTransaction(staker, helper.api!.tx.promotion.stake(1n * nominal))).to.be.eventually.fulfilled;529 await helper.staking.stake(staker, 1n * nominal);686 await expect(helper.signTransaction(staker, helper.api!.tx.promotion.stake(2n * nominal))).to.be.eventually.fulfilled;530 await helper.staking.stake(staker, 2n * nominal);687 await waitForRelayBlock(helper.api!, 36);531 await waitForRelayBlock(helper.api!, 36);688 532 689 533 const totalStakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(s => s[1]);690 expect((await helper.api!.rpc.unique.totalStakedPerBlock(normalizeAccountId(staker)))691 .map(([_, amount]) => amount.toBigInt()))692 .to.be.deep.equal([calculateIncome(nominal, 10n), calculateIncome(2n * nominal, 10n)]);534 expect(totalStakedPerBlock).to.be.deep.equal([calculateIncome(nominal, 10n), calculateIncome(2n * nominal, 10n)]);693 });535 });694 695 });536 });696 537 697 it('will not be credited for unstaked (reserved) balance', async () => {538 it('should not be credited for unstaked (reserved) balance', async () => {698 // arrange: bob.stake(10000);699 // arrange: bob.unstake(5000);700 // arrange: waitForRewards();701702 // assert: bob.staked to equal [5002.5]703 await usingPlaygrounds(async helper => {539 await usingPlaygrounds(async helper => {704 const staker = await createUser(20n * nominal);540 expect.fail('Implement me after unstake method will be fixed');705 await waitForRecalculationBlock(helper.api!);706 await expect(helper.signTransaction(staker, helper.api!.tx.promotion.stake(10n * nominal))).to.be.eventually.fulfilled;707 await expect(helper.signTransaction(staker, helper.api!.tx.promotion.unstake(5n * nominal))).to.be.eventually.fulfilled;708 await waitForRelayBlock(helper.api!, 38);709710 expect((await helper.api!.rpc.unique.totalStakedPerBlock(normalizeAccountId(staker)))711 .map(([_, amount]) => amount.toBigInt()))712 .to.be.deep.equal([calculateIncome(5n * nominal, 10n)]);713 714 });541 });715 716 });542 });717 543 718 it('will bring compound interest', async () => {544 it('should bring compound interest', async () => {719 // arrange: bob balance = 30000720 // arrange: bob.stake(10000);721 // arrange: bob.stake(10000);722 // arrange: waitForRewards();723724 // assert: bob.staked() equal [10005, 10005, 10005] /// 10_000 * 1.0005725 // act: waitForRewards();726727 // assert: bob.staked() equal [10010.0025, 10010.0025, 10010.0025] /// 10_005 * 1.0005728 // act: bob.unstake(10.0025)729 // assert: bob.staked() equal [10000, 10010.0025, 10010.0025] /// 10_005 * 1.0005730731 // act: waitForRewards();732 // assert: bob.staked() equal [10005, 10015,00750125, 10015,00750125] ///733 await usingPlaygrounds(async helper => {545 await usingPlaygrounds(async helper => {734 const staker = await createUser(40n * nominal);546 const [staker] = await helper.arrange.creteAccounts([80n], alice);735 547 736 await waitForRecalculationBlock(helper.api!);548 await waitForRecalculationBlock(helper.api!);737 549 738739 await expect(helper.signTransaction(staker, helper.api!.tx.promotion.stake(10n * nominal))).to.be.eventually.fulfilled;550 await helper.staking.stake(staker, 10n * nominal);551 await helper.staking.stake(staker, 20n * nominal);552 await helper.staking.stake(staker, 30n * nominal);740 553 741 await expect(helper.signTransaction(staker, helper.api!.tx.promotion.stake(10n * nominal))).to.be.eventually.fulfilled;742 743 await expect(helper.signTransaction(staker, helper.api!.tx.promotion.stake(10n * nominal))).to.be.eventually.fulfilled;744 745 await waitForRelayBlock(helper.api!, 34);554 await waitForRelayBlock(helper.api!, 34);746 expect((await helper.api!.rpc.unique.totalStakedPerBlock(normalizeAccountId(staker)))555 let totalStakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(s => s[1]);747 .map(([_, amount]) => amount.toBigInt()))748 .to.be.deep.equal([calculateIncome(10n * nominal, 10n), calculateIncome(10n * nominal, 10n), calculateIncome(10n * nominal, 10n)]);556 expect(totalStakedPerBlock).to.deep.equal([calculateIncome(10n * nominal, 10n), calculateIncome(20n * nominal, 10n), calculateIncome(30n * nominal, 10n)]);749 557 750 await waitForRelayBlock(helper.api!, 20);558 await waitForRelayBlock(helper.api!, 20);751 await expect(helper.signTransaction(staker, helper.api!.tx.promotion.unstake(calculateIncome(10n * nominal, 10n, 2) - 10n * nominal))).to.be.eventually.fulfilled;559 totalStakedPerBlock = (await helper.staking.getTotalStakedPerBlock({Substrate: staker.address})).map(s => s[1]);752 expect((await helper.api!.rpc.unique.totalStakedPerBlock(normalizeAccountId(staker)))753 .map(([_, amount]) => amount.toBigInt()))754 .to.be.deep.equal([10n * nominal, calculateIncome(10n * nominal, 10n, 2), calculateIncome(10n * nominal, 10n, 2)]);560 expect(totalStakedPerBlock).to.deep.equal([calculateIncome(10n * nominal, 10n, 2), calculateIncome(20n * nominal, 10n, 2), calculateIncome(30n * nominal, 10n, 2)]); 755 });561 });756 757 });562 });563564 // TODO (load test. Can pay reward for 10000 addresses)758});565});759566760567789 });596 });790}597}791598792793function calculatePalleteAddress(palletId: any) {599function calculatePalleteAddress(palletId: any) {794 const address = stringToU8a(('modl' + palletId).padEnd(32, '\0'));600 const address = stringToU8a(('modl' + palletId).padEnd(32, '\0'));795 return encodeAddress(address);601 return encodeAddress(address);796}602}603797function calculateIncome(base: bigint, calcPeriod: bigint, iter = 0): bigint {604function calculateIncome(base: bigint, calcPeriod: bigint, iter = 0): bigint {798 const DAY = 7200n;605 const DAY = 7200n;799 const ACCURACY = 1_000_000_000n;606 const ACCURACY = 1_000_000_000n;802 if (iter > 1) {609 if (iter > 1) {803 return calculateIncome(income, calcPeriod, iter - 1);610 return calculateIncome(income, calcPeriod, iter - 1);804 } else return income;611 } else return income;805}806807async function createUser(amount?: bigint) {808 return await usingPlaygrounds(async helper => {809 const user: IKeyringPair = helper.util.fromSeed(mnemonicGenerate());810 await helper.balance.transferToSubstrate(alice, user.address, amount ? amount : 10n * helper.balance.getOneTokenNominal());811 return user;812 });813}612}814613