git.delta.rocks / unique-network / refs/commits / 71f76028ba5c

difftreelog

source

tests/src/benchmarks/mintFee/benchmark.ts24.9 KiBsourcehistory
1import {EthUniqueHelper, SponsoringMode, usingEthPlaygrounds} from '../../eth/util';2import {readFile} from 'fs/promises';3import {CollectionLimitField, ContractImports, TokenPermissionField} from '../../eth/util/playgrounds/types';4import {5  ICrossAccountId,6  ITokenPropertyPermission,7} from '../../util/playgrounds/types';8import {IKeyringPair} from '@polkadot/types/types';9import {UniqueNFTCollection} from '../../util/playgrounds/unique';10import {Contract} from 'web3-eth-contract';11import {createObjectCsvWriter} from 'csv-writer';1213const CONTRACT_IMPORT: ContractImports[] = [14  {15    fsPath: `${__dirname}/../../eth/api/CollectionHelpers.sol`,16    solPath: 'eth/api/CollectionHelpers.sol',17  },18  {19    fsPath: `${__dirname}/../../eth/api/ContractHelpers.sol`,20    solPath: 'eth/api/ContractHelpers.sol',21  },22  {23    fsPath: `${__dirname}/../../eth/api/UniqueRefungibleToken.sol`,24    solPath: 'eth/api/UniqueRefungibleToken.sol',25  },26  {27    fsPath: `${__dirname}/../../eth/api/UniqueRefungible.sol`,28    solPath: 'eth/api/UniqueRefungible.sol',29  },30  {31    fsPath: `${__dirname}/../../eth/api/UniqueNFT.sol`,32    solPath: 'eth/api/UniqueNFT.sol',33  },34];3536const PROPERTIES = Array(40)37  .fill(0)38  .map((_, i) => {39    return {40      key: `key_${i}`,41      value: Uint8Array.from(Buffer.from(`value_${i}`)),42    };43  });4445const PERMISSIONS: ITokenPropertyPermission[] = PROPERTIES.map((p) => {46  return {47    key: p.key,48    permission: {49      tokenOwner: true,50      collectionAdmin: true,51      mutable: true,52    },53  };54});5556interface IBenchmarkResultForProp {57	propertiesNumber: number;58	substrateFee: number;59	ethFee: number;60	ethBulkFee: number;61  ethMintCrossFee: number;62	evmProxyContractFee: number;63	evmProxyContractBulkFee: number;64}65interface IBenchmarkCollection {66  createFee: number,67  mintFee: number,68  transferFee: number,69}70const main = async () => {71  const benchmarks = [72    'substrateFee',73    'ethFee',74    'ethBulkFee',75    'ethMintCrossFee',76    'evmProxyContractFee',77    'evmProxyContractBulkFee',78  ];79  const headers = [80    'propertiesNumber',81    ...benchmarks,82  ];838485  const csvWriter = createObjectCsvWriter({86    path: 'properties.csv',87    header: headers,88  });8990  await usingEthPlaygrounds(async (helper, privateKey) => {91    const NOMINAL = helper.balance.getOneTokenNominal();92    const CONTRACT_SOURCE = (93      await readFile(`${__dirname}/proxyContract.sol`)94    ).toString();95    const ZEPPELIN_OBJECT = '0x' + (await readFile(`${__dirname}/openZeppelin/bin/ZeppelinContract.bin`)).toString();96    const ZEPPELIN_ABI = JSON.parse((await readFile(`${__dirname}/openZeppelin/bin/ZeppelinContract.abi`)).toString());9798    console.log('\n ERC721 ops fees');99    console.table(await ERC721CalculateFeeGas(helper, privateKey), ['fee', 'gas', 'substrate']);100101    const donor = await privateKey('//Alice'); // Seed from account with balance on this network102    const [substrateReceiver] = await helper.arrange.createAccounts([10n], donor);103104    const ethSigner = await helper.eth.createAccountWithBalance(donor, 100n);105    const ethReceiver = await helper.eth.createAccountWithBalance(donor, 5n);106107    let susbtrateCollection: UniqueNFTCollection | null;108    const createCollectionSubstrateFee = convertToTokens(109      await helper.arrange.calculcateFee({Substrate: donor.address}, async () => {110        susbtrateCollection = await helper.nft.mintCollection(donor, {tokenPropertyPermissions: [111          {112            key: 'url',113            permission: {114              tokenOwner: true,115              collectionAdmin: true,116              mutable: true,117            },118          },119        ]});120      }),121      NOMINAL,122    );123124    const susbstrateMintFee = convertToTokens(125      await helper.arrange.calculcateFee(126        {Substrate: donor.address},127        () => susbtrateCollection!.mintToken(donor, {Substrate: substrateReceiver.address}, [{key: 'url', value: 'test'}]),128      ),129      NOMINAL,130    );131    const susbstrateTransferFee = convertToTokens(132      await helper.arrange.calculcateFee(133        {Substrate: substrateReceiver.address},134        () => susbtrateCollection!.transferToken(substrateReceiver, 1, {Substrate: donor.address}),135      ),136      NOMINAL,137    );138    const substrateFee: IBenchmarkCollection = {139      createFee: createCollectionSubstrateFee,140      mintFee: susbstrateMintFee,141      transferFee: susbstrateTransferFee,142    };143144    const helperContract = await helper.ethNativeContract.collectionHelpers(ethSigner);145146    let ethContract: Contract | null = null;147148    const createCollectionEthFee = convertToTokens(149      await helper.arrange.calculcateFee({Ethereum: ethSigner}, async () => {150        const result = await helperContract.methods.createNFTCollection('a', 'b', 'c').send({from: ethSigner, value: Number(2n * helper.balance.getOneTokenNominal())});151        ethContract = await helper.ethNativeContract.collection(helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId), 'nft', ethSigner);152      }),153      NOMINAL,154    );155156    await ethContract!.methods.setTokenPropertyPermissions([157      ['url', [158        [TokenPermissionField.Mutable, true],159        [TokenPermissionField.TokenOwner, true],160        [TokenPermissionField.CollectionAdmin, true]],161      ],162    ]).send({from: ethSigner});163164    const ethMintFee = convertToTokens(await helper.arrange.calculcateFee(165      {Ethereum: ethSigner},166      () => ethContract!.methods.mintCross(167        helper.ethCrossAccount.fromAddress(ethReceiver),168        [{key: 'url', value: Buffer.from('test')}],169      )170        .send({from: ethSigner}),171    ), NOMINAL);172173    const ethTransferFee = convertToTokens(await helper.arrange.calculcateFee(174      {Ethereum: ethReceiver},175      () => ethContract!.methods.transferFrom(ethReceiver, ethSigner, 1)176        .send({from: ethReceiver}),177    ), NOMINAL);178179    const ethFee: IBenchmarkCollection = {180      createFee: createCollectionEthFee,181      mintFee: ethMintFee,182      transferFee: ethTransferFee,183    };184185    let zeppelelinContract: Contract | null = null;186187    const zeppelinDeployFee = convertToTokens(188      await helper.arrange.calculcateFee({Ethereum: ethSigner}, async () => {189        zeppelelinContract = await helper.ethContract.deployByAbi(190          ethSigner,191          ZEPPELIN_ABI,192          ZEPPELIN_OBJECT,193        );194      }),195      NOMINAL,196    );197198    const zeppelinMintFee = convertToTokens(await helper.arrange.calculcateFee(199      {Ethereum: ethSigner},200      () => zeppelelinContract!.methods.safeMint(ethReceiver, 'test').send({from: ethSigner}),201    ), NOMINAL);202203204    const zeppelinTransferFee = convertToTokens(await helper.arrange.calculcateFee(205      {Ethereum: ethReceiver},206      () => zeppelelinContract!.methods.safeTransferFrom(ethReceiver, ethSigner, 0).send({from: ethReceiver}),207    ), NOMINAL);208209    const zeppelinFee: IBenchmarkCollection = {210      createFee: zeppelinDeployFee,211      mintFee: zeppelinMintFee,212      transferFee: zeppelinTransferFee,213    };214215    console.log('collection ops fees');216    const results = {substrate: substrateFee, eth: ethFee, zeppelin: zeppelinFee};217    console.table(results);218219    const contract = await helper.ethContract.deployByCode(220      ethSigner,221      'ProxyMint',222      CONTRACT_SOURCE,223      CONTRACT_IMPORT,224    );225226    const fees = await benchMintFee(helper, privateKey, contract);227    console.log('Minting without properties');228    console.table(fees);229230    const result: IBenchmarkResultForProp[] = [];231    const csvResult: IBenchmarkResultForProp[] = [];232233    for (let i = 1; i <= 20; i++) {234      const benchResult = await benchMintWithProperties(helper, privateKey, contract, {235        propertiesNumber: i,236      }) as any;237238      csvResult.push(benchResult);239240      const minFee = Math.min(...(benchmarks.map(x => benchResult[x])));241      for(const key of benchmarks) {242        const keyPercent = Math.round((benchResult[key] / minFee) * 100);243        benchResult[key] = `${benchResult[key]} (${keyPercent}%)`;244      }245246      result.push(benchResult);247    }248249    await csvWriter.writeRecords(csvResult);250251    console.log('Minting with properties');252    console.table(result, headers);253  });254};255256main()257  .then(() => process.exit(0))258  .catch((e) => {259    console.log(e);260    process.exit(1);261  });262263async function createCollectionForBenchmarks(264  helper: EthUniqueHelper,265  privateKey: (seed: string) => Promise<IKeyringPair>,266  ethSigner: string,267  proxyContract: string | null,268  permissions: ITokenPropertyPermission[],269) {270  const donor = await privateKey('//Alice');271272  const collection = await helper.nft.mintCollection(donor, {273    name: 'test mintToSubstrate',274    description: 'EVMHelpers',275    tokenPrefix: 'ap',276    tokenPropertyPermissions: [277      {278        key: 'url',279        permission: {280          tokenOwner: true,281          collectionAdmin: true,282          mutable: true,283        },284      },285      {286        key: 'URI',287        permission: {288          tokenOwner: true,289          collectionAdmin: true,290          mutable: true,291        },292      },293    ],294    limits: {sponsorTransferTimeout: 0, sponsorApproveTimeout: 0},295    permissions: {mintMode: true},296  });297298  await collection.addToAllowList(donor, {299    Ethereum: helper.address.substrateToEth(donor.address),300  });301  await collection.addToAllowList(donor, {Substrate: donor.address});302  await collection.addAdmin(donor, {Ethereum: ethSigner});303  await collection.addAdmin(donor, {304    Ethereum: helper.address.substrateToEth(donor.address),305  });306307  if (proxyContract) {308    await collection.addToAllowList(donor, {Ethereum: proxyContract});309    await collection.addAdmin(donor, {Ethereum: proxyContract});310  }311312  await collection.setTokenPropertyPermissions(donor, permissions);313314  return collection;315}316317async function benchMintFee(318  helper: EthUniqueHelper,319  privateKey: (seed: string) => Promise<IKeyringPair>,320  proxyContract: Contract,321): Promise<{322	substrateFee: number;323	ethFee: number;324	evmProxyContractFee: number;325}> {326  const donor = await privateKey('//Alice');327  const substrateReceiver = await privateKey('//Bob');328  const ethSigner = await helper.eth.createAccountWithBalance(donor, 100n);329330  const nominal = helper.balance.getOneTokenNominal();331332  await helper.eth.transferBalanceFromSubstrate(333    donor,334    proxyContract.options.address,335    100n,336  );337338  const collection = await createCollectionForBenchmarks(339    helper,340    privateKey,341    ethSigner,342    proxyContract.options.address,343    PERMISSIONS,344  );345346  const substrateFee = await helper.arrange.calculcateFee(347    {Substrate: donor.address},348    () => collection.mintToken(donor, {Substrate: substrateReceiver.address}),349  );350351  const collectionEthAddress = helper.ethAddress.fromCollectionId(collection.collectionId);352  const collectionContract = await helper.ethNativeContract.collection(353    collectionEthAddress,354    'nft',355  );356357  const receiverEthAddress = helper.address.substrateToEth(substrateReceiver.address);358359  const encodedCall = collectionContract.methods360    .mint(receiverEthAddress)361    .encodeABI();362363  const ethFee = await helper.arrange.calculcateFee(364    {Substrate: donor.address},365    async () => {366      await helper.eth.sendEVM(367        donor,368        collectionContract.options.address,369        encodedCall,370        '0',371      );372    },373  );374375  const evmProxyContractFee = await helper.arrange.calculcateFee(376    {Ethereum: ethSigner},377    async () => {378      await proxyContract.methods379        .mintToSubstrate(380          helper.ethAddress.fromCollectionId(collection.collectionId),381          substrateReceiver.addressRaw,382        )383        .send({from: ethSigner});384    },385  );386387  return {388    substrateFee: convertToTokens(substrateFee, nominal),389    ethFee: convertToTokens(ethFee, nominal),390    evmProxyContractFee: convertToTokens(evmProxyContractFee, nominal),391  };392}393394async function benchMintWithProperties(395  helper: EthUniqueHelper,396  privateKey: (seed: string) => Promise<IKeyringPair>,397  proxyContract: Contract,398  setup: { propertiesNumber: number },399): Promise<IBenchmarkResultForProp> {400  const donor = await privateKey('//Alice'); // Seed from account with balance on this network401  const ethSigner = await helper.eth.createAccountWithBalance(donor, 100n);402403  const susbstrateReceiver = await privateKey('//Bob');404  const receiverEthAddress = helper.address.substrateToEth(susbstrateReceiver.address);405406  const nominal = helper.balance.getOneTokenNominal();407408  const substrateFee = await calculateFeeNftMintWithProperties(409    helper,410    privateKey,411    {Substrate: donor.address},412    ethSigner,413    proxyContract.options.address,414    async (collection) => {415      await collection.mintToken(416        donor,417        {Substrate: susbstrateReceiver.address},418        PROPERTIES.slice(0, setup.propertiesNumber).map((p) => {419          return {key: p.key, value: Buffer.from(p.value).toString()};420        }),421      );422    },423  );424425  const ethFee = await calculateFeeNftMintWithProperties(426    helper,427    privateKey,428    {Substrate: donor.address},429    ethSigner,430    proxyContract.options.address,431    async (collection) => {432      const evmContract = await helper.ethNativeContract.collection(433        helper.ethAddress.fromCollectionId(collection.collectionId),434        'nft',435        undefined,436        true,437      );438439      const subTokenId = await evmContract.methods.nextTokenId().call();440441      let encodedCall = evmContract.methods442        .mint(receiverEthAddress)443        .encodeABI();444445      await helper.eth.sendEVM(446        donor,447        evmContract.options.address,448        encodedCall,449        '0',450      );451452      for (const val of PROPERTIES.slice(0, setup.propertiesNumber)) {453        encodedCall = await evmContract.methods454          .setProperty(subTokenId, val.key, Buffer.from(val.value))455          .encodeABI();456457        await helper.eth.sendEVM(458          donor,459          evmContract.options.address,460          encodedCall,461          '0',462        );463      }464    },465  );466467  const ethBulkFee = await calculateFeeNftMintWithProperties(468    helper,469    privateKey,470    {Substrate: donor.address},471    ethSigner,472    proxyContract.options.address,473    async (collection) => {474      const evmContract = await helper.ethNativeContract.collection(475        helper.ethAddress.fromCollectionId(collection.collectionId),476        'nft',477      );478479      const subTokenId = await evmContract.methods.nextTokenId().call();480481      let encodedCall = evmContract.methods482        .mint(receiverEthAddress)483        .encodeABI();484485      await helper.eth.sendEVM(486        donor,487        evmContract.options.address,488        encodedCall,489        '0',490      );491492      encodedCall = await evmContract.methods493        .setProperties(494          subTokenId,495          PROPERTIES.slice(0, setup.propertiesNumber),496        )497        .encodeABI();498499      await helper.eth.sendEVM(500        donor,501        evmContract.options.address,502        encodedCall,503        '0',504      );505    },506  );507508  const ethMintCrossFee = await calculateFeeNftMintWithProperties(509    helper,510    privateKey,511    {Ethereum: ethSigner},512    ethSigner,513    proxyContract.options.address,514    async (collection) => {515      const evmContract = await helper.ethNativeContract.collection(516        helper.ethAddress.fromCollectionId(collection.collectionId),517        'nft',518      );519520      await evmContract.methods.mintCross(521        helper.ethCrossAccount.fromAddress(receiverEthAddress),522        PROPERTIES.slice(0, setup.propertiesNumber),523      )524        .send({from: ethSigner});525    },526  );527528  const proxyContractFee = await calculateFeeNftMintWithProperties(529    helper,530    privateKey,531    {Ethereum: ethSigner},532    ethSigner,533    proxyContract.options.address,534    async (collection) => {535      await proxyContract.methods536        .mintToSubstrateWithProperty(537          helper.ethAddress.fromCollectionId(collection.collectionId),538          susbstrateReceiver.addressRaw,539          PROPERTIES.slice(0, setup.propertiesNumber),540        )541        .send({from: ethSigner});542    },543  );544545  const proxyContractBulkFee = await calculateFeeNftMintWithProperties(546    helper,547    privateKey,548    {Ethereum: ethSigner},549    ethSigner,550    proxyContract.options.address,551    async (collection) => {552      await proxyContract.methods553        .mintToSubstrateBulkProperty(554          helper.ethAddress.fromCollectionId(collection.collectionId),555          susbstrateReceiver.addressRaw,556          PROPERTIES.slice(0, setup.propertiesNumber),557        )558        .send({from: ethSigner, gas: 25_000_000});559    },560  );561562  return {563    propertiesNumber: setup.propertiesNumber,564    substrateFee: convertToTokens(substrateFee, nominal),565    ethFee: convertToTokens(ethFee, nominal),566    ethBulkFee: convertToTokens(ethBulkFee, nominal),567    ethMintCrossFee: convertToTokens(ethMintCrossFee, nominal),568    evmProxyContractFee: convertToTokens(proxyContractFee, nominal),569    evmProxyContractBulkFee: convertToTokens(proxyContractBulkFee, nominal),570  };571}572573async function calculateFeeNftMintWithProperties(574  helper: EthUniqueHelper,575  privateKey: (seed: string) => Promise<IKeyringPair>,576  payer: ICrossAccountId,577  ethSigner: string,578  proxyContractAddress: string,579  calculatedCall: (collection: UniqueNFTCollection) => Promise<any>,580): Promise<bigint> {581  const collection = await createCollectionForBenchmarks(582    helper,583    privateKey,584    ethSigner,585    proxyContractAddress,586    PERMISSIONS,587  );588  return helper.arrange.calculcateFee(payer, async () => {589    await calculatedCall(collection);590  });591}592function convertToTokens(value: bigint, nominal = 1000_000_000_000_000_000n): number {593  return Number((value * 1000n) / nominal) / 1000;594}595596interface IFeeGas {597  fee: number | bigint,598  gas: number | bigint,599  substrate?: number,600}601interface IFunctionFee {602  [name: string]: IFeeGas603}604605async function ERC721CalculateFeeGas(606  helper: EthUniqueHelper,607  privateKey: (seed: string) => Promise<IKeyringPair>,608609): Promise<IFunctionFee> {610  const res: IFunctionFee = {};611  const donor = await privateKey('//Alice');612  const ethSigner = await helper.eth.createAccountWithBalance(donor, 100n);613  const ethReceiver = await helper.eth.createAccountWithBalance(donor, 10n);614  const crossSigner = helper.ethCrossAccount.fromAddress(ethSigner);615  const crossReceiver = helper.ethCrossAccount.fromAddress(ethReceiver);616  const collection = await createCollectionForBenchmarks(617    helper,618    privateKey,619    ethSigner,620    null,621    PERMISSIONS,622  );623624  const evmContract = await helper.ethNativeContract.collection(625    helper.ethAddress.fromCollectionId(collection.collectionId),626    'nft',627    ethSigner,628    true,629  );630631  res['mint'] =632    await helper.arrange.calculcateFeeGas(633      {Ethereum: ethSigner},634      () => evmContract.methods.mint(ethSigner).send(),635    );636637  res['mint'].substrate = convertToTokens((await helper.arrange.calculcateFee(638    {Substrate: donor.address},639    () => collection.mintToken(640      donor,641      {Ethereum: ethSigner},642    ),643  )));644645  res['mintCross'] =646    await helper.arrange.calculcateFeeGas(647      {Ethereum: ethSigner},648      () => evmContract.methods.mintCross(crossSigner, []).send(),649    );650651  res['mintCross'].substrate = convertToTokens((await helper.arrange.calculcateFee(652    {Substrate: donor.address},653    () => collection.mintMultipleTokens(donor, [{654      owner: {Ethereum: ethSigner},655    }]),656  )));657658  res['mintWithTokenURI'] =659    await helper.arrange.calculcateFeeGas(660      {Ethereum: ethSigner},661      () => evmContract.methods.mintWithTokenURI(ethSigner, 'Test URI').send(),662    );663664  res['setProperties'] =665    await helper.arrange.calculcateFeeGas(666      {Ethereum: ethSigner},667      () => evmContract.methods.setProperties(1, PROPERTIES.slice(0,1)).send(),668    );669670  res['deleteProperties'] =671    await helper.arrange.calculcateFeeGas(672      {Ethereum: ethSigner},673      () => evmContract.methods.deleteProperties(1, [PROPERTIES[0].key]).send(),674    );675676  res['transfer'] =677    await helper.arrange.calculcateFeeGas(678      {Ethereum: ethSigner},679      () => evmContract.methods.transfer(ethReceiver, 1).send(),680    );681682  res['transferCross'] =683    await helper.arrange.calculcateFeeGas(684      {Ethereum: ethReceiver},685      () => evmContract.methods.transferCross(crossSigner, 1).send({from: ethReceiver}),686    );687688  res['transferFrom'] =689    await helper.arrange.calculcateFeeGas(690      {Ethereum: ethSigner},691      () => evmContract.methods.transferFrom(ethSigner, ethReceiver, 1).send(),692    );693694  res['transferFromCross'] =695    await helper.arrange.calculcateFeeGas(696      {Ethereum: ethReceiver},697      () => evmContract.methods.transferFromCross(crossReceiver, crossSigner, 1).send({from:ethReceiver}),698    );699700  res['burn'] =701    await helper.arrange.calculcateFeeGas(702      {Ethereum: ethSigner},703      () => evmContract.methods.burn(1).send(),704    );705706  res['approveCross'] =707    await helper.arrange.calculcateFeeGas(708      {Ethereum: ethSigner},709      () => evmContract.methods.approveCross(crossReceiver, 2).send(),710    );711712  res['burnFromCross'] =713    await helper.arrange.calculcateFeeGas(714      {Ethereum: ethReceiver},715      () => evmContract.methods.burnFromCross(crossSigner, 2).send({from:ethReceiver}),716    );717718  res['setTokenPropertyPermissions'] =719    await helper.arrange.calculcateFeeGas(720      {Ethereum: ethSigner},721      () =>  evmContract.methods.setTokenPropertyPermissions([722        ['url', [723          [TokenPermissionField.Mutable, true],724          [TokenPermissionField.TokenOwner, true],725          [TokenPermissionField.CollectionAdmin, true]],726        ],727      ]).send(),728    );729730  res['setCollectionSponsorCross'] =731    await helper.arrange.calculcateFeeGas(732      {Ethereum: ethSigner},733      () =>  evmContract.methods.setCollectionSponsorCross(crossReceiver).send(),734    );735736  res['confirmCollectionSponsorship'] =737    await helper.arrange.calculcateFeeGas(738      {Ethereum: ethReceiver},739      () =>  evmContract.methods.confirmCollectionSponsorship().send({from: ethReceiver}),740    );741742  res['removeCollectionSponsor'] =743    await helper.arrange.calculcateFeeGas(744      {Ethereum: ethSigner},745      () =>  evmContract.methods.removeCollectionSponsor().send(),746    );747748  res['setCollectionProperties'] =749    await helper.arrange.calculcateFeeGas(750      {Ethereum: ethSigner},751      () => evmContract.methods.setCollectionProperties(PROPERTIES.slice(0, 1)).send(),752    );753754  res['deleteCollectionProperties'] =755    await helper.arrange.calculcateFeeGas(756      {Ethereum: ethSigner},757      () =>  evmContract.methods.deleteCollectionProperties(PROPERTIES.slice(0,1).map(p => p.key)).send(),758    );759  res['setCollectionProperties'].substrate = convertToTokens((await helper.arrange.calculcateFee(760    {Substrate: donor.address},761    () => collection.setProperties(donor, PROPERTIES.slice(0, 1)762      .map(p => { return {key: p.key, value: p.value.toString()}; })),763  )));764765  res['deleteCollectionProperties'].substrate = convertToTokens((await helper.arrange.calculcateFee(766    {Substrate: donor.address},767    () => collection.deleteProperties(donor, PROPERTIES.slice(0, 1)768      .map(p => p.key)),769  )));770771  res['setCollectionLimit'] =772    await helper.arrange.calculcateFeeGas(773      {Ethereum: ethSigner},774      () =>  evmContract.methods.setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: 1000}}).send(),775    );776777  const {collectionAddress} = await helper.eth.createCollection('nft', ethSigner, 'A', 'B', 'C');778  const collectionWithEthOwner = await helper.ethNativeContract.collection(collectionAddress, 'nft', ethSigner, true);779780781  res['addCollectionAdminCross'] =782    await helper.arrange.calculcateFeeGas(783      {Ethereum: ethSigner},784      () =>  collectionWithEthOwner.methods.addCollectionAdminCross(crossReceiver).send(),785    );786787  res['removeCollectionAdminCross'] =788    await helper.arrange.calculcateFeeGas(789      {Ethereum: ethSigner},790      () =>  collectionWithEthOwner.methods.removeCollectionAdminCross(crossReceiver).send(),791    );792793  res['setCollectionNesting'] =794    await helper.arrange.calculcateFeeGas(795      {Ethereum: ethSigner},796      () =>  evmContract.methods.setCollectionNesting(true).send(),797    );798799  res['setCollectionNesting[]'] =800    await helper.arrange.calculcateFeeGas(801      {Ethereum: ethSigner},802      () =>  evmContract.methods.setCollectionNesting(true, [collectionAddress]).send(),803    );804805  res['setCollectionAcces'] =806    await helper.arrange.calculcateFeeGas(807      {Ethereum: ethSigner},808      () =>  evmContract.methods.setCollectionAccess(SponsoringMode.Allowlisted).send(),809    );810811  res['addToCollectionAllowListCross'] =812    await helper.arrange.calculcateFeeGas(813      {Ethereum: ethSigner},814      () =>  evmContract.methods.addToCollectionAllowListCross(crossReceiver).send(),815    );816817  res['removeFromCollectionAllowListCross'] =818    await helper.arrange.calculcateFeeGas(819      {Ethereum: ethSigner},820      () =>  evmContract.methods.removeFromCollectionAllowListCross(crossReceiver).send(),821    );822823  res['setCollectionMintMode'] =824    await helper.arrange.calculcateFeeGas(825      {Ethereum: ethSigner},826      () =>  evmContract.methods.setCollectionMintMode(true).send(),827    );828829  res['changeCollectionOwnerCross'] =830    await helper.arrange.calculcateFeeGas(831      {Ethereum: ethSigner},832      () =>  collectionWithEthOwner.methods.changeCollectionOwnerCross(crossReceiver).send(),833    );834835  return res;836}