git.delta.rocks / unique-network / refs/commits / 275d4ae154a4

difftreelog

CORE-386 Fix error case

Trubnikov Sergey2022-06-10parent: #40b1404.patch.diff
in: master

3 files changed

modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -105,7 +105,7 @@
 			.confirm_sponsorship(caller.as_sub())
 			.map_err(dispatch_to_evm::<T>)?
 		{
-			return Err("Caller is not set as sponsor".into());
+			return Err("caller is not set as sponsor".into());
 		}
 		save(self)
 	}
@@ -136,7 +136,7 @@
 			}
 			_ => {
 				return Err(Error::Revert(format!(
-					"Unknown integer limit \"{}\"",
+					"unknown integer limit \"{}\"",
 					limit
 				)))
 			}
@@ -163,7 +163,7 @@
 			}
 			_ => {
 				return Err(Error::Revert(format!(
-					"Unknown boolean limit \"{}\"",
+					"unknown boolean limit \"{}\"",
 					limit
 				)))
 			}
@@ -244,11 +244,11 @@
 		collections: Vec<address>,
 	) -> Result<void> {
 		if collections.is_empty() {
-			return Err("No addresses provided".into());
+			return Err("no addresses provided".into());
 		}
 		if collections.len() >= OwnerRestrictedSet::bound() {
 			return Err(Error::Revert(format!(
-				"Out of bound: {} >= {}",
+				"out of bound: {} >= {}",
 				collections.len(),
 				OwnerRestrictedSet::bound()
 			)));
@@ -261,7 +261,7 @@
 					let mut bv = OwnerRestrictedSet::new();
 					for i in collections {
 						bv.try_insert(crate::eth::map_eth_to_id(&i).ok_or_else(|| {
-							Error::Revert("Can't convert address into collection id".into())
+							Error::Revert("can't convert address into collection id".into())
 						})?)
 						.map_err(|e| Error::Revert(format!("{:?}", e)))?;
 					}
@@ -286,7 +286,7 @@
 			access: Some(match mode {
 				0 => AccessMode::Normal,
 				1 => AccessMode::AllowList,
-				_ => return Err("Not supported access mode".into()),
+				_ => return Err("not supported access mode".into()),
 			}),
 			..Default::default()
 		};
modifiedtests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth
before · tests/src/eth/contractSponsoring.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {expect} from 'chai';18import {19  contractHelpers,20  createEthAccountWithBalance,21  transferBalanceToEth,22  deployFlipper,23  itWeb3,24  SponsoringMode,25  createEthAccount,26  collectionIdToAddress,27  GAS_ARGS,28  normalizeEvents,29  subToEth,30  executeEthTxOnSub,31  evmCollectionHelpers,32  getCollectionAddressFromResult,33  evmCollection,34  ethBalanceViaSub,35} from './util/helpers';36import {37  addCollectionAdminExpectSuccess,38  createCollectionExpectSuccess,39  getDetailedCollectionInfo,40  transferBalanceTo,41} from '../util/helpers';42import nonFungibleAbi from './nonFungibleAbi.json';43import getBalance from '../substrate/get-balance';44import {evmToAddress} from '@polkadot/util-crypto';4546describe('Sponsoring EVM contracts', () => {47  itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3, privateKeyWrapper}) => {48    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);49    const flipper = await deployFlipper(web3, owner);50    const helpers = contractHelpers(web3, owner);51    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;52    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});53    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;54  });5556  itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {57    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);58    const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);59    const flipper = await deployFlipper(web3, owner);60    const helpers = contractHelpers(web3, owner);61    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;62    await expect(helpers.methods.setSponsoringMode(notOwner, SponsoringMode.Allowlisted).send({from: notOwner})).to.rejected;63    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;64  });6566  itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => {67    const alice = privateKeyWrapper('//Alice');6869    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);70    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);7172    const flipper = await deployFlipper(web3, owner);7374    const helpers = contractHelpers(web3, owner);7576    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;77    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});78    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});79    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;8081    await transferBalanceToEth(api, alice, flipper.options.address);8283    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);84    expect(originalFlipperBalance).to.be.not.equal('0');8586    await flipper.methods.flip().send({from: caller});87    expect(await flipper.methods.getValue().call()).to.be.true;8889    // Balance should be taken from flipper instead of caller90    const balanceAfter = await web3.eth.getBalance(flipper.options.address);91    expect(+balanceAfter).to.be.lessThan(+originalFlipperBalance);92  });9394  itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should decrease (allowlisted)', async ({api, web3, privateKeyWrapper}) => {95    const alice = privateKeyWrapper('//Alice');9697    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);98    const caller = createEthAccount(web3);99100    const flipper = await deployFlipper(web3, owner);101102    const helpers = contractHelpers(web3, owner);103    await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});104    await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});105106    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;107    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});108    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});109    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;110111    await transferBalanceToEth(api, alice, flipper.options.address);112113    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);114    expect(originalFlipperBalance).to.be.not.equal('0');115116    await flipper.methods.flip().send({from: caller});117    expect(await flipper.methods.getValue().call()).to.be.true;118119    // Balance should be taken from flipper instead of caller120    const balanceAfter = await web3.eth.getBalance(flipper.options.address);121    expect(+balanceAfter).to.be.lessThan(+originalFlipperBalance);122  });123124  itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should not decrease (non-allowlisted)', async ({api, web3, privateKeyWrapper}) => {125    const alice = privateKeyWrapper('//Alice');126127    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);128    const caller = createEthAccount(web3);129130    const flipper = await deployFlipper(web3, owner);131132    const helpers = contractHelpers(web3, owner);133134    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;135    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});136    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});137    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;138139    await transferBalanceToEth(api, alice, flipper.options.address);140141    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);142    expect(originalFlipperBalance).to.be.not.equal('0');143144    await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);145    expect(await flipper.methods.getValue().call()).to.be.false;146147    // Balance should be taken from flipper instead of caller148    const balanceAfter = await web3.eth.getBalance(flipper.options.address);149    expect(+balanceAfter).to.be.equals(+originalFlipperBalance);150  });151152  itWeb3('Sponsoring is set, an address that has UNQ can send a transaction and it works. User balance should not change', async ({api, web3, privateKeyWrapper}) => {153    const alice = privateKeyWrapper('//Alice');154155    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);156    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);157    const originalCallerBalance = await web3.eth.getBalance(caller);158159    const flipper = await deployFlipper(web3, owner);160161    const helpers = contractHelpers(web3, owner);162    await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});163    await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});164165    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;166    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});167    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});168    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;169170    await transferBalanceToEth(api, alice, flipper.options.address);171172    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);173    expect(originalFlipperBalance).to.be.not.equal('0');174175    await flipper.methods.flip().send({from: caller});176    expect(await flipper.methods.getValue().call()).to.be.true;177178    expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);179  });180181  itWeb3('Sponsoring is limited, with setContractRateLimit. The limitation is working if transactions are sent more often, the sender pays the commission.', async ({api, web3, privateKeyWrapper}) => {182    const alice = privateKeyWrapper('//Alice');183184    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);185    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);186    const originalCallerBalance = await web3.eth.getBalance(caller);187188    const flipper = await deployFlipper(web3, owner);189190    const helpers = contractHelpers(web3, owner);191    await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});192    await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});193194    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;195    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});196    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});197    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;198199    await transferBalanceToEth(api, alice, flipper.options.address);200201    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);202    expect(originalFlipperBalance).to.be.not.equal('0');203204    await flipper.methods.flip().send({from: caller});205    expect(await flipper.methods.getValue().call()).to.be.true;206    expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);207208    const newFlipperBalance = await web3.eth.getBalance(flipper.options.address);209    expect(newFlipperBalance).to.be.not.equals(originalFlipperBalance);210211    await flipper.methods.flip().send({from: caller});212    expect(await web3.eth.getBalance(flipper.options.address)).to.be.equal(newFlipperBalance);213    expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);214  });215216  // TODO: Find a way to calculate default rate limit217  itWeb3('Default rate limit equals 7200', async ({api, web3, privateKeyWrapper}) => {218    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);219    const flipper = await deployFlipper(web3, owner);220    const helpers = contractHelpers(web3, owner);221    expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');222  });223224  itWeb3('Sponsoring collection from evm address via access list', async ({api, web3, privateKeyWrapper}) => {225    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);226    const collectionHelpers = evmCollectionHelpers(web3, owner);227    let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send();228    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);229    const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);230    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);231    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});232    let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;233    const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;234    expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;235    expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));236    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');237238    await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});239    collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;240    expect(collectionSub.sponsorship.isConfirmed).to.be.true;241    expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));242243    const user = createEthAccount(web3);244    const nextTokenId = await collectionEvm.methods.nextTokenId().call();245    expect(nextTokenId).to.be.equal('1');246247    const oldPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();248    expect(oldPermissions.mintMode).to.be.false;249    expect(oldPermissions.access).to.be.equal('Normal');250251    await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});252    await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});253    await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});254255    const newPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();256    expect(newPermissions.mintMode).to.be.true;257    expect(newPermissions.access).to.be.equal('AllowList');258259    const ownerBalanceBefore = await ethBalanceViaSub(api, owner);260    const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);261262    {263      const nextTokenId = await collectionEvm.methods.nextTokenId().call();264      expect(nextTokenId).to.be.equal('1');265      const result = await collectionEvm.methods.mintWithTokenURI(266        user,267        nextTokenId,268        'Test URI',269      ).send({from: user});270      const events = normalizeEvents(result.events);271272      expect(events).to.be.deep.equal([273        {274          address: collectionIdAddress,275          event: 'Transfer',276          args: {277            from: '0x0000000000000000000000000000000000000000',278            to: user,279            tokenId: nextTokenId,280          },281        },282      ]);283284      const ownerBalanceAfter = await ethBalanceViaSub(api, owner);285      const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);286287      expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');288      expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);289      expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;290    }291  });292293  itWeb3('Check that transaction via EVM spend money from sponsor address', async ({api, web3, privateKeyWrapper}) => {294    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);295    const collectionHelpers = evmCollectionHelpers(web3, owner);296    let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send();297    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);298    const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);299    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);300    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send();301    let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;302    const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;303    expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;304    expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));305    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');306    const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress);307    await sponsorCollection.methods.confirmCollectionSponsorship().send();308    collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;309    expect(collectionSub.sponsorship.isConfirmed).to.be.true;310    expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));311312    const user = createEthAccount(web3);313    await collectionEvm.methods.addCollectionAdmin(user).send();314    315    const ownerBalanceBefore = await ethBalanceViaSub(api, owner);316    const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);317    318  319    const userCollectionEvm = evmCollection(web3, user, collectionIdAddress);320    const nextTokenId = await userCollectionEvm.methods.nextTokenId().call();321    expect(nextTokenId).to.be.equal('1');322    result = await userCollectionEvm.methods.mintWithTokenURI(323      user,324      nextTokenId,325      'Test URI',326    ).send();327328    const events = normalizeEvents(result.events);329    const address = collectionIdToAddress(collectionId);330331    expect(events).to.be.deep.equal([332      {333        address,334        event: 'Transfer',335        args: {336          from: '0x0000000000000000000000000000000000000000',337          to: user,338          tokenId: nextTokenId,339        },340      },341    ]);342    expect(await userCollectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');343  344    const ownerBalanceAfter = await ethBalanceViaSub(api, owner);345    expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);346    const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);347    expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;348  });349});
after · tests/src/eth/contractSponsoring.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {expect} from 'chai';18import {19  contractHelpers,20  createEthAccountWithBalance,21  transferBalanceToEth,22  deployFlipper,23  itWeb3,24  SponsoringMode,25  createEthAccount,26  collectionIdToAddress,27  GAS_ARGS,28  normalizeEvents,29  subToEth,30  executeEthTxOnSub,31  evmCollectionHelpers,32  getCollectionAddressFromResult,33  evmCollection,34  ethBalanceViaSub,35} from './util/helpers';36import {37  addCollectionAdminExpectSuccess,38  createCollectionExpectSuccess,39  getDetailedCollectionInfo,40  transferBalanceTo,41} from '../util/helpers';42import nonFungibleAbi from './nonFungibleAbi.json';43import getBalance from '../substrate/get-balance';44import {evmToAddress} from '@polkadot/util-crypto';4546describe('Sponsoring EVM contracts', () => {47  itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3, privateKeyWrapper}) => {48    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);49    const flipper = await deployFlipper(web3, owner);50    const helpers = contractHelpers(web3, owner);51    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;52    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});53    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;54  });5556  itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {57    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);58    const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);59    const flipper = await deployFlipper(web3, owner);60    const helpers = contractHelpers(web3, owner);61    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;62    await expect(helpers.methods.setSponsoringMode(notOwner, SponsoringMode.Allowlisted).send({from: notOwner})).to.rejected;63    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;64  });6566  itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => {67    const alice = privateKeyWrapper('//Alice');6869    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);70    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);7172    const flipper = await deployFlipper(web3, owner);7374    const helpers = contractHelpers(web3, owner);7576    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;77    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});78    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});79    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;8081    await transferBalanceToEth(api, alice, flipper.options.address);8283    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);84    expect(originalFlipperBalance).to.be.not.equal('0');8586    await flipper.methods.flip().send({from: caller});87    expect(await flipper.methods.getValue().call()).to.be.true;8889    // Balance should be taken from flipper instead of caller90    const balanceAfter = await web3.eth.getBalance(flipper.options.address);91    expect(+balanceAfter).to.be.lessThan(+originalFlipperBalance);92  });9394  itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should decrease (allowlisted)', async ({api, web3, privateKeyWrapper}) => {95    const alice = privateKeyWrapper('//Alice');9697    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);98    const caller = createEthAccount(web3);99100    const flipper = await deployFlipper(web3, owner);101102    const helpers = contractHelpers(web3, owner);103    await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});104    await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});105106    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;107    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});108    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});109    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;110111    await transferBalanceToEth(api, alice, flipper.options.address);112113    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);114    expect(originalFlipperBalance).to.be.not.equal('0');115116    await flipper.methods.flip().send({from: caller});117    expect(await flipper.methods.getValue().call()).to.be.true;118119    // Balance should be taken from flipper instead of caller120    const balanceAfter = await web3.eth.getBalance(flipper.options.address);121    expect(+balanceAfter).to.be.lessThan(+originalFlipperBalance);122  });123124  itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should not decrease (non-allowlisted)', async ({api, web3, privateKeyWrapper}) => {125    const alice = privateKeyWrapper('//Alice');126127    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);128    const caller = createEthAccount(web3);129130    const flipper = await deployFlipper(web3, owner);131132    const helpers = contractHelpers(web3, owner);133134    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;135    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});136    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});137    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;138139    await transferBalanceToEth(api, alice, flipper.options.address);140141    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);142    expect(originalFlipperBalance).to.be.not.equal('0');143144    await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);145    expect(await flipper.methods.getValue().call()).to.be.false;146147    // Balance should be taken from flipper instead of caller148    const balanceAfter = await web3.eth.getBalance(flipper.options.address);149    expect(+balanceAfter).to.be.equals(+originalFlipperBalance);150  });151152  itWeb3('Sponsoring is set, an address that has UNQ can send a transaction and it works. User balance should not change', async ({api, web3, privateKeyWrapper}) => {153    const alice = privateKeyWrapper('//Alice');154155    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);156    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);157    const originalCallerBalance = await web3.eth.getBalance(caller);158159    const flipper = await deployFlipper(web3, owner);160161    const helpers = contractHelpers(web3, owner);162    await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});163    await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});164165    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;166    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});167    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});168    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;169170    await transferBalanceToEth(api, alice, flipper.options.address);171172    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);173    expect(originalFlipperBalance).to.be.not.equal('0');174175    await flipper.methods.flip().send({from: caller});176    expect(await flipper.methods.getValue().call()).to.be.true;177178    expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);179  });180181  itWeb3('Sponsoring is limited, with setContractRateLimit. The limitation is working if transactions are sent more often, the sender pays the commission.', async ({api, web3, privateKeyWrapper}) => {182    const alice = privateKeyWrapper('//Alice');183184    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);185    const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);186    const originalCallerBalance = await web3.eth.getBalance(caller);187188    const flipper = await deployFlipper(web3, owner);189190    const helpers = contractHelpers(web3, owner);191    await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});192    await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});193194    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;195    await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});196    await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});197    expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;198199    await transferBalanceToEth(api, alice, flipper.options.address);200201    const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);202    expect(originalFlipperBalance).to.be.not.equal('0');203204    await flipper.methods.flip().send({from: caller});205    expect(await flipper.methods.getValue().call()).to.be.true;206    expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);207208    const newFlipperBalance = await web3.eth.getBalance(flipper.options.address);209    expect(newFlipperBalance).to.be.not.equals(originalFlipperBalance);210211    await flipper.methods.flip().send({from: caller});212    expect(await web3.eth.getBalance(flipper.options.address)).to.be.equal(newFlipperBalance);213    expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);214  });215216  // TODO: Find a way to calculate default rate limit217  itWeb3('Default rate limit equals 7200', async ({api, web3, privateKeyWrapper}) => {218    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);219    const flipper = await deployFlipper(web3, owner);220    const helpers = contractHelpers(web3, owner);221    expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');222  });223224  itWeb3('Sponsoring collection from evm address via access list', async ({api, web3, privateKeyWrapper}) => {225    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);226    const collectionHelpers = evmCollectionHelpers(web3, owner);227    let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send();228    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);229    const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);230    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);231    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});232    let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;233    const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;234    expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;235    expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));236    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');237238    await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});239    collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;240    expect(collectionSub.sponsorship.isConfirmed).to.be.true;241    expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));242243    const user = createEthAccount(web3);244    const nextTokenId = await collectionEvm.methods.nextTokenId().call();245    expect(nextTokenId).to.be.equal('1');246247    const oldPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();248    expect(oldPermissions.mintMode).to.be.false;249    expect(oldPermissions.access).to.be.equal('Normal');250251    await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});252    await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner});253    await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});254255    const newPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman();256    expect(newPermissions.mintMode).to.be.true;257    expect(newPermissions.access).to.be.equal('AllowList');258259    const ownerBalanceBefore = await ethBalanceViaSub(api, owner);260    const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);261262    {263      const nextTokenId = await collectionEvm.methods.nextTokenId().call();264      expect(nextTokenId).to.be.equal('1');265      const result = await collectionEvm.methods.mintWithTokenURI(266        user,267        nextTokenId,268        'Test URI',269      ).send({from: user});270      const events = normalizeEvents(result.events);271272      expect(events).to.be.deep.equal([273        {274          address: collectionIdAddress,275          event: 'Transfer',276          args: {277            from: '0x0000000000000000000000000000000000000000',278            to: user,279            tokenId: nextTokenId,280          },281        },282      ]);283284      const ownerBalanceAfter = await ethBalanceViaSub(api, owner);285      const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);286287      expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');288      expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);289      expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;290    }291  });292293  itWeb3('Check that transaction via EVM spend money from sponsor address', async ({api, web3, privateKeyWrapper}) => {294    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);295    const collectionHelpers = evmCollectionHelpers(web3, owner);296    let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send();297    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);298    const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);299    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);300    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send();301    let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;302    const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;303    expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;304    expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));305    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');306    const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress);307    await sponsorCollection.methods.confirmCollectionSponsorship().send();308    collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;309    expect(collectionSub.sponsorship.isConfirmed).to.be.true;310    expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));311312    const user = createEthAccount(web3);313    await collectionEvm.methods.addCollectionAdmin(user).send();314    315    const ownerBalanceBefore = await ethBalanceViaSub(api, owner);316    const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);317    318  319    const userCollectionEvm = evmCollection(web3, user, collectionIdAddress);320    const nextTokenId = await userCollectionEvm.methods.nextTokenId().call();321    expect(nextTokenId).to.be.equal('1');322    result = await userCollectionEvm.methods.mintWithTokenURI(323      user,324      nextTokenId,325      'Test URI',326    ).send();327328    const events = normalizeEvents(result.events);329    const address = collectionIdToAddress(collectionId);330331    expect(events).to.be.deep.equal([332      {333        address,334        event: 'Transfer',335        args: {336          from: '0x0000000000000000000000000000000000000000',337          to: user,338          tokenId: nextTokenId,339        },340      },341    ]);342    expect(await userCollectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');343  344    const ownerBalanceAfter = await ethBalanceViaSub(api, owner);345    expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);346    const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);347    expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;348  });349});
modifiedtests/src/eth/createCollection.test.tsdiffbeforeafterboth
--- a/tests/src/eth/createCollection.test.ts
+++ b/tests/src/eth/createCollection.test.ts
@@ -80,7 +80,7 @@
     expect(collectionSub.sponsorship.isUnconfirmed).to.be.true;
     const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format;
     expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format)));
-    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('Caller is not set as sponsor');
+    await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');
     const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress);
     await sponsorCollection.methods.confirmCollectionSponsorship().send();
     collectionSub = (await getDetailedCollectionInfo(api, collectionId))!;
@@ -208,7 +208,7 @@
       const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress);
       await expect(sponsorCollection.methods
         .confirmCollectionSponsorship()
-        .call()).to.be.rejectedWith('Caller is not set as sponsor');
+        .call()).to.be.rejectedWith('caller is not set as sponsor');
     }
     {
       await expect(contractEvmFromNotOwner.methods
@@ -225,6 +225,6 @@
     const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
     await expect(collectionEvm.methods
       .setCollectionLimit('badLimit', 'true')
-      .call()).to.be.rejectedWith('Unknown boolean limit "badLimit"');
+      .call()).to.be.rejectedWith('unknown boolean limit "badLimit"');
   });
 });
\ No newline at end of file