git.delta.rocks / unique-network / refs/commits / 31fca6536571

difftreelog

Add no-floating-promises rule to eslint

Max Andreev2022-12-22parent: #72b9c7c.patch.diff
in: master

6 files changed

modifiedtests/.eslintrc.jsondiffbeforeafterboth
--- a/tests/.eslintrc.json
+++ b/tests/.eslintrc.json
@@ -18,6 +18,9 @@
         "mocha"
     ],
     "rules": {
+        "@typescript-eslint/no-floating-promises": [
+            "error"
+        ],
         "indent": [
             "error",
             2,
modifiedtests/package.jsondiffbeforeafterboth
--- a/tests/package.json
+++ b/tests/package.json
@@ -11,8 +11,8 @@
     "@types/chai-subset": "^1.3.3",
     "@types/mocha": "^10.0.0",
     "@types/node": "^18.11.2",
-    "@typescript-eslint/eslint-plugin": "^5.40.1",
-    "@typescript-eslint/parser": "^5.40.1",
+    "@typescript-eslint/eslint-plugin": "^5.47.0",
+    "@typescript-eslint/parser": "^5.47.0",
     "chai": "^4.3.6",
     "chai-subset": "^1.6.0",
     "eslint": "^8.25.0",
modifiedtests/src/calibrate.tsdiffbeforeafterboth
before · tests/src/calibrate.ts
1import {IKeyringPair} from '@polkadot/types/types';2import {usingEthPlaygrounds, EthUniqueHelper} from './eth/util';34class Fract {5  static ZERO = new Fract(0n);6  constructor(public readonly a: bigint, public readonly b: bigint = 1n) {7    if (b === 0n) throw new Error('division by zero');8    if (b < 0n) throw new Error('missing normalization');9  }1011  mul(other: Fract) {12    return new Fract(this.a * other.a, this.b * other.b).optimize();13  }1415  div(other: Fract) {16    return this.mul(other.inv());17  }1819  plus(other: Fract) {20    if (this.b === other.b) {21      return new Fract(this.a + other.a, this.b);22    }23    return new Fract(this.a * other.b + other.a * this.b, this.b * other.b).optimize();24  }2526  minus(other: Fract) {27    return this.plus(other.neg());28  }2930  neg() {31    return new Fract(-this.a, this.b);32  }33  inv() {34    if (this.a < 0) {35      return new Fract(-this.b, -this.a);36    } else {37      return new Fract(this.b, this.a);38    }39  }4041  optimize() {42    function gcd(x: bigint, y: bigint) {43      if (x < 0n)44        x = -x;45      if (y < 0n)46        y = -y;47      while(y) {48        const t = y;49        y = x % y;50        x = t;51      }52      return x;53    }54    const v = gcd(this.a, this.b);55    return new Fract(this.a / v, this.b / v);56  }5758  toBigInt() {59    return this.a / this.b;60  }61  toNumber() {62    const v = this.optimize();63    return Number(v.a) / Number(v.b);64  }65  toString() {66    const v = this.optimize();67    return `${v.a} / ${v.b}`;68  }6970  lt(other: Fract) {71    return this.a * other.b < other.a * this.b;72  }73  eq(other: Fract) {74    return this.a * other.b === other.a * this.b;75  }7677  sqrt() {78    if (this.a < 0n) {79      throw 'square root of negative numbers is not supported';80    }8182    if (this.lt(new Fract(2n))) {83      return this;84    }8586    function newtonIteration(n: Fract, x0: Fract): Fract {87      const x1 = rpn(n, x0, '/', x0, '+', new Fract(2n), '/');88      if (x0.eq(x1) || x0.eq(x1.minus(new Fract(1n)))) {89        return x0;90      }91      return newtonIteration(n, x1);92    }9394    return newtonIteration(this, new Fract(1n));95  }96}9798type Op = Fract | '+' | '-' | '*' | '/' | 'dup' | Op[];99function rpn(...ops: (Op)[]) {100  const stack: Fract[] = [];101  for (const op of ops) {102    if (op instanceof Fract) {103      stack.push(op);104    } else if (op === '+') {105      if (stack.length < 2)106        throw new Error('stack underflow');107      const b = stack.pop()!;108      const a = stack.pop()!;109      stack.push(a.plus(b));110    } else if (op === '*') {111      if (stack.length < 2)112        throw new Error('stack underflow');113      const b = stack.pop()!;114      const a = stack.pop()!;115      stack.push(a.mul(b));116    } else if (op === '-') {117      if (stack.length < 2)118        throw new Error('stack underflow');119      const b = stack.pop()!;120      const a = stack.pop()!;121      stack.push(a.minus(b));122    } else if (op === '/') {123      if (stack.length < 2)124        throw new Error('stack underflow');125      const b = stack.pop()!;126      const a = stack.pop()!;127      stack.push(a.div(b));128    } else if (op === 'dup') {129      if (stack.length < 1)130        throw new Error('stack underflow');131      const a = stack.pop()!;132      stack.push(a);133      stack.push(a);134    } else if (Array.isArray(op)) {135      stack.push(rpn(...op));136    } else {137      throw new Error(`unknown operand: ${op}`);138    }139  }140  if (stack.length != 1)141    throw new Error('one element should be left on stack');142  return stack[0]!;143}144145function linearRegression(points: { x: Fract, y: Fract }[]) {146  let sumxy = Fract.ZERO;147  let sumx = Fract.ZERO;148  let sumy = Fract.ZERO;149  let sumx2 = Fract.ZERO;150  const n = points.length;151  for (let i = 0; i < n; i++) {152    const p = points[i];153    sumxy = rpn(p.x, p.y, '*', sumxy, '+');154    sumx = sumx.plus(p.x);155    sumy = sumy.plus(p.y);156    sumx2 = rpn(p.x, p.x, '*', sumx2, '+');157  }158159  const nb = new Fract(BigInt(n));160161  const a = rpn(162    [nb, sumxy, '*', sumx, sumy, '*', '-'],163    [nb, sumx2, '*', sumx, sumx, '*', '-'],164    '/',165  );166  const b = rpn(167    [sumy, a, sumx, '*', '-'],168    nb,169    '/',170  );171172  return {a, b};173}174175const hypothesisLinear = (a: Fract, b: Fract) => (x: Fract) => rpn(x, a, '*', b, '+');176177function _error(points: { x: Fract, y: Fract }[], hypothesis: (a: Fract) => Fract) {178  return points.map(p => {179    const v = hypothesis(p.x);180    const vv = p.y;181182    return rpn(v, vv, '-', 'dup', '*');183  }).reduce((a, b) => a.plus(b), Fract.ZERO).sqrt().div(new Fract(BigInt(points.length)));184}185186async function calibrateWeightToFee(helper: EthUniqueHelper, privateKey: (account: string) => Promise<IKeyringPair>) {187  const alice = await privateKey('//Alice');188  const bob = await privateKey('//Bob');189  const dataPoints = [];190191  {192    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});193    const token = await collection.mintToken(alice, {Substrate: alice.address});194    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);195    await token.transfer(alice, {Substrate: bob.address});196    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);197198    console.log(`\t[NFT transfer] Original price: ${Number(aliceBalanceBefore - aliceBalanceAfter) / Number(helper.balance.getOneTokenNominal())} UNQ`);199  }200201  const api = helper.getApi();202  const base = (await api.query.configuration.weightToFeeCoefficientOverride() as any).toBigInt();203  for (let i = -5; i < 5; i++) {204    await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setWeightToFeeCoefficientOverride(base + base / 1000n * BigInt(i))));205206    const coefficient = new Fract((await api.query.configuration.weightToFeeCoefficientOverride() as any).toBigInt());207    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});208    const token = await collection.mintToken(alice, {Substrate: alice.address});209210    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);211    await token.transfer(alice, {Substrate: bob.address});212    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);213214    const transferPrice = new Fract(aliceBalanceBefore - aliceBalanceAfter);215216    dataPoints.push({x: transferPrice, y: coefficient});217  }218  const {a, b} = linearRegression(dataPoints);219220  const hyp = hypothesisLinear(a, b);221  // console.log(`\t[NFT transfer] Error: ${_error(dataPoints, hyp).toNumber()}`);222223  // 0.1 UNQ224  const perfectValue = hyp(rpn(new Fract(helper.balance.getOneTokenNominal()), new Fract(1n, 10n), '*'));225  await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setWeightToFeeCoefficientOverride(perfectValue.toBigInt())));226227  {228    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});229    const token = await collection.mintToken(alice, {Substrate: alice.address});230    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);231    await token.transfer(alice, {Substrate: bob.address});232    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);233234    console.log(`\t[NFT transfer] Calibrated price: ${Number(aliceBalanceBefore - aliceBalanceAfter) / Number(helper.balance.getOneTokenNominal())} UNQ`);235  }236}237238async function calibrateMinGasPrice(helper: EthUniqueHelper, privateKey: (account: string) => Promise<IKeyringPair>) {239  const alice = await privateKey('//Alice');240  const caller = await helper.eth.createAccountWithBalance(alice);241  const receiver = helper.eth.createAccount();242  const dataPoints = [];243244  {245    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});246    const token = await collection.mintToken(alice, {Ethereum: caller});247248    const address = helper.ethAddress.fromCollectionId(collection.collectionId);249    const contract = await helper.ethNativeContract.collection(address, 'nft', caller);250251    const cost = await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gas: helper.eth.DEFAULT_GAS}));252253    console.log(`\t[ETH NFT transfer] Original price: ${Number(cost) / Number(helper.balance.getOneTokenNominal())} UNQ`);254  }255256  const api = helper.getApi();257  // const defaultCoeff = (api.consts.configuration.defaultMinGasPrice as any).toBigInt();258  const base = (await api.query.configuration.minGasPriceOverride() as any).toBigInt();259  for (let i = -8; i < 8; i++) {260    const gasPrice = base + base / 100000n * BigInt(i);261    const gasPriceStr = '0x' + gasPrice.toString(16);262    await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setMinGasPriceOverride(gasPrice)));263264    const coefficient = new Fract((await api.query.configuration.minGasPriceOverride() as any).toBigInt());265    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});266    const token = await collection.mintToken(alice, {Ethereum: caller});267268    const address = helper.ethAddress.fromCollectionId(collection.collectionId);269    const contract = await helper.ethNativeContract.collection(address, 'nft', caller);270271    const transferPrice = new Fract(await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gasPrice: gasPriceStr, gas: helper.eth.DEFAULT_GAS})));272273    dataPoints.push({x: transferPrice, y: coefficient});274  }275276  const {a, b} = linearRegression(dataPoints);277278  const hyp = hypothesisLinear(a, b);279  // console.log(`\t[ETH NFT transfer] Error: ${_error(dataPoints, hyp).toNumber()}`);280281  // 0.15 UNQ282  const perfectValue = hyp(rpn(new Fract(helper.balance.getOneTokenNominal()), new Fract(15n, 100n), '*'));283  await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setMinGasPriceOverride(perfectValue.toBigInt())));284285  {286    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});287    const token = await collection.mintToken(alice, {Ethereum: caller});288289    const address = helper.ethAddress.fromCollectionId(collection.collectionId);290    const contract = await helper.ethNativeContract.collection(address, 'nft', caller);291292    const cost = await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gas: helper.eth.DEFAULT_GAS}));293294    console.log(`\t[ETH NFT transfer] Calibrated price: ${Number(cost) / Number(helper.balance.getOneTokenNominal())} UNQ`);295  }296}297298(async () => {299  await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {300    // Subsequent runs reduce error, as price line is not actually straight, this is a curve301302    const iterations = 3;303304    console.log('[Calibrate WeightToFee]');305    for (let i = 0; i < iterations; i++) {306      await calibrateWeightToFee(helper, privateKey);307    }308309    console.log();310311    console.log('[Calibrate MinGasPrice]');312    for (let i = 0; i < iterations; i++) {313      await calibrateMinGasPrice(helper, privateKey);314    }315  });316})();
after · tests/src/calibrate.ts
1import {IKeyringPair} from '@polkadot/types/types';2import {usingEthPlaygrounds, EthUniqueHelper} from './eth/util';34class Fract {5  static ZERO = new Fract(0n);6  constructor(public readonly a: bigint, public readonly b: bigint = 1n) {7    if (b === 0n) throw new Error('division by zero');8    if (b < 0n) throw new Error('missing normalization');9  }1011  mul(other: Fract) {12    return new Fract(this.a * other.a, this.b * other.b).optimize();13  }1415  div(other: Fract) {16    return this.mul(other.inv());17  }1819  plus(other: Fract) {20    if (this.b === other.b) {21      return new Fract(this.a + other.a, this.b);22    }23    return new Fract(this.a * other.b + other.a * this.b, this.b * other.b).optimize();24  }2526  minus(other: Fract) {27    return this.plus(other.neg());28  }2930  neg() {31    return new Fract(-this.a, this.b);32  }33  inv() {34    if (this.a < 0) {35      return new Fract(-this.b, -this.a);36    } else {37      return new Fract(this.b, this.a);38    }39  }4041  optimize() {42    function gcd(x: bigint, y: bigint) {43      if (x < 0n)44        x = -x;45      if (y < 0n)46        y = -y;47      while(y) {48        const t = y;49        y = x % y;50        x = t;51      }52      return x;53    }54    const v = gcd(this.a, this.b);55    return new Fract(this.a / v, this.b / v);56  }5758  toBigInt() {59    return this.a / this.b;60  }61  toNumber() {62    const v = this.optimize();63    return Number(v.a) / Number(v.b);64  }65  toString() {66    const v = this.optimize();67    return `${v.a} / ${v.b}`;68  }6970  lt(other: Fract) {71    return this.a * other.b < other.a * this.b;72  }73  eq(other: Fract) {74    return this.a * other.b === other.a * this.b;75  }7677  sqrt() {78    if (this.a < 0n) {79      throw 'square root of negative numbers is not supported';80    }8182    if (this.lt(new Fract(2n))) {83      return this;84    }8586    function newtonIteration(n: Fract, x0: Fract): Fract {87      const x1 = rpn(n, x0, '/', x0, '+', new Fract(2n), '/');88      if (x0.eq(x1) || x0.eq(x1.minus(new Fract(1n)))) {89        return x0;90      }91      return newtonIteration(n, x1);92    }9394    return newtonIteration(this, new Fract(1n));95  }96}9798type Op = Fract | '+' | '-' | '*' | '/' | 'dup' | Op[];99function rpn(...ops: (Op)[]) {100  const stack: Fract[] = [];101  for (const op of ops) {102    if (op instanceof Fract) {103      stack.push(op);104    } else if (op === '+') {105      if (stack.length < 2)106        throw new Error('stack underflow');107      const b = stack.pop()!;108      const a = stack.pop()!;109      stack.push(a.plus(b));110    } else if (op === '*') {111      if (stack.length < 2)112        throw new Error('stack underflow');113      const b = stack.pop()!;114      const a = stack.pop()!;115      stack.push(a.mul(b));116    } else if (op === '-') {117      if (stack.length < 2)118        throw new Error('stack underflow');119      const b = stack.pop()!;120      const a = stack.pop()!;121      stack.push(a.minus(b));122    } else if (op === '/') {123      if (stack.length < 2)124        throw new Error('stack underflow');125      const b = stack.pop()!;126      const a = stack.pop()!;127      stack.push(a.div(b));128    } else if (op === 'dup') {129      if (stack.length < 1)130        throw new Error('stack underflow');131      const a = stack.pop()!;132      stack.push(a);133      stack.push(a);134    } else if (Array.isArray(op)) {135      stack.push(rpn(...op));136    } else {137      throw new Error(`unknown operand: ${op}`);138    }139  }140  if (stack.length != 1)141    throw new Error('one element should be left on stack');142  return stack[0]!;143}144145function linearRegression(points: { x: Fract, y: Fract }[]) {146  let sumxy = Fract.ZERO;147  let sumx = Fract.ZERO;148  let sumy = Fract.ZERO;149  let sumx2 = Fract.ZERO;150  const n = points.length;151  for (let i = 0; i < n; i++) {152    const p = points[i];153    sumxy = rpn(p.x, p.y, '*', sumxy, '+');154    sumx = sumx.plus(p.x);155    sumy = sumy.plus(p.y);156    sumx2 = rpn(p.x, p.x, '*', sumx2, '+');157  }158159  const nb = new Fract(BigInt(n));160161  const a = rpn(162    [nb, sumxy, '*', sumx, sumy, '*', '-'],163    [nb, sumx2, '*', sumx, sumx, '*', '-'],164    '/',165  );166  const b = rpn(167    [sumy, a, sumx, '*', '-'],168    nb,169    '/',170  );171172  return {a, b};173}174175const hypothesisLinear = (a: Fract, b: Fract) => (x: Fract) => rpn(x, a, '*', b, '+');176177function _error(points: { x: Fract, y: Fract }[], hypothesis: (a: Fract) => Fract) {178  return points.map(p => {179    const v = hypothesis(p.x);180    const vv = p.y;181182    return rpn(v, vv, '-', 'dup', '*');183  }).reduce((a, b) => a.plus(b), Fract.ZERO).sqrt().div(new Fract(BigInt(points.length)));184}185186async function calibrateWeightToFee(helper: EthUniqueHelper, privateKey: (account: string) => Promise<IKeyringPair>) {187  const alice = await privateKey('//Alice');188  const bob = await privateKey('//Bob');189  const dataPoints = [];190191  {192    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});193    const token = await collection.mintToken(alice, {Substrate: alice.address});194    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);195    await token.transfer(alice, {Substrate: bob.address});196    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);197198    console.log(`\t[NFT transfer] Original price: ${Number(aliceBalanceBefore - aliceBalanceAfter) / Number(helper.balance.getOneTokenNominal())} UNQ`);199  }200201  const api = helper.getApi();202  const base = (await api.query.configuration.weightToFeeCoefficientOverride() as any).toBigInt();203  for (let i = -5; i < 5; i++) {204    await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setWeightToFeeCoefficientOverride(base + base / 1000n * BigInt(i))));205206    const coefficient = new Fract((await api.query.configuration.weightToFeeCoefficientOverride() as any).toBigInt());207    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});208    const token = await collection.mintToken(alice, {Substrate: alice.address});209210    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);211    await token.transfer(alice, {Substrate: bob.address});212    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);213214    const transferPrice = new Fract(aliceBalanceBefore - aliceBalanceAfter);215216    dataPoints.push({x: transferPrice, y: coefficient});217  }218  const {a, b} = linearRegression(dataPoints);219220  const hyp = hypothesisLinear(a, b);221  // console.log(`\t[NFT transfer] Error: ${_error(dataPoints, hyp).toNumber()}`);222223  // 0.1 UNQ224  const perfectValue = hyp(rpn(new Fract(helper.balance.getOneTokenNominal()), new Fract(1n, 10n), '*'));225  await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setWeightToFeeCoefficientOverride(perfectValue.toBigInt())));226227  {228    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});229    const token = await collection.mintToken(alice, {Substrate: alice.address});230    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);231    await token.transfer(alice, {Substrate: bob.address});232    const aliceBalanceAfter = await helper.balance.getSubstrate(alice.address);233234    console.log(`\t[NFT transfer] Calibrated price: ${Number(aliceBalanceBefore - aliceBalanceAfter) / Number(helper.balance.getOneTokenNominal())} UNQ`);235  }236}237238async function calibrateMinGasPrice(helper: EthUniqueHelper, privateKey: (account: string) => Promise<IKeyringPair>) {239  const alice = await privateKey('//Alice');240  const caller = await helper.eth.createAccountWithBalance(alice);241  const receiver = helper.eth.createAccount();242  const dataPoints = [];243244  {245    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});246    const token = await collection.mintToken(alice, {Ethereum: caller});247248    const address = helper.ethAddress.fromCollectionId(collection.collectionId);249    const contract = await helper.ethNativeContract.collection(address, 'nft', caller);250251    const cost = await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gas: helper.eth.DEFAULT_GAS}));252253    console.log(`\t[ETH NFT transfer] Original price: ${Number(cost) / Number(helper.balance.getOneTokenNominal())} UNQ`);254  }255256  const api = helper.getApi();257  // const defaultCoeff = (api.consts.configuration.defaultMinGasPrice as any).toBigInt();258  const base = (await api.query.configuration.minGasPriceOverride() as any).toBigInt();259  for (let i = -8; i < 8; i++) {260    const gasPrice = base + base / 100000n * BigInt(i);261    const gasPriceStr = '0x' + gasPrice.toString(16);262    await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setMinGasPriceOverride(gasPrice)));263264    const coefficient = new Fract((await api.query.configuration.minGasPriceOverride() as any).toBigInt());265    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});266    const token = await collection.mintToken(alice, {Ethereum: caller});267268    const address = helper.ethAddress.fromCollectionId(collection.collectionId);269    const contract = await helper.ethNativeContract.collection(address, 'nft', caller);270271    const transferPrice = new Fract(await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gasPrice: gasPriceStr, gas: helper.eth.DEFAULT_GAS})));272273    dataPoints.push({x: transferPrice, y: coefficient});274  }275276  const {a, b} = linearRegression(dataPoints);277278  const hyp = hypothesisLinear(a, b);279  // console.log(`\t[ETH NFT transfer] Error: ${_error(dataPoints, hyp).toNumber()}`);280281  // 0.15 UNQ282  const perfectValue = hyp(rpn(new Fract(helper.balance.getOneTokenNominal()), new Fract(15n, 100n), '*'));283  await helper.signTransaction(alice, api.tx.sudo.sudo(api.tx.configuration.setMinGasPriceOverride(perfectValue.toBigInt())));284285  {286    const collection = await helper.nft.mintCollection(alice, {name: 'New', description: 'New collection', tokenPrefix: 'NEW'});287    const token = await collection.mintToken(alice, {Ethereum: caller});288289    const address = helper.ethAddress.fromCollectionId(collection.collectionId);290    const contract = await helper.ethNativeContract.collection(address, 'nft', caller);291292    const cost = await helper.eth.calculateFee({Ethereum: caller}, () => contract.methods.transfer(receiver, token.tokenId).send({from: caller, gas: helper.eth.DEFAULT_GAS}));293294    console.log(`\t[ETH NFT transfer] Calibrated price: ${Number(cost) / Number(helper.balance.getOneTokenNominal())} UNQ`);295  }296}297298// eslint-disable-next-line @typescript-eslint/no-floating-promises299(async () => {300  await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {301    // Subsequent runs reduce error, as price line is not actually straight, this is a curve302303    const iterations = 3;304305    console.log('[Calibrate WeightToFee]');306    for (let i = 0; i < iterations; i++) {307      await calibrateWeightToFee(helper, privateKey);308    }309310    console.log();311312    console.log('[Calibrate MinGasPrice]');313    for (let i = 0; i < iterations; i++) {314      await calibrateMinGasPrice(helper, privateKey);315    }316  });317})();
modifiedtests/src/transfer.nload.tsdiffbeforeafterboth
--- a/tests/src/transfer.nload.ts
+++ b/tests/src/transfer.nload.ts
@@ -14,6 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
+/* eslint-disable @typescript-eslint/no-floating-promises */
 import os from 'os';
 import {IKeyringPair} from '@polkadot/types/types';
 import {usingPlaygrounds} from './util';
modifiedtests/src/util/globalSetup.tsdiffbeforeafterboth
--- a/tests/src/util/globalSetup.ts
+++ b/tests/src/util/globalSetup.ts
@@ -17,7 +17,7 @@
       // 2. Create donors for test files
       await fundFilenamesWithRetries(3)
         .then((result) => {
-          if (!result) Promise.reject();
+          if (!result) throw Error('Some problems with fundFilenamesWithRetries');
         });
 
       // 3. Configure App Promotion
@@ -38,7 +38,7 @@
       }
     } catch (error) {
       console.error(error);
-      Promise.reject();
+      throw Error('Error during globalSetup');
     }
   });
 };
modifiedtests/yarn.lockdiffbeforeafterboth
--- a/tests/yarn.lock
+++ b/tests/yarn.lock
@@ -1064,14 +1064,14 @@
   dependencies:
     "@types/node" "*"
 
-"@typescript-eslint/eslint-plugin@^5.40.1":
-  version "5.46.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.46.1.tgz#098abb4c9354e19f460d57ab18bff1f676a6cff0"
-  integrity sha512-YpzNv3aayRBwjs4J3oz65eVLXc9xx0PDbIRisHj+dYhvBn02MjYOD96P8YGiWEIFBrojaUjxvkaUpakD82phsA==
+"@typescript-eslint/eslint-plugin@^5.47.0":
+  version "5.47.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz#dadb79df3b0499699b155839fd6792f16897d910"
+  integrity sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.46.1"
-    "@typescript-eslint/type-utils" "5.46.1"
-    "@typescript-eslint/utils" "5.46.1"
+    "@typescript-eslint/scope-manager" "5.47.0"
+    "@typescript-eslint/type-utils" "5.47.0"
+    "@typescript-eslint/utils" "5.47.0"
     debug "^4.3.4"
     ignore "^5.2.0"
     natural-compare-lite "^1.4.0"
@@ -1079,72 +1079,72 @@
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/parser@^5.40.1":
-  version "5.46.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.46.1.tgz#1fc8e7102c1141eb64276c3b89d70da8c0ba5699"
-  integrity sha512-RelQ5cGypPh4ySAtfIMBzBGyrNerQcmfA1oJvPj5f+H4jI59rl9xxpn4bonC0tQvUKOEN7eGBFWxFLK3Xepneg==
+"@typescript-eslint/parser@^5.47.0":
+  version "5.47.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.47.0.tgz#62e83de93499bf4b500528f74bf2e0554e3a6c8d"
+  integrity sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.46.1"
-    "@typescript-eslint/types" "5.46.1"
-    "@typescript-eslint/typescript-estree" "5.46.1"
+    "@typescript-eslint/scope-manager" "5.47.0"
+    "@typescript-eslint/types" "5.47.0"
+    "@typescript-eslint/typescript-estree" "5.47.0"
     debug "^4.3.4"
 
-"@typescript-eslint/scope-manager@5.46.1":
-  version "5.46.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.46.1.tgz#70af8425c79bbc1178b5a63fb51102ddf48e104a"
-  integrity sha512-iOChVivo4jpwUdrJZyXSMrEIM/PvsbbDOX1y3UCKjSgWn+W89skxWaYXACQfxmIGhPVpRWK/VWPYc+bad6smIA==
+"@typescript-eslint/scope-manager@5.47.0":
+  version "5.47.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz#f58144a6b0ff58b996f92172c488813aee9b09df"
+  integrity sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==
   dependencies:
-    "@typescript-eslint/types" "5.46.1"
-    "@typescript-eslint/visitor-keys" "5.46.1"
+    "@typescript-eslint/types" "5.47.0"
+    "@typescript-eslint/visitor-keys" "5.47.0"
 
-"@typescript-eslint/type-utils@5.46.1":
-  version "5.46.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.46.1.tgz#195033e4b30b51b870dfcf2828e88d57b04a11cc"
-  integrity sha512-V/zMyfI+jDmL1ADxfDxjZ0EMbtiVqj8LUGPAGyBkXXStWmCUErMpW873zEHsyguWCuq2iN4BrlWUkmuVj84yng==
+"@typescript-eslint/type-utils@5.47.0":
+  version "5.47.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.47.0.tgz#2b440979c574e317d3473225ae781f292c99e55d"
+  integrity sha512-1J+DFFrYoDUXQE1b7QjrNGARZE6uVhBqIvdaXTe5IN+NmEyD68qXR1qX1g2u4voA+nCaelQyG8w30SAOihhEYg==
   dependencies:
-    "@typescript-eslint/typescript-estree" "5.46.1"
-    "@typescript-eslint/utils" "5.46.1"
+    "@typescript-eslint/typescript-estree" "5.47.0"
+    "@typescript-eslint/utils" "5.47.0"
     debug "^4.3.4"
     tsutils "^3.21.0"
 
-"@typescript-eslint/types@5.46.1":
-  version "5.46.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.46.1.tgz#4e9db2107b9a88441c4d5ecacde3bb7a5ebbd47e"
-  integrity sha512-Z5pvlCaZgU+93ryiYUwGwLl9AQVB/PQ1TsJ9NZ/gHzZjN7g9IAn6RSDkpCV8hqTwAiaj6fmCcKSQeBPlIpW28w==
+"@typescript-eslint/types@5.47.0":
+  version "5.47.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.47.0.tgz#67490def406eaa023dbbd8da42ee0d0c9b5229d3"
+  integrity sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==
 
-"@typescript-eslint/typescript-estree@5.46.1":
-  version "5.46.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.1.tgz#5358088f98a8f9939355e0996f9c8f41c25eced2"
-  integrity sha512-j9W4t67QiNp90kh5Nbr1w92wzt+toiIsaVPnEblB2Ih2U9fqBTyqV9T3pYWZBRt6QoMh/zVWP59EpuCjc4VRBg==
+"@typescript-eslint/typescript-estree@5.47.0":
+  version "5.47.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz#ed971a11c5c928646d6ba7fc9dfdd6e997649aca"
+  integrity sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==
   dependencies:
-    "@typescript-eslint/types" "5.46.1"
-    "@typescript-eslint/visitor-keys" "5.46.1"
+    "@typescript-eslint/types" "5.47.0"
+    "@typescript-eslint/visitor-keys" "5.47.0"
     debug "^4.3.4"
     globby "^11.1.0"
     is-glob "^4.0.3"
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/utils@5.46.1":
-  version "5.46.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.46.1.tgz#7da3c934d9fd0eb4002a6bb3429f33298b469b4a"
-  integrity sha512-RBdBAGv3oEpFojaCYT4Ghn4775pdjvwfDOfQ2P6qzNVgQOVrnSPe5/Pb88kv7xzYQjoio0eKHKB9GJ16ieSxvA==
+"@typescript-eslint/utils@5.47.0":
+  version "5.47.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.47.0.tgz#b5005f7d2696769a1fdc1e00897005a25b3a0ec7"
+  integrity sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw==
   dependencies:
     "@types/json-schema" "^7.0.9"
     "@types/semver" "^7.3.12"
-    "@typescript-eslint/scope-manager" "5.46.1"
-    "@typescript-eslint/types" "5.46.1"
-    "@typescript-eslint/typescript-estree" "5.46.1"
+    "@typescript-eslint/scope-manager" "5.47.0"
+    "@typescript-eslint/types" "5.47.0"
+    "@typescript-eslint/typescript-estree" "5.47.0"
     eslint-scope "^5.1.1"
     eslint-utils "^3.0.0"
     semver "^7.3.7"
 
-"@typescript-eslint/visitor-keys@5.46.1":
-  version "5.46.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.1.tgz#126cc6fe3c0f83608b2b125c5d9daced61394242"
-  integrity sha512-jczZ9noovXwy59KjRTk1OftT78pwygdcmCuBf8yMoWt/8O8l+6x2LSEze0E4TeepXK4MezW3zGSyoDRZK7Y9cg==
+"@typescript-eslint/visitor-keys@5.47.0":
+  version "5.47.0"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz#4aca4efbdf6209c154df1f7599852d571b80bb45"
+  integrity sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==
   dependencies:
-    "@typescript-eslint/types" "5.46.1"
+    "@typescript-eslint/types" "5.47.0"
     eslint-visitor-keys "^3.3.0"
 
 abortcontroller-polyfill@^1.7.3: